File uploads with GraphQL and apollo

Daniel Büchele
Aug 21, 2016 · 2 min read

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.

    Daniel Büchele

    Written by

    Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
    Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
    Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade