grill-me
Interview the user relentlessly about a plan or design until reaching shared understanding,…
Adding custom GraphQL queries and mutations using GraphQLSchemaFactory. Use this skill when the developer wants to add custom GraphQL endpoints, create custom queries or mutations, add business logic to the API layer, build custom resolvers, inject backend services (identity,
$ npx -y skills add webiny/webiny-js --skill graphql-api --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/graphql-apiContext preview
The summary Claude sees to decide when to auto-load this skill.
Adding custom GraphQL queries and mutations using GraphQLSchemaFactory. Use this skill when the developer wants to add custom GraphQL endpoints, create custom queries or mutations, add business logic to the API layer, build custom resolvers, inject backend services (identity,
name: webiny-custom-graphql-api context: webiny-extensions description: > Adding custom GraphQL queries and mutations using GraphQLSchemaFactory. Use this skill when the developer wants to add custom GraphQL endpoints, create custom queries or mutations, add business logic to the API layer, build custom resolvers, inject backend services (identity, tenancy, CMS use-cases) into their GraphQL schema, or build dynamic GraphQL inputs from CMS models. Covers the full pattern from simple queries to complex resolvers with dependency injection and permission transformers.
Add custom GraphQL queries and mutations using `GraphQLSchemaFactory`. Implement `GraphQLSchemaFactory.Interface`, use the schema builder to add type definitions and resolvers (with per-resolver DI), and export with `GraphQLSchemaFactory.createImplementation()`. Register as `<Api.Extension>`.
**YOU MUST include the full file path with the `.ts` extension in every `src` prop.** For example, use `src={"/extensions/MySchema.ts"}`, NOT `src={"/extensions/MySchema"}`. Omitting the file extension will cause a build failure.
**YOU MUST use `export default` for the `createImplementation()` call** when the file is targeted directly by an Extension `src` prop. Using a named export (`export const Foo = SomeFactory.createImplementation(...)`) will cause a build failure. Named exports are only valid inside files registered via `createFeature`.
The `execute` method receives a schema builder and returns it after adding type defs and resolvers.
// extensions/mySchema/MyGraphQLSchema.ts
import { GraphQLSchemaFactory } from "webiny/api/graphql";
class MySchema implements GraphQLSchemaFactory.Interface {
async execute(
builder: GraphQLSchemaFactory.SchemaBuilder
): Promise<GraphQLSchemaFactory.SchemaBuilder> {
builder.addTypeDefs(/* GraphQL */ `
extend type Query {
hello: String!
}
`);
builder.addResolver({
path: "Query.hello",
resolver: () => {
return () => "Hello, World!";
}
});
return builder;
}
}
export default GraphQLSchemaFactory.createImplementation({
implementation: MySchema,
dependencies: []
});Register as an extension:
// extensions/mySchema/Extension.tsx
import React from "react";
import { Api } from "webiny/extensions";
export const MySchema = () => {
return <Api.Extension src={"@/extensions/mySchema/MyGraphQLSchema.ts"} />;
};| Method | Description | | --------------------------------------- | --------------------------------------------------------------------------------------------- | | `builder.addTypeDefs(typeDefs: string)` | Add GraphQL type definitions (use `extend type Query/Mutation` to add to existing root types) | | `builder.addResolver<TArgs>(config)` | Add a resolver with optional per-resolver DI dependencies |
builder.addResolver<TArgs>({
path: "TypeName.fieldName", // dot-separated path
dependencies: [SomeAbstraction], // optional: DI tokens resolved at request time
resolver: (dep1, dep2, ...) => { // factory: receives resolved deps
return ({ parent, args, context, info }) => {
// actual resolver logic
return result;
};
}
});Key points:
Dependencies in `addResolver` are resolved at request time from the request-scoped container. This is different from class-level constructor DI — it gives each resolver access to request-scoped services like identity and tenant context.
import { GraphQLSchemaFactory } from "webiny/api/graphql";
import { IdentityContext } from "webiny/api/security";
class WhoAmISchema implements GraphQLSchemaFactory.Interface {
async execute(
builder: GraphQLSchemaFactory.SchemaBuilder
): Promise<GraphQLSchemaFactory.SchemaBuilder> {
builder.addTypeDefs(/* GraphQL */ `
extend type Query {
whoAmI: String
}
`);
builder.addResolver({
path: "Query.whoAmI",
dependencies: [IdentityContext],
resolver: (identityContext: IdentityContext.Interface) => {
return () => {
const identity = identityContext.getIdentity();
return `Hello, ${identity.displayName}!`;
};
}
});
return builder;
}
}
export default GraphQLSchemaFactory.createImplementation({
implementation: WhoAmISchema,
dependencies: []
});Note: `GraphQLSchemaFactory` implementations typically have `dependencies: []` because DI happens at the resolver level via `addResolver({ dependencies })`, not at the class constructor level.
---
Full pattern using `Response` / `ErrorResponse` wrappers and UseCase injection:
import { Response } from "@webiny/api-graphql";
import { ErrorResponse } from "@webiny/api-graphql";
import { GraphQLSchemaFactory } from "@webiny/api-graphql/graphql/abstractions.js";
import { GetCurrentEntityUseCase } from "../features/getCurrentEntity/abstractions.js";
class GetCurrentEntitySchema implements GraphQLSchemaFactory.Interface {
async execute(
builder: GraphQLSchemaFactory.SchemaBuilder
): Promise<GraphQLSchemaFactory.SchemaBuiOpen-source content platform. Self-hosted on AWS serverless. Built as a TypeScript framework you extend with code, not a closed product you configure through a UI. Runs on Lambda, DynamoDB, S3, and CloudFront inside your own AWS account. Scales automatically.
Repo: webiny/webiny-js
Interview the user relentlessly about a plan or design until reaching shared understanding,…
Turn a PRD into a multi-phase implementation plan using tracer-bullet vertical slices, saved…
Webiny-only. Run all checks required before packages are ready for publish: deps, build,…
Use when running tests. Shows how to run tests for a single package, including OpenSearch…
Generate, refresh, and maintain Webiny MCP server skills from source documentation and…
Create a PRD through user interview, codebase exploration, and module design, then submit as…