File uploads with GraphQL and apollo

File uploads using GraphQL don’t seem to be a common thing. On some places people suggest to simply create an endpoind besides your GraphQL-endpoint to POST files to, which returns an URL of the uploaded file. Then you can use this URL in your GraphQL mutation and store it on the server.

However, I like the idea of having a single endpoint for all of my API. This is why I wanted my GraphQL server to handle uploads. Turnsout, you can send arbitrary data with any GraphQL-request. So instead of sending a regular POST-request, you can send a multipart-request. GraphQL needs a multipart field called query, but other than that you can easily transmit your files as part of this multipart-request.

Server side

Using graphQL.js on the server side the changes are pretty simple. We need to read the file(s) from the multipart-request, for example using multer middleware. The file(s) will then be available on the request object, which can be passed into context and processed in the resolve function:

graphQLServer.use(multer({
storage: multer.memoryStorage(),
}).any());

The resolve function can for example upload the file to the CDN and return the URL.

Client side

In one of our projects we are using Apollo on the client-side to handle GraphQL requests. So we need to write a custom NetworkInterface that is capable of multipart requests.

This network interface iterates over the request’s variables and looks for a File object. All files are added to the request and the variables are then replaced with a random string that refers to the field name of the file in the multipart-request.

Show your support

Clapping shows how much you appreciated Daniel Büchele’s story.