First Steps
Using Envelop is straight-forward and intuitive, in this section you will learn how to install and set up a GraphQL server using Envelop from scratch.
In case you are being referred to the Envelop documentation from a framework or library that implements envelop, you can straight dive into the Plugin Hub or head over to the Plugin Tutorial for learning how to write your plugins.
Installation
Start by adding the core of envelop
and graphql
to your codebase.
npm i @envelop/core graphql
Create Your First Envelop
After installing the @envelop/core
package, you can use the envelop
function for creating your
getEnveloped
function. We use a simple GraphQL schema that we build with the buildSchema
function from graphql
.
import * as GraphQLJS from 'graphql'
import { envelop, useEngine, useSchema } from '@envelop/core'
const schema = GraphQLJS.buildSchema(/* GraphQL */ `
type Query {
hello: String
}
`)
export const getEnveloped = envelop({
plugins: [useEngine(GraphQLJS), useSchema(schema)]
})
Use Your Envelop
The result of envelop
is a factory function that allows you to get everything you need for the
GraphQL execution: parse
, validate
, contextBuilder
, execute
and subscribe
. It is usually
named getEnveloped
.
By calling the getEnveloped
function you will get all the primitive functions required for the
GraphQL execution layer.
// prettier-ignore
const {
contextFactory,
parse,
validate,
execute,
subscribe,
schema,
} = getEnveloped()
Add Plugins to Your Envelop
After you set up your base Envelop, you can start customizing your GraphQL server. Adding new functionality is as easy as adding a new envelop plugin to your base envelop setup.
Let’s add a parser and validation cache, so sending the same operation string sent to our server is cached using an LRU cache, allowing to improve the overall performance of the GraphQL execution layer.
npm i @envelop/parser-cache @envelop/validation-cache
import * as GraphQLJS from 'graphql'
import { buildSchema } from 'graphql'
import { envelop, useEngine, useSchema } from '@envelop/core'
import { useParserCache } from '@envelop/parser-cache'
import { useValidationCache } from '@envelop/validation-cache'
const schema = buildSchema(/* GraphQL */ `
type Query {
hello: String
}
`)
const getEnveloped = envelop({
plugins: [
useEngine(GraphQLJS),
// all enabled plugins
useSchema(schema),
useParserCache(),
useValidationCache()
]
})
Use Your Envelop with an HTTP Server
You can build a very simple GraphQL HTTP server from scratch, by using the Node.js http
module and
only these functions.
import { createServer } from 'node:http'
import { GraphQLError } from 'graphql'
import { getEnveloped } from './envelop'
const httpServer = createServer(async (req, res) => {
try {
// body parsing
req.body = await new Promise((resolve, reject) => {
let data = ''
req.on('data', chunk => {
data += String(chunk)
})
req.on('end', () => {
resolve(data)
})
req.on('error', err => reject(err))
})
const {
// Get the GraphQL execution functions with attached plugin handlers
parse,
validate,
contextFactory,
execute,
schema
// pass in an initial context that all plugins can consume and extend
} = getEnveloped({ req })
// Parse request body JSON
const { query, variables } = JSON.parse(req.body)
const document = parse(query)
const validationErrors = validate(schema, document)
if (validationErrors.length > 0) {
return res.end(JSON.stringify({ errors: validationErrors }))
}
// Build the context and execute
const contextValue = await contextFactory()
const result = await execute({
document,
schema,
variableValues: variables,
contextValue
})
// Send the response
res.end(JSON.stringify(result))
} catch (err) {
if (err instanceof GraphQLError === false) {
err = new GraphQLError(err.message)
}
res.end(JSON.stringify({ errors: [err] }))
}
})
httpServer.listen(3000)
After starting this server we can send a GraphQL operation using curl
, yielding a response of
{"data":{"__typename":"Query"}}
.
curl \
-X POST \
-d '{"query":"{__typename}"}' \
http://localhost:3000
This example uses the Node.js http
module and is a very simplified handler that does not
strictly follow the GraphQL over HTTP
specification as it does not handle headers or
respect HTTP methods. For actual production usage, we recommend using Envelop with one of the
popular and battle-tested HTTP frameworks and servers. Check the examples on our Integrations
page.