0
0
GraphqlHow-ToBeginner · 4 min read

How to Use Apollo Upload Client for File Uploads in GraphQL

To use apollo-upload-client, install it and replace Apollo Client's HttpLink with createUploadLink. This allows you to send files in GraphQL mutations by passing File objects in variables.
📐

Syntax

The main part of using apollo-upload-client is to import createUploadLink and use it as the link in Apollo Client setup. This link handles multipart requests needed for file uploads.

Example parts:

  • createUploadLink({ uri: 'your_graphql_endpoint' }): creates a link that supports file uploads.
  • ApolloClient({ link, cache }): sets up the client with the upload link and cache.
  • mutation: GraphQL mutation that accepts Upload scalar type.
  • variables: pass File objects in variables to upload.
javascript
import { ApolloClient, InMemoryCache } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';

const uploadLink = createUploadLink({ uri: '/graphql' });

const client = new ApolloClient({
  link: uploadLink,
  cache: new InMemoryCache(),
});
💻

Example

This example shows how to set up Apollo Client with apollo-upload-client and send a file in a mutation called UPLOAD_FILE. The mutation expects a variable file of type Upload.

javascript
import React, { useState } from 'react';
import { ApolloClient, InMemoryCache, ApolloProvider, useMutation, gql } from '@apollo/client';
import { createUploadLink } from 'apollo-upload-client';

const uploadLink = createUploadLink({ uri: '/graphql' });
const client = new ApolloClient({ link: uploadLink, cache: new InMemoryCache() });

const UPLOAD_FILE = gql`
  mutation UploadFile($file: Upload!) {
    uploadFile(file: $file) {
      filename
      mimetype
      encoding
    }
  }
`;

function FileUpload() {
  const [file, setFile] = useState(null);
  const [uploadFile, { data, loading, error }] = useMutation(UPLOAD_FILE);

  const onChange = ({ target: { validity, files } }) => {
    if (validity.valid && files.length > 0) {
      setFile(files[0]);
    }
  };

  const onSubmit = (e) => {
    e.preventDefault();
    if (file) {
      uploadFile({ variables: { file } });
    }
  };

  return (
    <form onSubmit={onSubmit}>
      <input type="file" required onChange={onChange} />
      <button type="submit">Upload</button>
      {loading && <p>Uploading...</p>}
      {error && <p>Error: {error.message}</p>}
      {data && (
        <p>Uploaded: {data.uploadFile.filename} ({data.uploadFile.mimetype})</p>
      )}
    </form>
  );
}

export default function App() {
  return (
    <ApolloProvider client={client}>
      <FileUpload />
    </ApolloProvider>
  );
}
Output
User selects a file and clicks Upload. The UI shows 'Uploading...' then displays 'Uploaded: filename (mimetype)' on success.
⚠️

Common Pitfalls

  • Not using createUploadLink and instead using the default HttpLink will cause file uploads to fail.
  • Passing file data as a string or base64 instead of a File object will not work.
  • Server must support the Upload scalar and multipart requests; otherwise, uploads fail.
  • For React, ensure the file input's onChange sets the file correctly in state.
javascript
/* Wrong way: Using HttpLink (no upload support) */
import { ApolloClient, HttpLink, InMemoryCache } from '@apollo/client';

const client = new ApolloClient({
  link: new HttpLink({ uri: '/graphql' }), // No upload support
  cache: new InMemoryCache(),
});

/* Right way: Using createUploadLink */
import { createUploadLink } from 'apollo-upload-client';

const uploadLink = createUploadLink({ uri: '/graphql' });

const clientCorrect = new ApolloClient({
  link: uploadLink,
  cache: new InMemoryCache(),
});
📊

Quick Reference

  • Install with npm install apollo-upload-client.
  • Import createUploadLink and use it as Apollo Client's link.
  • Use GraphQL Upload scalar type in your schema.
  • Pass File objects in mutation variables.
  • Ensure server supports multipart requests.

Key Takeaways

Use createUploadLink from apollo-upload-client to enable file uploads in Apollo Client.
Pass actual File objects in mutation variables for uploads, not strings or base64.
Your GraphQL server must support the Upload scalar and multipart requests.
Replace HttpLink with createUploadLink to avoid upload failures.
Handle file input changes properly in your UI to send files correctly.