-
Notifications
You must be signed in to change notification settings - Fork 2k
docs: move migrate from express graphql guide to graphqlJS docs #4433
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
sarahxsanders
wants to merge
4
commits into
graphql:16.x.x
Choose a base branch
from
sarahxsanders:migrate-from-express
base: 16.x.x
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+214
−0
Open
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,213 @@ | ||
--- | ||
title: Migrate from Express GraphQL to GraphQL over HTTP | ||
sidebarTitle: Migrate from Express GraphQL | ||
--- | ||
|
||
# Migrate from Express GraphQL to GraphQL over HTTP | ||
|
||
When GraphQL was open-sourced in 2015, `express-graphql` quickly became the standard way to run a GraphQL server in Node.js. | ||
Built as middleware for Express, it offered a simple and reliable development experience. However, it hasn’t received a | ||
feature update since 2018 and is no longer actively maintained. For modern applications, it lacks support for new transport | ||
features, fine-grained request handling, and deployment flexibility. | ||
|
||
[`graphql-http`](https://github.com/graphql/graphql-http) is a lightweight implementation of | ||
the [GraphQL over HTTP specification](https://graphql.github.io/graphql-over-http/draft/). It's framework-agnostic, built to be | ||
composable, and easy to integrate into different server environments. Unlike `express-graphql`, it can run in a wide range of | ||
environments, not just Express. | ||
|
||
This guide is for developers currently using `express-graphql` who want to | ||
modernize their stack, adopt the HTTP spec, or decouple their GraphQL server | ||
from Express. | ||
|
||
## Benefits of migrating | ||
|
||
### `express-graphql` is no longer supported | ||
|
||
The library has not received updates for some time. As a deprecated package, it is not evolving with the GraphQL ecosystem. This makes it less flexible for long-term projects. | ||
|
||
### `graphql-http` is spec-compliant by default | ||
|
||
The GraphQL over HTTP specification defines how GraphQL should be transported over HTTP, including request methods, status codes, content types, and more. `graphql-http` follows this spec precisely, helping your server behave predictably and remain compatible with future tooling. | ||
|
||
### It's framework-agnostic by design | ||
|
||
Instead of relying on Express, `graphql-http` is built on the standard Web `Request` and `Response` interfaces. It works with Express, Fastify, Node's native HTTP server, and can also be used in serverless and edge environments. | ||
|
||
### It fits into modern JavaScript stacks | ||
|
||
`graphql-http` supports ESM and works well with modern build tools and lightweight deployment platforms. Its composable design makes it easy to customize, wrap, and integrate into different application architectures. | ||
|
||
### Designed for future compatibility | ||
|
||
As GraphQL evolves, tools and platforms increasingly expect spec-compliant behavior. Migration to `graphql-http` helps ensure your | ||
server will support future capabilities without relying on workarounds. | ||
|
||
### Understand current limitations | ||
|
||
Although `graphql-http` is a strong foundation for modern GraphQL servers, it's important to note what it doesn't include: | ||
|
||
- It doesn't support subscriptions or experimental features like incremental delivery (`@defer` / `@stream`) out of the box. | ||
- These limitations are by design. `graphql-http` strictly adheres to the current | ||
[GraphQL over HTTP specification](https://graphql.github.io/graphql-over-http/draft/), which does | ||
not yet define behavior for those features. | ||
- If your application needs support for subscriptions or live queries, consider using complementary libraries like | ||
[`graphql-ws`](https://github.com/enisdenjo/graphql-ws) or [`graphql-sse`](https://github.com/enisdenjo/graphql-sse). | ||
|
||
These are not limitations unique to `graphql-http`. `express-graphql` does not support these features either, but it's important | ||
to set the right expectations about extensibility. | ||
yaacovCR marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## Migration guide | ||
|
||
The following steps walk through how to migrate an existing `express-graphql` server to use `graphql-http`. The steps assume you already have a working Express app using `express-graphql`. | ||
|
||
### Prerequisites | ||
|
||
Before you begin, make sure you have: | ||
|
||
- Node.js 16 or later | ||
- A GraphQL schema | ||
- An existing Express app configured with `express-graphql` | ||
|
||
### Step 1: Install graphql-http and the Express adapter | ||
|
||
Install the core `graphql-http` package along with its Express adapter: | ||
|
||
```bash | ||
npm install graphql graphql-http @graphql-http/express | ||
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
The `graphql` package is a peer dependency of `graphql-http`, and must be installed if it isn't already. | ||
|
||
### Step 2: Remove express-graphql middleware | ||
|
||
In your Express server file, remove the `express-graphql` middleware: | ||
|
||
```js | ||
// Before (using express-graphql) | ||
import { graphqlHTTP } from 'express-graphql'; | ||
|
||
app.use('/graphql', graphqlHTTP({ | ||
schema, | ||
graphiql: true, | ||
})); | ||
``` | ||
|
||
### Step 3: Add graphql-http middleware with createHandler | ||
|
||
Replace it with the `graphql-http` handler using the Express adapter: | ||
|
||
```js | ||
import express from 'express'; | ||
import { createHandler } from 'graphql-http/lib/use/express'; | ||
import { schema } from './schema.js'; | ||
|
||
const app = express(); | ||
|
||
app.all('/graphql', createHandler({ schema })); | ||
|
||
app.listen(4000); | ||
``` | ||
|
||
- Use `app.all()` to allow both `GET` and `POST` requests. | ||
- The handler accepts an options object similar to `express-graphql`. | ||
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Step 4: Handle context, error formatting, and extensions | ||
|
||
You can provide options like `context`, `rootValue`, and `formatError`: | ||
|
||
```js | ||
app.all('/graphql', createHandler({ | ||
schema, | ||
context: async (req, res) => { | ||
return { user: await authenticate(req) }; | ||
}, | ||
formatError: (error) => ({ | ||
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
|
||
message: error.message, | ||
path: error.path, | ||
}), | ||
})); | ||
``` | ||
|
||
- `context` can be a static object or an async function. | ||
- You can also pass `rootValue`, or extend responses with custom logic. | ||
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
### Step 5: Add a GraphQL IDE (optional) | ||
|
||
Unlike `express-graphql`, `graphql-http` does not include a built-in GraphQL IDE. If you want to add one: | ||
|
||
- Use a tool like [Ruru](https://www.npmjs.com/package/ruru) to serve an interactive GraphQL UI locally: | ||
|
||
```bash | ||
npx ruru -SP -p 4001 -e http://localhost:4000/graphql | ||
``` | ||
|
||
- Or serve a static HTML page that embeds [GraphiQL](https://github.com/graphql/graphiql) from a CDN. | ||
|
||
In either case, make sure to restrict access in production environments. | ||
|
||
### Step 6: Test your setup | ||
|
||
After migrating, verify that your server responds correctly: | ||
|
||
- Send queries and mutations using your preferred client. | ||
- Check for proper HTTP status codes and response shapes. | ||
- Check the GraphQL `context` and related variables are populated correctly and | ||
that your dataloaders and authorization logic are functioning as expected. | ||
|
||
## Best practices | ||
|
||
When migrating from `express-graphql` to `graphql-http`, there are a few key differences and potential pitfalls to keep in mind. These tips can help you avoid common issues and ensure a smoother transition. | ||
|
||
### Be aware of different error behavior | ||
|
||
`graphql-http` follows the GraphQL over HTTP spec closely, which means error formatting and status codes may differ from what you're used to with `express-graphql`. For example: | ||
|
||
- Invalid queries may return a `400 Bad Request` instead of a `200 OK`. | ||
- Errors in parsing or validation are surfaced earlier and more strictly. | ||
- You can customize error output using the `formatError` option, but it must conform to the spec. | ||
|
||
This can affect client expectations if they were relying on `express-graphql`'s more lenient defaults. | ||
|
||
### Consider IDE support in development | ||
|
||
`express-graphql` includes GraphiQL by default in development mode. `graphql-http` does not. | ||
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
To restore this functionality, consider: | ||
|
||
- Use a development tool like Ruru to serve an in-browser IDE. | ||
- Host a static IDE page at a separate endpoint. | ||
- Ensure the IDE is only available in non-production environments. | ||
|
||
### Watch for framework-specific middleware behavior | ||
|
||
Since `graphql-http` is framework-agnostic, it does not handle things like body parsing, CORS, or compression. You'll need to ensure those are handled appropriately by your Express setup: | ||
|
||
```js | ||
import cors from 'cors'; | ||
import express from 'express'; | ||
|
||
app.use(cors()); | ||
app.use(express.json()); | ||
``` | ||
|
||
This gives you more control but requires a bit more setup. | ||
|
||
### Understand streaming and file upload limitations | ||
|
||
`graphql-http` aims to support the GraphQL over HTTP spec, including eventually supporting response streaming. However, | ||
support for features like `@defer` and `@stream` is still evolving. These capabilities are experimental in `graphql-js` | ||
and not yet supported by `graphql-http`. | ||
|
||
- Most GraphQL clients don’t yet support multipart responses. | ||
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- Server-side support for streaming may be incomplete or inconsistent. | ||
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
|
||
- If your app relies on incremental delivery, consider using a transport library like | ||
[`graphql-sse`](https://github.com/enisdenjo/graphql-sse) instead. | ||
sarahxsanders marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
## What's next | ||
|
||
`graphql-http` is the reference implementation of the GraphQL-over-HTTP specification, | ||
but there are many other servers you can use to serve your GraphQL API, each with | ||
different features and trade-offs. For a list of other spec-compliant server | ||
implementations see the | ||
[`graphql-http` server list](https://github.com/graphql/graphql-http?tab=readme-ov-file#servers), and don't forget to check out the | ||
[Tools and Libraries page on graphql.org](https://graphql.org/community/tools-and-libraries/?tags=server_javascript). |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.