How to: Customize the Mesh server#
GraphQL Mesh provides a reliable and production-ready server implementation built with GraphQL Yoga and Envelop with, out of the box support for:
- Persisted queries
- Live queries
- Files upload
- Serverless deployment
- and more...
Customizing your GraphQL Mesh Gateway server can be achieved in 2 ways:
- Configure and provide Envelop plugins: to add behaviors such as caching, authentication, tracing to your Gateway
- Provide a standalone server implementation: to completely replace the server used by the Gateway
Configure and provide Envelop plugins#
Envelop is a library that helps build GraphQL API faster and flexibly with plugin-based architecture.
Similar to Express middlewares allowing you to customize requests' behavior, Envelop applies the same idea to GraphQL requests.
By exposing hooks in all the phases of a GraphQL Request execution, Envelop enables the creation of plugins that simplify the setup of standard API features such as:
- Security: Depth limits, Rate limiting
- Authentication
- Advanced caching
- Error handling: Sentry, error masking
- Monitoring: Hive
- Logging
- Tracing: NewRelic, Datadog, StatsD, Apollo Tracing
An Envelop plugin is a standalone npm
package that provides a plugin function that can be used in an Envelop setup to customize a GraphQL API behavior.
Examples of plugins are:
useGenericAuth
(@envelop/generic-auth
): Custom authentication flow by providing a custom user resolver.useDepthLimit
(@envelop/depth-limit
): Limit the depth of executed selection sets.
The GraphQL Mesh configuration accepts a additionalEnvelopPlugins
parameter that should point to a file that exports a list of Envelop plugins, as shown below:
.meshrc.yaml
sources:
# ...
additionalEnvelopPlugins: "./envelopPlugins"
envelopPlugins.ts
import { PluginOrDisabledPlugin } from "@envelop/core"
import { useDepthLimit } from '@envelop/depth-limit';
import { useSentry } from '@envelop/sentry';
const plugins: PluginOrDisabledPlugin = [
useDepthLimit({
maxDepth: 10,
}),
useSentry({
includeRawResult: false
}),
]
export default plugins
Note: The file can also export a factory function returning a PluginOrDisabledPlugin
list
Provide a standalone server implementation#
Disclaimer: This section explains how to provide a custom server implementation used by mesh serve
and mesh dev
. If you are looking for solutions to deploy Mesh to Serverless environments or not rely on mesh serve
, please refer to the "How to: Deploy a Mesh Gateway" guide.
The following example shows how to replace GraphQL Mesh's default server implementation with Apollo Server .
GraphQL Mesh uses Envelop under the hood, so you need to check other integrations to see how to use getEnveloped
with other server frameworks. Envelop Integrations
myServerHandler.ts
import { ApolloServer } from 'apollo-server';
import type { ServeMeshOptions } from '@graphql-mesh/runtime';
export default async function ({ getBuiltMesh, logger, argsPort }: ServeMeshOptions): Promise<void> {
const { schema, getEnveloped } = await getBuiltMesh();
const apolloServer = new ApolloServer({
schema,
executor: async requestContext => {
const { schema, execute, contextFactory } = getEnveloped({ req: requestContext.request.http });
return execute({
schema: schema,
document: requestContext.document,
contextValue: await contextFactory(),
variableValues: requestContext.request.variables,
operationName: requestContext.operationName,
});
},
});
const { url } = await apolloServer.listen(argsPort);
logger.info(`🚀 Server ready at ${url}`);
}
Then add the following line to your configuration file.
.meshrc.yaml
serve:
customServerHandler: ./myServerHandler
When you use a custom server handler, you won't be able to use configuration options under serve
!
Configuration: serve
reference#
fork
- - Spawn multiple server instances as node clusters (default:1
) One of:Int
Boolean
port
- - TCP Port to listen (default:3000
) One of:Int
String
hostname
(type:String
) - The binding hostname (default:localhost
)cors
(type:Object
) - Configuration for CORS:origin
(type:Any
)allowedHeaders
(type:Array of String
)exposedHeaders
(type:Array of String
)credentials
(type:Boolean
)maxAge
(type:Int
)preflightContinue
(type:Boolean
)optionsSuccessStatus
(type:Int
)
handlers
- - Express/Connect compatible handlers and middlewares extend GraphQL Mesh HTTP Server Array of:object
:path
(type:String
, required) - Path that remote API will pingmethod
(type:String (GET | POST | DELETE | PATCH)
) - HTTP Method that the handler will controlpubsubTopic
(type:String
, required) - Name of the topic you want to pass incoming payloadpayload
(type:String
) - Part of the object you want to pass (e.g.data.messages
)
object
:path
(type:String
, required) - Path that the handler will controlhandler
(type:String
, required) - Path of the handler's codemethod
(type:String (GET | POST | DELETE | PATCH)
) - HTTP Method that the handler will control
staticFiles
(type:String
) - Path to your static files you want to be served with GraphQL Mesh HTTP Serverplayground
(type:Boolean
) - Show GraphiQL PlaygroundsslCredentials
(type:Object
) - SSL Credentials for HTTPS Server If this is provided, Mesh will be served via HTTPS:key
(type:String
, required)cert
(type:String
, required)
endpoint
(type:String
) - Path to GraphQL Endpoint (default: /graphql)browser
- - Path to the browser that will be used bymesh serve
to open a playground window in development mode This feature can be disable by passingfalse
One of:String
Boolean
customServerHandler
(type:String
) - If you want to use a custom GraphQL server, you can pass the path of the code file that exports a custom Mesh Server Handler With a custom server handler, you won't be able to use the features of GraphQL Mesh HTTP ServerplaygroundTitle
(type:String
) - Title of GraphiQL Playground