Terminating SSL
In the examples below, we use top-level await
calls to start our server asynchronously. Check out our Getting Started guide to see how we configured our project to support this.
Most production environments use a load balancer or HTTP proxy (such as nginx) to perform SSL termination on behalf of web applications in that environment.
If you're using Apollo Server in an application that must perform its own SSL termination, you can use the https
module with the expressMiddleware
function.
Here's an example that uses HTTPS in production and HTTP in development:
index.ts
import { ApolloServer } from '@apollo/server';import { expressMiddleware } from '@apollo/server/express4';import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';import typeDefs from './graphql/schema';import resolvers from './graphql/resolvers';import cors from 'cors';import bodyParser from 'body-parser';import express from 'express';import http from 'http';import https from 'https';import fs from 'fs';const configurations = {// Note: You may need sudo to run on port 443production: { ssl: true, port: 443, hostname: 'example.com' },development: { ssl: false, port: 4000, hostname: 'localhost' },};const environment = process.env.NODE_ENV || 'production';const config = configurations[environment];const server = new ApolloServer({typeDefs,resolvers,});await server.start();const app = express();// our express server is mounted at /graphqlapp.use('/graphql', cors<cors.CorsRequest>(), bodyParser.json(), expressMiddleware(server));// Create the HTTPS or HTTP server, per configurationlet httpServer;if (config.ssl) {// Assumes certificates are in a .ssl folder off of the package root.// Make sure these files are secured.httpServer = https.createServer({key: fs.readFileSync(`./ssl/${environment}/server.key`),cert: fs.readFileSync(`./ssl/${environment}/server.crt`),},app,);} else {httpServer = http.createServer(app);}await new Promise<void>((resolve) => httpServer.listen({ port: config.port }, resolve));console.log('🚀 Server ready at', `http${config.ssl ? 's' : ''}://${config.hostname}:${config.port}/graphql`);
index.js
import { ApolloServer } from '@apollo/server';import { expressMiddleware } from '@apollo/server/express4';import typeDefs from './graphql/schema';import resolvers from './graphql/resolvers';import cors from 'cors';import bodyParser from 'body-parser';import express from 'express';import http from 'http';import https from 'https';import fs from 'fs';const configurations = {// Note: You may need sudo to run on port 443production: { ssl: true, port: 443, hostname: 'example.com' },development: { ssl: false, port: 4000, hostname: 'localhost' },};const environment = process.env.NODE_ENV || 'production';const config = configurations[environment];const server = new ApolloServer({typeDefs,resolvers,});await server.start();const app = express();// our express server is mounted at /graphqlapp.use('/graphql', cors(), bodyParser.json(), expressMiddleware(server));// Create the HTTPS or HTTP server, per configurationlet httpServer;if (config.ssl) {// Assumes certificates are in a .ssl folder off of the package root.// Make sure these files are secured.httpServer = https.createServer({key: fs.readFileSync(`./ssl/${environment}/server.key`),cert: fs.readFileSync(`./ssl/${environment}/server.crt`),},app,);} else {httpServer = http.createServer(app);}await new Promise((resolve) => httpServer.listen({ port: config.port }, resolve));console.log('🚀 Server ready at', `http${config.ssl ? 's' : ''}://${config.hostname}:${config.port}/graphql`);