Learn how to configure cross-origin resource sharing on your express-based GraphQL servers.

What is CORS?
Cross-origin resource sharing, short CORS, is a protection mechanism for web pages, allowing the browser to safely load resources from domains that are different from the one it originally loaded the page from.
As an example, say you’re accessing https://www.prisma.io/ in your browser. The browser downloads the HTML and JavaScript for the site in order to render it for you. Now, some data to be displayed on the site actually is stored somewhere else, on a different server — a different origin.
Two URLs are said to have the same origin if the following three properties are identical for them: domain, protocol and port:
http://localhost:3000,ws://localhost:3000andhttp://localhost:4000all have different origins.http://localhost:3000andhttp://localhost:3000/graphqlhave the same origin.
In order for your browser to load the data from that other server, the other server needs to set Access-Control headers properly in order to determine its policy regarding cross-origin resource access. For example, by simply specifying Access-Control-Allow-Origin: *, the server indicates to the browser that it will allow CORS anywhere.
How about an example
Now, imagine the following scenario. You’re starting out with a new project and for now are only developing locally on your machine. You used create-react-app to bootstrap your frontend and for the backend you setup a simple express.js server (either based on express-graphql, graphql-yoga or apollo-server).
In fact, we prepared an example that mimics this exact scenario:
Server
Notice that line 23 is commented out — CORS is not enabled!
Frontend
Standard setup for using Apollo Client 2.0
The
Appcomponent sends a simplehelloquery using Apollo Client
In your local development setup, where the React app is loaded from http://localhost:3000 and the GraphQL server is serving at http://localhost:4000/graphql, you’ll now get an access control error if you’re trying to run the app:

What exactly is the issue when CORS is not enabled? Well, CORS is in fact a specification for a communication flow between client (a browser) and server. In some situations, this flow requires the server to process HTTP OPTIONS requests as can be seen from this flowchart:
The CORS flow might required additional HTTP requests with the OPTIONS method (source)
The problem is that neither express-graphql nor apollo-server accept HTTP requests other than GET and POST — which is why the request fails in our scenario. This is also indicated by the error message we saw in the console: OPTIONS [http://localhost:4000](http://localhost:4000) 405 (Method not allowed).
Here is the GitHub discussion on
express-graphqlwhere this issue first came up.
Luckily, the solution is very simple. As express-graphql and apollo-server are both based on express.js, you can simply use its standard cors middleware to fix the issue.
Uncommenting line 23 in server.js will enable the cors middleware for your express server: app.use(cors()). Having the middleware enabled ensures your express server sets the proper HTTP header, enabling your React app to load data from it:
Using the cors middleware, the server sets the correct HTTP header enabling cross-origin resource sharing
Summary
CORS is an important protection mechanism preventing websites from downloading malicious resources, but from a developer standpoint it can be a pain to properly configure it.
When using express-graphql and apollo-server, all you need to do is include the standard cors middleware used in express.js apps and you’re good to go:
Don’t miss the next post!
Sign up for the Prisma Newsletter