Each module contains GraphQL Type definitions, unique id and optionally resolvers.
What Happened Here?
We are using createModule to declare our module, and name it as my-module. Naming is important because it helps you to locate issues in your type definition.
We also added dirname and pointed it to __dirname to make it simpler later to match the exception to the correct file. It’s optional but useful.
Next, there are typeDefs and resolvers which you should already know if you are familiar with GraphQL. It defines the type we have in that module and the implementation behind it.
At this point, this module acts like a type “capsule” you can load and import to various GraphQL Applications.
Use Your Module
As mentioned before, Modules create Application, so let’s create one. We are importing the module we created earlier, and provide it to the application:
import { createApplication } from 'graphql-modules'import { myModule } from './my-module'// This is your application, it contains your GraphQL schema and the implementation of it.const application = createApplication({ modules: [myModule]})// This is your actual GraphQL schemaconst mySchema = application.schema
Use Your Application
Now that you have Module, Application and you got your GraphQLSchema, you need to make it available to consumption.
GraphQL-Modules allow you to do much more, like managing the lifecycle of your execution, encapsulating your HTTP request and more. To do that in the most optimal and flexible way, we need to wrap the GraphQL execution flow. Some GraphQL server’s implementation allows this kind of flexibility, and some don’t.
But we got you covered, and provided solutions for all popular GraphQL server implementations.
Your GraphQL Application exposes createExecution and createSubscription methods, which are just plug-and-play replacements for the default functions from graphql-js.
import express from 'express'import graphqlHTTP from 'express-graphql'import { application } from './application'const execute = application.createExecution()const schema = application.schemaconst server = express()server.use( '/', graphqlHTTP({ schema, customExecuteFn: execute, graphiql: true }))server.listen(4000, () => { console.log(`🚀 Server ready at http://localhost:4000/`)})
If you are using GraphQL-Helix, here’s how you do it:
import express from 'express'import { getGraphQLParameters, processRequest } from 'graphql-helix'import { application } from './application'const app = express()app.use(express.json())app.use('/graphql', async (req, res) => { const request = { body: req.body, headers: req.headers, method: req.method, query: req.query } const { operationName, query, variables } = getGraphQLParameters(request) const result = await processRequest({ operationName, query, variables, request, schema: application.schema, execute: application.createExecution(), subscribe: application.createSubscription() }) result.headers.forEach(({ name, value }) => res.setHeader(name, value)) res.status(result.status) res.json(result.payload)})app.listen(port, () => { console.log(`GraphQL server is running on port ${port}.`)})
If you are using a different server or setup, you can get the custom execute and subscribe functions from your Application, and provide it to your server: