Enhances Apollo for intuitive file uploads via GraphQL mutations or queries. Use with Apollo upload server.
- > 2% market share browsers supported.
- MIT license.
Install with Yarn:
yarn add apollo-upload-client
Setup Apollo client with a special network interface:
import ApolloClient from 'apollo-client'
import {createNetworkInterface} from 'apollo-upload-client'
const client = new ApolloClient({
networkInterface: createNetworkInterface({
uri: '/graphql'
})
})
Alternatively enable query batching:
import ApolloClient from 'apollo-client'
import {createBatchNetworkInterface} from 'apollo-upload-client'
const client = new ApolloClient({
networkInterface: createBatchNetworkInterface({
uri: '/graphql',
batchInterval: 10
})
})
Also setup Apollo upload server.
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 available under the variable name in the resolver. See the server usage.
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} />
}
}
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} />
}
}