@conjecto/apollo-upload-client
v13.0.0
Published
A terminating Apollo Link for Apollo Client that allows FileList, File, Blob or ReactNativeFile instances within query or mutation variables and sends GraphQL multipart requests.
Downloads
4
Maintainers
Readme
apollo-upload-client
A terminating Apollo Link for Apollo Client that allows FileList
, File
, Blob
or ReactNativeFile
instances within query or mutation variables and sends GraphQL multipart requests.
Setup
Install with npm:
npm install apollo-upload-client
Apollo Boost doesn’t allow link customization; if you are using it migrate to a manual Apollo Client setup.
Apollo Client can only have 1 “terminating” Apollo Link that sends the GraphQL requests; if one such as apollo-link-http
is already setup, remove it.
Initialize the client with a terminating link using createUploadLink
.
Also ensure the GraphQL server implements the GraphQL multipart request spec and that uploads are handled correctly in resolvers.
Usage
Use FileList
, File
, Blob
or ReactNativeFile
instances anywhere within query or mutation variables to send a GraphQL multipart request.
See also the example API and client.
FileList
const { useMutation } = require('@apollo/react-hooks');
const gql = require('graphql-tag');
const MUTATION = gql`
mutation($files: [Upload!]!) {
uploadFiles(files: $files) {
success
}
}
`;
function UploadFiles() {
const [mutate] = useMutation(MUTATION);
function onChange({ target: { validity, files } }) {
if (validity.valid) mutate({ variables: { files } });
}
return <input type="file" multiple required onChange={onChange} />;
}
File
const { useMutation } = require('@apollo/react-hooks');
const gql = require('graphql-tag');
const MUTATION = gql`
mutation($file: Upload!) {
uploadFile(file: $file) {
success
}
}
`;
function UploadFile() {
const [mutate] = useMutation(MUTATION);
function onChange({
target: {
validity,
files: [file],
},
}) {
if (validity.valid) mutate({ variables: { file } });
}
return <input type="file" required onChange={onChange} />;
}
Blob
const { useMutation } = require('@apollo/react-hooks');
const gql = require('graphql-tag');
const MUTATION = gql`
mutation($file: Upload!) {
uploadFile(file: $file) {
success
}
}
`;
function UploadFile() {
const [mutate] = useMutation(MUTATION);
function onChange({ target: { validity, value } }) {
if (validity.valid) {
const file = new Blob([value], { type: 'text/plain' });
// Optional, defaults to `blob`.
file.name = 'text.txt';
mutate({ variables: { file } });
}
}
return <input type="text" required onChange={onChange} />;
}
Support
- Node.js v10+
- Browsers
> 0.5%, not OperaMini all, not dead
- React Native
Consider polyfilling:
API
Table of contents
- class ReactNativeFile
- function createUploadLink
- function formDataAppendFile
- function isExtractableFile
- type ExtractableFileMatcher
- type FetchOptions
- type FormDataFileAppender
- type ReactNativeFileSubstitute
class ReactNativeFile
Used to mark React Native File
substitutes as it’s too risky to assume all objects with uri
, type
and name
properties are extractable files.
| Parameter | Type | Description |
| :-- | :-- | :-- |
| file
| ReactNativeFileSubstitute | A React Native File
substitute. |
See
Examples
A React Native file that can be used in query or mutation variables.
const { ReactNativeFile } = require('apollo-upload-client'); const file = new ReactNativeFile({ uri: uriFromCameraRoll, name: 'a.jpg', type: 'image/jpeg', });
function createUploadLink
Creates a terminating Apollo Link capable of file uploads.
The link matches and extracts files in the GraphQL operation. If there are files it uses a FormData
instance as the fetch
options.body
to make a GraphQL multipart request, otherwise it sends a regular POST request.
Some of the options are similar to the createHttpLink
options.
| Parameter | Type | Description |
| :-- | :-- | :-- |
| options
| object | Options. |
| options.uri
| string? = /graphql | GraphQL endpoint URI. |
| options.isExtractableFile
| ExtractableFileMatcher? = isExtractableFile | Customizes how files are matched in the GraphQL operation for extraction. |
| options.FormData
| class? | FormData
implementation to use, defaulting to the FormData
global. |
| options.formDataAppendFile
| FormDataFileAppender? = formDataAppendFile | Customizes how extracted files are appended to the FormData
instance. |
| options.fetch
| Function? | fetch
implementation to use, defaulting to the fetch
global. |
| options.fetchOptions
| FetchOptions? | fetch
options; overridden by upload requirements. |
| options.credentials
| string? | Overrides options.fetchOptions.credentials
. |
| options.headers
| object? | Merges with and overrides options.fetchOptions.headers
. |
| options.includeExtensions
| boolean? = false
| Toggles sending extensions
fields to the GraphQL server. |
Returns: ApolloLink — A terminating Apollo Link capable of file uploads.
See
Examples
A basic Apollo Client setup.
const { ApolloClient } = require('apollo-client'); const { InMemoryCache } = require('apollo-cache-inmemory'); const { createUploadLink } = require('apollo-upload-client'); const client = new ApolloClient({ cache: new InMemoryCache(), link: createUploadLink(), });
function formDataAppendFile
The default implementation for createUploadLink
options.formDataAppendFile
that uses the standard FormData.append
method.
Type: FormDataFileAppender
| Parameter | Type | Description |
| :-- | :-- | :-- |
| formData
| FormData | FormData
instance to append the specified file to. |
| fieldName
| string | Field name for the file. |
| file
| * | File to append. |
function isExtractableFile
The default implementation for createUploadLink
options.isExtractableFile
.
Type: ExtractableFileMatcher
| Parameter | Type | Description |
| :-------- | :--- | :-------------- |
| value
| * | Value to check. |
Returns: boolean — Is the value an extractable file.
See
type ExtractableFileMatcher
A function that checks if a value is an extractable file.
Type: Function
| Parameter | Type | Description |
| :-------- | :--- | :-------------- |
| value
| * | Value to check. |
Returns: boolean — Is the value an extractable file.
See
isExtractableFile
has this type.
Examples
How to check for the default exactable files, as well as a custom type of file.
const { isExtractableFile } = require('apollo-upload-client'); const isExtractableFileEnhanced = (value) => isExtractableFile(value) || (typeof CustomFile !== 'undefined' && value instanceof CustomFile);
type FetchOptions
GraphQL request fetch
options.
Type: object
| Property | Type | Description |
| :------------ | :------ | :------------------------------- |
| headers
| object | HTTP request headers. |
| credentials
| string? | Authentication credentials mode. |
See
type FormDataFileAppender
Appends a file extracted from the GraphQL operation to the FormData
instance used as the fetch
options.body
for the GraphQL multipart request.
| Parameter | Type | Description |
| :-- | :-- | :-- |
| formData
| FormData | FormData
instance to append the specified file to. |
| fieldName
| string | Field name for the file. |
| file
| * | File to append. The file type depends on what the ExtractableFileMatcher
extracts. |
See
formDataAppendFile
has this type.createUploadLink
accepts this type inoptions.formDataAppendFile
.
type ReactNativeFileSubstitute
A React Native File
substitute.
Be aware that inspecting network requests with Chrome dev tools interferes with the React Native FormData
implementation, causing network errors.
Type: object
| Property | Type | Description |
| :-- | :-- | :-- |
| uri
| string | Filesystem path. |
| name
| string? | File name. |
| type
| string? | File content type. Some environments (particularly Android) require a valid MIME type; Expo ImageResult.type
is unreliable as it can be just image
. |
See
Examples
A camera roll file.
{ uri: uriFromCameraRoll, name: 'a.jpg', type: 'image/jpeg' }