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:
TypeScript
index.ts
1import { ApolloServer } from '@apollo/server';
2import { expressMiddleware } from '@apollo/server/express4';
3import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
4import typeDefs from './graphql/schema';
5import resolvers from './graphql/resolvers';
6import cors from 'cors';
7import express from 'express';
8import http from 'http';
9import https from 'https';
10import fs from 'fs';
11
12const configurations = {
13 // Note: You may need sudo to run on port 443
14 production: { ssl: true, port: 443, hostname: 'example.com' },
15 development: { ssl: false, port: 4000, hostname: 'localhost' },
16};
17
18const environment = process.env.NODE_ENV || 'production';
19const config = configurations[environment];
20
21const server = new ApolloServer({
22 typeDefs,
23 resolvers,
24});
25await server.start();
26
27const app = express();
28// our express server is mounted at /graphql
29app.use(
30 '/graphql',
31 cors<cors.CorsRequest>(),
32 express.json(),
33 expressMiddleware(server),
34);
35
36// Create the HTTPS or HTTP server, per configuration
37let httpServer;
38if (config.ssl) {
39 // Assumes certificates are in a .ssl folder off of the package root.
40 // Make sure these files are secured.
41 httpServer = https.createServer(
42 {
43 key: fs.readFileSync(`./ssl/${environment}/server.key`),
44 cert: fs.readFileSync(`./ssl/${environment}/server.crt`),
45 },
46
47 app,
48 );
49} else {
50 httpServer = http.createServer(app);
51}
52
53await new Promise<void>((resolve) => httpServer.listen({ port: config.port }, resolve));
54
55console.log('🚀 Server ready at', `http${config.ssl ? 's' : ''}://${config.hostname}:${config.port}/graphql`);