apollo-fetch-upload
TypeScript icon, indicating that this package has built-in type declarations

1.2.0 • Public • Published

apollo-fetch-upload

npm version

Enables the use of File, FileList and ReactNativeFile instances anywhere within mutation or query input variables. With the apollo-upload-server middleware setup on the GraphQL server, files upload to a configurable temp directory. Upload input type metadata replaces the original files in the arguments received by the resolver.

Checkout the example API and client.

Use apollo-upload-client for earlier versions of apollo-client that do not support an apollo-fetch network interface.

Setup

Install with npm:

npm install apollo-fetch-upload

To setup an ApolloClient network interface:

import ApolloClient from 'apollo-client'
import { createApolloFetchUpload } from 'apollo-fetch-upload'
import { print } from 'graphql/language/printer'
 
const apolloFetchUpload = createApolloFetchUpload({
  uri: 'https://api.githunt.com/graphql'
})
 
const ApolloClient = new ApolloClient({
  networkInterface: {
    query: request => apolloFetchUpload({
      ...request,
      query: print(request.query)
    })
  }
})

Alternatively use query batching:

import ApolloClient from 'apollo-client'
import BatchHttpLink from 'apollo-link-batch-http'
import { createApolloFetchUpload } from 'apollo-fetch-upload'
 
const ApolloClient = new ApolloClient({
  networkInterface: new BatchHttpLink({
    fetch: createApolloFetchUpload({
      uri: 'https://api.githunt.com/graphql'
    })
  })
})

createApolloFetchUpload and constructUploadOptions have the same API as createApolloFetch and constructDefaultOptions in apollo-fetch.

See also the setup instructions for the apollo-upload-server middleware.

Usage

Use File, FileList or ReactNativeFile instances anywhere within mutation or query input variables. For server instructions see apollo-upload-server. Checkout the example API and client.

File example

import { graphql, gql } from 'react-apollo'
 
const UploadFile = ({ mutate }) => {
  const handleChange = ({ target }) =>
    target.validity.valid &&
    mutate({
      variables: {
        file: target.files[0]
      }
    })
 
  return <input type="file" required onChange={handleChange} />
}
 
export default graphql(gql`
  mutation($file: Upload!) {
    uploadFile(file: $file) {
      id
    }
  }
`)(UploadFile)

FileList example

import { graphql, gql } from 'react-apollo'
 
const UploadFiles = ({ mutate }) => {
  const handleChange = ({ target }) =>
    target.validity.valid &&
    mutate({
      variables: {
        files: target.files
      }
    })
 
  return <input type="file" multiple required onChange={handleChange} />
}
 
export default graphql(gql`
  mutation($files: [Upload!]!) {
    uploadFiles(files: $files) {
      id
    }
  }
`)(UploadFiles)

React Native

Substitute File with ReactNativeFile from extract-files:

import { ReactNativeFile } from 'apollo-fetch-upload'
 
const variables = {
  file: new ReactNativeFile({
    uri: /* Camera roll URI */,
    type: 'image/jpeg',
    name: 'photo.jpg'
  }),
  files: ReactNativeFile.list([{
    uri: /* Camera roll URI */,
    type: 'image/jpeg',
    name: 'photo-1.jpg'
  }, {
    uri: /* Camera roll URI */,
    type: 'image/jpeg',
    name: 'photo-2.jpg'
  }])
}

How it works

An ‘operations object’ is a GraphQL request (or array of requests if batching). A ‘file’ is a File or ReactNativeFile instance.

When an operations object is to be sent to the GraphQL server, any files within are extracted using extract-files, remembering their object paths within request variables.

If no files are extracted a normal fetch with default options happens; the operations object is converted to JSON and sent in the fetch body.

Files must upload as individual multipart form fields. A new FormData form is created and each extracted file is appended as a field named after the file's original operations object path; for example variables.files.0 or 0.variables.files.0 if batching. The operations object (now without files) is converted to JSON and appended as a field named operations. The form is sent in the fetch body.

Multipart GraphQL server requests are handled by apollo-upload-server middleware. The files upload to a temp directory, the operations field is JSON decoded and object-path is used to insert metadata about each of the uploads (including the temp path) in place of the original files in the resolver arguments.

Readme

Keywords

none

Package Sidebar

Install

npm i apollo-fetch-upload

Weekly Downloads

6

Version

1.2.0

License

MIT

Last publish

Collaborators

  • apollo-bot