Allowing users upload files from your mobile app
Enabling file uploads on the server
Voyager Server provides support for uploading binary data along with the GraphQL queries.
The implementation relies on upstream Apollo Server
capabilities.
The upload functionality uses the GraphQL multipart form requests specification. File upload needs to be implemented on both server and client:
-
On the client HTML FileList objects are mapped into a mutation and sent to the server in a multipart request.
-
On the server: The multipart request is handled. The server processes it and provides an upload argument to a resolver. In the resolver function, the upload promise resolves an object.
File upload is based on graphql-multipart-request-spec. |
To enable file uploads, create a schema and use the Upload
scalar.
For example:
const { ApolloServer, gql } = require('apollo-server');
const typeDefs = gql`
type File {
filename: String!
mimetype: String!
encoding: String!
}
type Query {
uploads: [File]
}
type Mutation {
singleUpload(file: Upload!): File!
}
`;
The following schema enables file uploads. The Upload
scalar will be injected as one of the arguments in the resolvers.
The Upload
scalar contains all file metadata and a Readable Stream that can be used to save the file to a specific location.
async singleUpload(parent, { file }) {
const { stream, filename, mimetype, encoding } = await file;
// Save file and return required metadata
}
See Official Apollo blog post for more information.
Implementing file upload on the client
Voyager Client provides support for uploading binary data along with the GraphQL queries.
The binary upload implementation uses the apollo-upload-client
package built by the Apollo community.
Introduction
The upload functionality uses the GraphQL multipart form requests specification. The File upload needs to be implemented on both server and client:
-
On the client HTML FileList objects are mapped into a mutation and sent to the server in a multipart request.
-
On the server: The multipart request is handled. The server processes it and provides an upload argument to a resolver. In the resolver function, the upload promise resolves an object.
File upload is based on graphql-multipart-request-spec. |
Uploading Files from GraphQL
File upload capability adds a new GraphQL scalar Upload
that can be used for mutations that operate on binary data.
The Upload
scalar maps html FileList
HTML5 object in GraphQL schemas.
The first step required to work with binary uploads is to write mutation that will contain Upload
scalar.
The following example demonstrates how to upload a profile picture:
import gql from 'graphql-tag'
import { Mutation } from 'react-apollo'
export const UPLOAD_PROFILE = gql`
mutation changeProfilePicture($file: Upload!) {
changeProfilePicture(file: $file) {
filename
mimetype
encoding
}
}
`;
Executing mutations
The Upload
scalar will be mapped to object returned from HTML file input.
The following example shows file upload in a React application.
const uploadOneFile = () => {
return (
<Mutation mutation={UPLOAD_PROFILE}>
{uploadFile => (
<input
type="file"
required
onChange={({ target: { validity, files: [file] } }) =>
validity.valid && uploadFile({ variables: { file } });
}
/>
)}
</Mutation>
);
};