Skip to content

Commit 1e32112

Browse files
committed
docs: add schema construction examples
1 parent 36a012f commit 1e32112

File tree

1 file changed

+103
-4
lines changed

1 file changed

+103
-4
lines changed

README.md

+103-4
Original file line numberDiff line numberDiff line change
@@ -125,21 +125,120 @@ type MutationArticles {
125125

126126
You may use sub-folders for `Query` & `Mutation` and all servers supports this feature. But for `Subscription` most current server implementations (eg. [apollo-server](https://www.apollographql.com/docs/apollo-server/data/subscriptions/)) does not support this yet.
127127

128-
## API
128+
## GraphQLSchema construction
129129

130-
![overview](./docs/diagrams/ast-transformation.drawio.svg)
130+
In `schema` folder create a file `index.ts` with the following content which traverses `query`, `mutation`, `subscription` folders and create `GraphQLSchema` instance for you:
131+
132+
```ts
133+
import { buildSchema } from 'graphql-compose-modules';
134+
135+
export const schema = buildSchema(module);
136+
```
137+
138+
After that you may create a GraphQL server:
139+
140+
```ts
141+
import { ApolloServer } from 'apollo-server';
142+
import { schema } from './schema';
143+
144+
const server = new ApolloServer({ schema });
145+
146+
server.listen().then(({ url }) => {
147+
console.log(`🚀 Server ready at ${url}`);
148+
});
149+
```
150+
151+
## Advanced GraphQLSchema construction
152+
153+
If you want transform AST of entrypoints (e.g. for adding authorization, logging, tracing) and for merging with another schemas distributed via npm packages – you may use the following advanced way:
154+
155+
```ts
156+
import { directoryToAst, astToSchema, astMerge } from 'graphql-compose-modules';
157+
import { addQueryToMutations } from './transformers/addQueryToMutations';
158+
import { remoteServiceAST } from '@internal/some-service';
159+
160+
// traverse `query`, `mutation`, `subscription` folders placed near this module
161+
let ast = directoryToAst(module);
162+
163+
// apply transformer which uses astVisitor() method under the hood
164+
addQueryToMutations(ast);
165+
166+
// merge with other ASTs distributed via npm packages
167+
ast = astMerge(ast, remoteServiceAST);
168+
169+
// construct SchemaComposer
170+
const sc = astToSchema(ast);
171+
172+
// construct GraphQLSchema instance and export it
173+
export const schema = sc.buildSchema();
174+
```
175+
176+
## Writing own transformer for entrypoints
177+
178+
For writing your own transformers you need to use `astVisitor()` method. As an example let's implement `addQueryToMutations` transformer which adds `query: Query` field to all your mutations:
179+
180+
```ts
181+
import { astVisitor, VISITOR_SKIP_CHILDREN, AstRootNode } from 'graphql-compose-modules';
182+
import { ObjectTypeComposer, SchemaComposer } from 'graphql-compose';
183+
184+
export function addQueryToMutations(
185+
ast: AstRootNode,
186+
schemaComposer: SchemaComposer<any>
187+
): void {
188+
astVisitor(ast, {
189+
// skip `query` & `subscriptions` root types
190+
ROOT_TYPE: (node) => {
191+
if (node.name !== 'mutation') {
192+
return VISITOR_SKIP_CHILDREN;
193+
}
194+
return;
195+
},
196+
// for every file in `mutation` folder try to add `query` field if it does not exists
197+
FILE: (node, nodeInfo) => {
198+
const fieldConfig = node.code.default || {};
199+
const next = fieldConfig.resolve;
200+
if (!next) return;
201+
202+
const outputType = fieldConfig.type;
203+
if (!outputType) return;
204+
const outputTC = schemaComposer.typeMapper.convertOutputTypeDefinition(
205+
outputType,
206+
nodeInfo.name,
207+
nodeInfo?.parent?.name
208+
);
209+
if (!(outputTC instanceof ObjectTypeComposer)) return;
210+
if (outputTC.hasField('query')) return;
211+
outputTC.setField('query', {
212+
description: 'Sub-query which have to be executed after mutation.',
213+
type: schemaComposer.Query,
214+
});
215+
216+
fieldConfig.resolve = async (s: any, args: any, context: any, i: any) => {
217+
const result = await next(s, args, context, i);
218+
return {
219+
query: {},
220+
...result,
221+
};
222+
};
223+
},
224+
});
225+
}
226+
```
227+
228+
## API
131229

132230
For now I provide basic overview of available API methods and I will describe them later.
133231

134232
### Main API method:
135233

136-
- `buildSchema(module: NodeModule, opts: BuildOptions): GraphQLSchema` – use this method for creating graphql schema
234+
- `buildSchema(module: NodeModule, opts: BuildOptions): GraphQLSchema` – use this method for creating graphql schema from folder
137235

138236
### Advanced API methods:
139237

140238
The following methods helps to use schema composition, applying middlewares and schema transformation via visitor pattern:
141239

142-
- `loadSchemaComposer(module: NodeModule, options: BuildOptions): SchemaComposer` – construct SchemaComposer from folder (uses `directoryToAst` & `astToSchema` methods under the hood)
240+
![overview](./docs/diagrams/ast-transformation.drawio.svg)
241+
143242
- `directoryToAst(module: NodeModule, options: DirectoryToAstOptions): AstRootNode` – traverses directories and construct AST for your graphql entrypoints
144243
- `astToSchema(ast: AstRootNode, opts: AstToSchemaOptions): SchemaComposer` – converts AST to GraphQL Schema
145244
- `astMerge(...asts: Array<AstRootNode>): AstRootNode` – combines several ASTs to one AST (helps compose several graphql schemas)

0 commit comments

Comments
 (0)