In combination with Apollo upload server, enhances Apollo for intuitive file uploads via GraphQL mutations or queries.
Setup
Install with Yarn:
yarn add apollo-upload-client
Create the Apollo client with the special network interface:
import ApolloClient from 'apollo-client'
import createNetworkInterface from 'apollo-upload-client'
const client = new ApolloClient({
networkInterface: createNetworkInterface({
uri: '/graphql'
})
})
Also setup Apollo upload server.
Usage
Once setup, you will be able to use File
objects, FileList
objects, or File
arrays within query or mutation input variables.
The files upload to a temp directory; the paths and metadata will be avalable under the variable name in the resolver. See the server usage.
Single file
See server usage for this example.
import React, {Component, PropTypes} from 'react'
import {graphql} from 'react-apollo'
import gql from 'graphql-tag'
@graphql(gql`
mutation updateUserAvatar ($userId: String!, $avatar: File!) {
updateUserAvatar (userId: $userId, avatar: $avatar) {
id
}
}
`)
export default class extends Component {
static propTypes = {
userId: PropTypes.string.isRequired,
mutate: PropTypes.func.isRequired
}
onChange = ({target}) => {
if (target.validity.valid) {
this.props
.mutate({
variables: {
userId: this.props.userId,
avatar: target.files[0]
}
})
.then(({data}) => console.log('Mutation response:', data))
}
}
render () {
return <input type='file' accept={'image/jpeg,image/png'} required onChange={this.onChange} />
}
}
Multiple files
See server usage for this example.
import React, {Component, PropTypes} from 'react'
import {graphql} from 'react-apollo'
import gql from 'graphql-tag'
@graphql(gql`
mutation updateGallery ($galleryId: String!, $images: [File!]!) {
updateGallery (galleryId: $galleryId, images: $images) {
id
}
}
`)
export default class extends Component {
static propTypes = {
galleryId: PropTypes.string.isRequired,
mutate: PropTypes.func.isRequired
}
onChange = ({target}) => {
if (target.validity.valid) {
this.props
.mutate({
variables: {
galleryId: this.props.galleryId,
images: target.files
}
})
.then(({data}) => console.log('Mutation response:', data))
}
}
render () {
return <input type='file' accept={'image/jpeg,image/png'} multiple required onChange={this.onChange} />
}
}
Caveats
- Batching is not compatible as only the standard Apollo network interface has been extended yet.
Inspiration