Skip to content

Commit 41f98d4

Browse files
glasserMeschreiber
andauthored
docs: support Express v5, recommend new separate Express packages (#8064)
The built-in `expressMiddleware` in `@apollo/server/express4` only supports Express v4, and that's not going to change. But Express v5 is now released. So we have released separate packages `@as-integrations/express4` and `@as-integrations/express5`. The next major version of Apollo Server will drop the hard-coded built-in integrations, putting all JS web frameworks on the same playing field where you have to install a small integration package to use it. This PR: - Documents that the two new packages exist (and that the old export does still work) - Changes most examples to use the new Express v5 integration - Changes the AS3 to AS4 migration guide to use the new Express v4 integration (assuming that anyone migrating from AS3 is not on the brand-new version of Express) Fixes #7928. --------- Co-authored-by: Maria Elisabeth Schreiber <maria.schreiber@apollographql.com>
1 parent 4f7d02d commit 41f98d4

13 files changed

+58
-32
lines changed

.changeset/stupid-insects-love.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@apollo/server': patch
3+
---
4+
5+
Update README.md to recommend Express v5 integration now that Express v5 is released.

docs/source/api/express-middleware.mdx

+15-3
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,18 @@ import TopLevelAwait from "../shared/top-level-await.mdx"
77

88
This API reference documents Apollo Server 4's [Express](https://expressjs.com/) integration, the `expressMiddleware` function.
99

10+
Apollo Server integrates with these Express versions through official integrations:
11+
- [**Express v4**](https://www.npmjs.com/package/@as-integrations/express4): Install with `npm install @as-integrations/express4`
12+
- [**Express v5**](https://www.npmjs.com/package/@as-integrations/express5): Install with `npm install @as-integrations/express5`
13+
14+
You must also install Express itself. Both packages export a function named `expressMiddleware` with the same API.
15+
16+
<Note>
17+
18+
The Express v4 integration is also bundled in `@apollo/server` at `@apollo/server/express4`. While you can use this bundled version now, we recommend installing the separate package. Express v5 requires the separate package, and future Apollo Server versions will remove the bundled integration.
19+
20+
</Note>
21+
1022
## `expressMiddleware`
1123

1224
<TopLevelAwait />
@@ -23,7 +35,7 @@ The `expressMiddleware` function accepts two arguments. The first **required** a
2335

2436
```ts
2537
import { ApolloServer } from '@apollo/server';
26-
import { expressMiddleware } from '@apollo/server/express4';
38+
import { expressMiddleware } from '@as-integrations/express5';
2739
import cors from 'cors';
2840
import express from 'express';
2941

@@ -95,10 +107,10 @@ Below is a full example of setting up `expressMiddleware`:
95107
<MultiCodeBlock>
96108

97109
```ts
98-
// npm install @apollo/server express graphql cors
110+
// npm install @apollo/server @as-integrations/express5 express graphql cors
99111
import { ApolloServer } from '@apollo/server';
100-
import { expressMiddleware } from '@apollo/server/express4';
101112
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
113+
import { expressMiddleware } from '@as-integrations/express5';
102114
import express from 'express';
103115
import http from 'http';
104116
import cors from 'cors';

docs/source/api/plugin/drain-http-server.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,8 @@ This plugin is exported from the `@apollo/server` package. Here's a basic exampl
3131

3232
```ts title="index.ts"
3333
import { ApolloServer } from '@apollo/server';
34-
import { expressMiddleware } from '@apollo/server/express4';
3534
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
35+
import { expressMiddleware } from '@as-integrations/express5';
3636
import express from 'express';
3737
import http from 'http';
3838
import cors from 'cors';

docs/source/api/standalone.mdx

+6-4
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ The `startStandaloneServer` function is not right for every use case, particular
124124

125125
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).
126126

127-
> 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 `Promise`s and `async` functions), but backward incompatible changes to the framework are rarer than in newer libraries.
127+
> We recommend Express because it's the most popular Node.js web framework, and it integrates well with many _other_ popular libraries.
128128
129129
### Example
130130

@@ -150,20 +150,22 @@ console.log(`🚀 Server ready at ${url}`);
150150
```
151151
</MultiCodeBlock>
152152

153-
To swap to using `expressMiddleware`, you'll first need to install the following packages so you'll be able to set up CORS for your server:
153+
To swap to using `expressMiddleware`, you'll first need to install the following packages: the Express library, Apollo's integration between Express and Apollo Server, and the CORS middleware for Express:
154154

155155
```bash
156-
npm install express cors
156+
npm install @as-integrations/express5 express cors
157157
```
158158

159+
Note that this should install v5 of Express.
160+
159161
Next, we can modify our code to match the following:
160162

161163
<MultiCodeBlock>
162164

163165
```ts
164166
// npm install @apollo/server express graphql cors
165167
import { ApolloServer } from '@apollo/server';
166-
import { expressMiddleware } from '@apollo/server/express4';
168+
import { expressMiddleware } from '@as-integrations/express5';
167169
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
168170
import express from 'express';
169171
import http from 'http';

docs/source/data/subscriptions.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,8 @@ A completed example of setting up subscriptions is shown below:
139139

140140
```ts title="index.ts"
141141
import { ApolloServer } from '@apollo/server';
142-
import { expressMiddleware } from '@apollo/server/express4';
143142
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
143+
import { expressMiddleware } from '@as-integrations/express5';
144144
import { createServer } from 'http';
145145
import express from 'express';
146146
import { makeExecutableSchema } from '@graphql-tools/schema';

docs/source/deployment/lambda.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -470,7 +470,7 @@ If you've [changed your setup to use `@vendia/serverless-express`](#customizing-
470470

471471
```ts
472472
const { ApolloServer } = require('@apollo/server');
473-
const { expressMiddleware } = require('@apollo/server/express4');
473+
const { expressMiddleware } = require('@as-integrations/express5');
474474
const serverlessExpress = require('@vendia/serverless-express');
475475
const express = require('express');
476476
const cors = require('cors');
@@ -519,7 +519,7 @@ You can update your Apollo Server setup to the following to have a fully functio
519519

520520
```ts
521521
const { ApolloServer } = require('@apollo/server');
522-
const { expressMiddleware } = require('@apollo/server/express4');
522+
const { expressMiddleware } = require('@as-integrations/express5');
523523
const serverlessExpress = require('@vendia/serverless-express');
524524
const express = require('express');
525525
const cors = require('cors');

docs/source/integrations/building-integrations.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ Server in their web framework of choice.
1515
## Overview
1616

1717
The primary responsibility of an Apollo Server integration is to translate
18-
requests and responses between a web framework's native format to the format used by `ApolloServer`. This article conceptually covers how to build an integration, using the [Express integration](https://github.com/apollographql/apollo-server/blob/main/packages/server/src/express4/index.ts) (i.e.,`expressMiddleware`) as an example.
18+
requests and responses between a web framework's native format to the format used by `ApolloServer`. This article conceptually covers how to build an integration, using the [Express integration](https://github.com/apollo-server-integrations/apollo-server-integration-express5/blob/main/src/index.ts) (i.e.,`expressMiddleware`) as an example.
1919

20-
> For more examples, see these Apollo Server 4 [integrations demos for Fastify and Lambda](https://github.com/apollographql/server-v4-integration-demos/tree/main/packages).
20+
> For more examples, see the source of the [community-maintained Apollo Server integrations](./integration-index).
2121
2222
If you are building a serverless integration, we **strongly recommend** prepending your function name with the word `start` (e.g., `startServerAndCreateLambdaHandler(server)`). This naming convention helps maintain Apollo Server's standard that every server uses a function or method whose name contains the word `start` (such as `startStandaloneServer(server)`.
2323

@@ -118,7 +118,7 @@ Apollo Server responds to a variety of requests via both `GET` and `POST` such a
118118

119119
Integrations _are_ responsible for parsing a request's body and using the values to construct the `HTTPGraphQLRequest` that Apollo Server expects.
120120

121-
In Apollo Server 4's Express integration, a user sets up the `body-parser` JSON middleware, which handles parsing JSON request bodies with a `content-type` of `application/json`. Integrations can require a similar middleware (or plugin) for their ecosystem, or they can handle body parsing themselves.
121+
In Apollo Server 4's Express integration, you set up the `express.json()` JSON middleware, which handles parsing JSON request bodies with a `content-type` of `application/json`. Integrations can require a similar middleware (or plugin) for their ecosystem, or they can handle body parsing themselves.
122122

123123
For example, a correctly parsed body should have a shape resembling this:
124124

docs/source/integrations/integration-index.mdx

+6-2
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ import IntegrationTable from "../shared/integration-table.mdx"
66

77
> Are you looking to build a new integration? Or help maintain an existing integration? See [Building Web Framework Integrations for Apollo Server](./building-integrations) for step-by-step guidance!
88
9-
Apollo Server 4 includes two built-in integrations: [`startStandaloneServer`](../api/standalone) and [`expressMiddleware`](../api/express-middleware).
9+
Apollo Server 4's [`startStandaloneServer`](../api/standalone) function spins up a basic web server with sensible defaults. The server is a fully functional GraphQL server supporting all of Apollo Server's GraphQL-level customizations, but it offers minimal opportunities for HTTP-level configuration.
1010

11-
The `startStandaloneServer` function sets useful defaults to get you started quickly. Under the hood, the `startStandaloneServer` function uses Apollo Server 4's Express integration (i.e., `expressMiddleware`). The `expressMiddleware` function is Apollo Server 4's [Express](https://expressjs.com/) integration.
11+
If you need more control over how your GraphQL server speaks HTTP, you should instead use an _integration_. Integrations are packages which connect the Apollo Server API to your favorite web framework.
12+
13+
Apollo maintains an [integration](../api/express-middleware) between Apollo Server and [Express](https://expressjs.com/), the most popular Node.js web framework. The integration with Express v4 is published as [`@as-integrations/express4`](https://www.npmjs.com/package/@as-integrations/express), and the integration with Express v5 is published as [`@as-integrations/express5`](https://www.npmjs.com/package/@as-integrations/express5). Both packages export the function [`expressMiddleware`](../api/express-middleware).
14+
15+
> The Express v4 integration is also included in the main `@apollo/server` package, exported from `@apollo/server/express4`. Its behavior is identical to the `@as-integrations/express4`. Express v5 is only supported by the external package. (A future major version of Apollo Server will remove `@apollo/server/express4`.)
1216
1317
> Have you built, or are you maintaining, an Apollo Server integration that isn't listed here? Please [submit a PR](https://github.com/apollographql/apollo-server/blob/main/docs/source/integrations/integration-index.mdx) to be added to this list!
1418

docs/source/integrations/mern.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ import records from "./routes/record.js";
133133
import gql from "graphql-tag";
134134
import { ApolloServer } from '@apollo/server';
135135
import { buildSubgraphSchema } from '@apollo/subgraph';
136-
import { expressMiddleware } from '@apollo/server/express4';
136+
import { expressMiddleware } from '@as-integrations/express5';
137137
import resolvers from "./resolvers.js";
138138
import { readFileSync } from "fs";
139139
//highlight-end

docs/source/migration.mdx

+10-6
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ Apollo Server 4 focuses on improving Apollo Server's extensibility and making it
1111

1212
Apollo Server 4 provides the following features:
1313
* A well-defined API with a stable HTTP abstraction, enabling contributors to easily [build and maintain integrations](./integrations/building-integrations) in their preferred frameworks.
14-
* A new `@apollo/server` package, combining numerous [smaller packages](#packages-merged-into-apolloserver) and including the [`startStandaloneServer`](#migrate-from-apollo-server) and [`expressMiddleware`](#migrate-from-apollo-server-express) functions.
14+
* A new `@apollo/server` package, combining numerous [smaller packages](#packages-merged-into-apolloserver) and including the [`startStandaloneServer`](#migrate-from-apollo-server) function.
15+
* Apollo-maintained packages to integrate with the Express web framework via the [`expressMiddleware`](#migrate-from-apollo-server-express) function.
1516
* Packages that can be used as either ECMAScript or CJS modules.
1617
* Experimental support for [incremental delivery](./workflow/requests#incremental-delivery-experimental) when combined with a pre-release of `graphql-js`.
1718

@@ -32,7 +33,6 @@ Apollo Server 4 takes a different approach to integrations by providing a stable
3233
The new `@apollo/server` package contains:
3334

3435
- The `ApolloServer` class
35-
- An [Express 4 integration](#migrate-from-apollo-server-express) (similar to Apollo Server 3's `apollo-server-express` package)
3636
- A [standalone server](#migrate-from-apollo-server) (similar to Apollo Server 3's `apollo-server` package)
3737
- A set of [core plugins](#plugins-are-in-deep-imports) (similar to Apollo Server 3's `apollo-server-core` package)
3838

@@ -53,10 +53,12 @@ graph TB;
5353
```
5454

5555
- If you're currently using the `apollo-server` package, you should use the [`startStandaloneServer`](#migrate-from-apollo-server) function.
56-
- If you're currently using the `apollo-server-express` package, you should use the [`expressMiddleware`](#migrate-from-apollo-server-express) function.
56+
- If you're currently using the `apollo-server-express` package, you should use the [`expressMiddleware`](#migrate-from-apollo-server-express) function in the `@as-integrations/express4` package.
5757

5858
The [`@apollo/server` package](https://www.npmjs.com/package/@apollo/server) exports these functions alongside the `ApolloServer` class.
5959

60+
> In Apollo Server 4, `@apollo/server` also contains a copy of the same `expressMiddleware` function from `@as-integrations/express4` package. We recommend you use the separate integration package instead of the copy in `@apollo/server`, which a future major version of Apollo Server will remove.
61+
6062
If you are using another Apollo Server 3 framework integration package (such as `apollo-server-koa` or `apollo-server-lambda`), check out our [list of integrations](./integrations/integration-index) to see if a community-maintained integration package exists for your framework of choice.
6163

6264
If there is no Apollo Server integration for your favorite framework _yet_, help the broader community by [building a new integration](./integrations/building-integrations)! You can also [join the discussions about maintaining our existing integrations](https://github.com/apollographql/apollo-server/labels/integration-collaborators).
@@ -187,9 +189,11 @@ Similarly, if you used the `stopGracePeriodMillis` constructor option in Apollo
187189

188190
If you used the `apollo-server-express` package in Apollo Server 3, use the `expressMiddleware` function in Apollo Server 4 (i.e., instead of using `server.applyMiddleware` or `server.getMiddleware`).
189191

192+
> The following assumes you are using Express v4. If you would like to use Express v5 (which was not supported by Apollo Server 3), you can follow the instructions below, but use the package `@as-integrations/express5` instead of `@as-integrations/express4`.
193+
190194
To migrate from Apollo Server 3's `apollo-server-express` package to using the `expressMiddleware` function, do the following:
191195

192-
1. Install the `@apollo/server` and `cors` packages.
196+
1. Install the `@apollo/server`, `@as-integrations/express4`, and `cors` packages.
193197
2. Import symbols from `@apollo/server` (i.e., instead of from `apollo-server-express` and `apollo-server-core`).
194198
3. Add `cors` to your server setup.
195199
4. Remove the Apollo Server 3 `apollo-server-express` and `apollo-server-core` packages.
@@ -234,8 +238,8 @@ looks like this in Apollo Server 4:
234238
```ts title="apollo-server-4.ts"
235239
// npm install @apollo/server express graphql cors
236240
import { ApolloServer } from '@apollo/server';
237-
import { expressMiddleware } from '@apollo/server/express4';
238241
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
242+
import { expressMiddleware } from '@as-integrations/express4';
239243
import express from 'express';
240244
import http from 'http';
241245
import cors from 'cors';
@@ -1923,7 +1927,7 @@ This section lists the TypeScript-only types (i.e., interfaces, not classes) tha
19231927

19241928
Apollo Server 4 changes the name of the constructor options type from `Config` to `ApolloServerOptions`. In Apollo Server 3, some integration packages export their own versions of this type (e.g., `ApolloServerExpressConfig`). In Apollo Server 4, there is only one `ApolloServer` type with only one constructor, so these additional types are no longer necessary.
19251929

1926-
Two types in `apollo-server-express` now have more explicit names exported from `@apollo/server/express4`. `GetMiddlewareOptions` is now `ExpressMiddlewareOptions` and `ExpressContext` is now `ExpressContextFunctionArgument`.
1930+
Two types in `apollo-server-express` now have more explicit names exported from `@as-integrations/express4`. `GetMiddlewareOptions` is now `ExpressMiddlewareOptions` and `ExpressContext` is now `ExpressContextFunctionArgument`.
19271931

19281932
### Removed types
19291933

docs/source/security/cors.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,8 @@ Below, we set up and customize the CORS behavior for our `expressMiddleware` fun
100100

101101
```ts
102102
import { ApolloServer } from '@apollo/server';
103-
import { expressMiddleware } from '@apollo/server/express4';
104103
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
104+
import { expressMiddleware } from '@as-integrations/express5';
105105
import express from 'express';
106106
import http from 'http';
107107
import { typeDefs, resolvers } from './schema';

docs/source/security/terminating-ssl.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ Here's an example that uses HTTPS in production and HTTP in development:
1616

1717
```ts title="index.ts"
1818
import { ApolloServer } from '@apollo/server';
19-
import { expressMiddleware } from '@apollo/server/express4';
2019
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer';
20+
import { expressMiddleware } from '@as-integrations/express5';
2121
import typeDefs from './graphql/schema';
2222
import resolvers from './graphql/resolvers';
2323
import cors from 'cors';

packages/server/README.md

+6-7
Original file line numberDiff line numberDiff line change
@@ -90,30 +90,29 @@ Open the URL it prints in a web browser. It will show [Apollo Sandbox](https://w
9090

9191
## Getting started: Express middleware
9292

93-
Apollo Server's built-in Express middleware lets you run your GraphQL server as part of an app built with [Express](https://expressjs.com/), the most popular web framework for Node.
93+
Apollo Server's Express middleware lets you run your GraphQL server as part of an app built with [Express](https://expressjs.com/), the most popular web framework for Node.
9494

95-
First, install Apollo Server, the JavaScript implementation of the core GraphQL algorithms, Express, and two common Express middleware packages:
95+
First, install Apollo Server, its Express middleware, the JavaScript implementation of the core GraphQL algorithms, Express, and the standard Express middleware package for CORS headers:
9696

9797
```
98-
npm install @apollo/server graphql express cors body-parser
98+
npm install @apollo/server @as-integrations/express5 graphql express cors
9999
```
100100

101101
If using Typescript you may also need to install additional type declaration packages as development dependencies to avoid common errors when importing the above packages (i.e. Could not find a declaration file for module '`cors`'):
102102

103103
```
104-
npm install --save-dev @types/cors @types/express @types/body-parser
104+
npm install --save-dev @types/cors @types/express
105105
```
106106

107107
Then, write the following to `server.mjs`. (By using the `.mjs` extension, Node lets you use the `await` keyword at the top level.)
108108

109109
```js
110110
import { ApolloServer } from '@apollo/server';
111-
import { expressMiddleware } from '@apollo/server/express4';
111+
import { expressMiddleware } from '@as-integrations/express5';
112112
import { ApolloServerPluginDrainHttpServer } from '@apollo/server/plugin/drainHttpServer'
113113
import express from 'express';
114114
import http from 'http';
115115
import cors from 'cors';
116-
import bodyParser from 'body-parser';
117116

118117
// The GraphQL schema
119118
const typeDefs = `#graphql
@@ -142,7 +141,7 @@ await server.start();
142141

143142
app.use(
144143
cors(),
145-
bodyParser.json(),
144+
express.json(),
146145
expressMiddleware(server),
147146
);
148147

0 commit comments

Comments
 (0)