API Reference: startStandaloneServer
This API reference documents the startStandaloneServer function.
Overview
This startStandaloneServer function helps you get started with Apollo Server quickly. This function is recommended for all projects that don't require serverless support or a particular Node.js framework (such as Fastify). Under the hood, the startStandaloneServer function uses Apollo Server 4's Express integration (i.e., expressMiddleware).
Because it sets helpful defaults, this function is less configurable than other Apollo Server integrations. Complex projects might eventually need to swap to using expressMiddleware (this process is straightforward).
startStandaloneServer
The startStandaloneServer function accepts two arguments. The first required argument is the instance of ApolloServer to begin listening for incoming requests:
import { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';const server = new ApolloServer({ typeDefs, resolvers });// `startStandaloneServer` returns a `Promise` with the// the URL that the server is listening on.const { url } = await startStandaloneServer(server);
import { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';const server = new ApolloServer({ typeDefs, resolvers });// `startStandaloneServer` returns a `Promise` with the// the URL that the server is listening on.const { url } = await startStandaloneServer(server);
The startStandaloneServer function's second optional argument is an object for configuring your server's options, which can contain the following properties:
Options
| Name / Type | Description |
|---|---|
| An optional asynchronous The The |
| An optional If no |
Example
Below is a full example of setting up startStandaloneServer:
// npm install @apollo/server graphqlimport { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';import { typeDefs, resolvers } from './schema';interface MyContext {token?: String;}async function startApolloServer() {const server = new ApolloServer<MyContext>({ typeDefs, resolvers });const { url } = await startStandaloneServer(server, {context: async ({ req }) => ({ token: req.headers.token }),listen: { port: 4000 },});console.log(`🚀 Server ready at ${url}`);}
// npm install @apollo/server graphqlimport { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';import { typeDefs, resolvers } from './schema';async function startApolloServer() {const server = new ApolloServer({ typeDefs, resolvers });const { url } = await startStandaloneServer(server, {context: async ({ req }) => ({ token: req.headers.token }),listen: { port: 4000 },});console.log(`🚀 Server ready at ${url}`);}
Swapping to expressMiddleware
The startStandaloneServer function is not right for every use case, particularly if you need to customize your server's behavior. For example, you might want to customize your CORS behavior, run some middleware before processing GraphQL requests, or serve other endpoints from the same server.
In these cases, we recommend you swap out startStandaloneServer for expressMiddleware (unless you are confident that you want to use a different Node.js framework). This change requires only a few lines and has a minimal effect on your server's existing behavior (startStandaloneServer uses expressMiddleware under the hood).
We recommend Express because it's the most popular Node.js web framework, and it integrates well with many other popular libraries. It does have its limitations (for example, Express async support is not built around Promises and async functions), but backward incompatible changes to the framework are rarer than in newer libraries.
Example
Let's say our current startStandaloneServer setup uses the following code:
import { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';import { typeDefs, resolvers } from './schema';interface MyContext {token?: String;}async function startApolloServer() {const server = new ApolloServer<MyContext>({ typeDefs, resolvers });const { url } = await startStandaloneServer(server, {context: async ({ req }) => ({ token: req.headers.token }),listen: { port: 4000 },});console.log(`🚀 Server ready at ${url}`);}
import { ApolloServer } from '@apollo/server';import { startStandaloneServer } from '@apollo/server/standalone';import { typeDefs, resolvers } from './schema';async function startApolloServer() {const server = new ApolloServer({ typeDefs, resolvers });const { url } = await startStandaloneServer(server, {context: async ({ req }) => ({ token: req.headers.token }),listen: { port: 4000 },});console.log(`🚀 Server ready at ${url}`);}
To swap to using expressMiddleware, you'll first need to install the following packages so you'll be able to set up HTTP body parsing and CORS for your server:
npm install express cors body-parser
Next, we can modify our code to match the following:
// npm install @apollo/server express graphql cors body-parserimport { ApolloServer } from '@apollo/server';import { expressMiddleware } from '@apollo/server/express4';import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';import express from 'express';import http from 'http';import cors from 'cors';import bodyParser from 'body-parser';import { typeDefs, resolvers } from './schema';interface MyContext {token?: String;}async function startApolloServer() {// Required logic for integrating with Expressconst app = express();// Our httpServer handles incoming requests to our Express app.// Below, we tell Apollo Server to "drain" this httpServer,// enabling our servers to shut down gracefully.const httpServer = http.createServer(app);// Same ApolloServer initialization as before, plus the drain plugin// for our httpServer.const server = new ApolloServer<MyContext>({typeDefs,resolvers,plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],});// Ensure we wait for our server to startawait server.start();// Set up our Express middleware to handle CORS, body parsing,// and our expressMiddleware function.app.use('/',cors<cors.CorsRequest>(),bodyParser.json(),// expressMiddleware accepts the same arguments:// an Apollo Server instance and optional configuration optionsexpressMiddleware(server, {context: async ({ req }) => ({ token: req.headers.token }),}),);// Modified server startupawait new Promise<void>(resolve => httpServer.listen({ port: 4000 }, resolve));console.log(`🚀 Server ready at http://localhost:4000/`);}
// npm install @apollo/server express graphql cors body-parserimport { ApolloServer } from '@apollo/server';import { expressMiddleware } from '@apollo/server/express4';import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';import express from 'express';import http from 'http';import cors from 'cors';import bodyParser from 'body-parser';import { typeDefs, resolvers } from './schema';async function startApolloServer() {// Required logic for integrating with Expressconst app = express();// Our httpServer handles incoming requests to our Express app.// Below, we tell Apollo Server to "drain" this httpServer,// enabling our servers to shut down gracefully.const httpServer = http.createServer(app);// Same ApolloServer initialization as before, plus the drain plugin// for our httpServer.const server = new ApolloServer({typeDefs,resolvers,plugins: [ApolloServerPluginDrainHttpServer({ httpServer })],});// Ensure we wait for our server to startawait server.start();// Set up our Express middleware to handle CORS, body parsing,// and our expressMiddleware function.app.use('/',cors(),bodyParser.json(),// expressMiddleware accepts the same arguments:// an Apollo Server instance and optional configuration optionsexpressMiddleware(server, {context: async ({ req }) => ({ token: req.headers.token }),}),);// Modified server startupawait new Promise(resolve => httpServer.listen({ port: 4000 }, resolve));console.log(`🚀 Server ready at http://localhost:4000/`);}