Graphql Multipart Request Spec

A spec for GraphQL multipart form requests (file uploads).
Alternatives To Graphql Multipart Request Spec
Project NameStarsDownloadsRepos Using ThisPackages Using ThisMost Recent CommitTotal ReleasesLatest ReleaseOpen IssuesLicenseLanguage
Resumable.js4,32547332 years ago2November 06, 2017164mitJavaScript
A JavaScript library for providing multiple simultaneous, stable, fault-tolerant and resumable/restartable uploads via the HTML5 File API.
Flow.js2,8163192 years ago8June 05, 2020120mitJavaScript
A JavaScript library providing multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API.
Android Upload Service2,73019337 days ago19November 04, 20214apache-2.0Kotlin
Easily upload files (Multipart/Binary/FTP out of the box) in the background with progress notification. Support for persistent upload requests, customizations and custom plugins.
Evaporatejs1,76226122 months ago51October 08, 201791JavaScript
Javascript library for browser to S3 multipart resumable uploads
Express Fileupload1,4083,0564512 months ago45May 24, 202238mitJavaScript
Simple express file upload middleware that wraps around busboy
Graphql Upload1,3162,2861167 months ago18June 28, 20223mitJavaScript
Middleware and an Upload scalar to add support for GraphQL multipart requests (file uploads via queries and mutations) to various Node.js GraphQL servers.
Graphql Multipart Request Spec797
a year ago2
A spec for GraphQL multipart form requests (file uploads).
Uploader65723276 months ago24January 05, 202240otherJavaScript
A JavaScript library providing multiple simultaneous, stable, fault-tolerant and resumable/restartable file uploads via the HTML5 File API.
Mod0burpuploadscanner328
2 years ago24otherPerl
HTTP file upload scanner for Burp Proxy
S3 Upload Stream320303863 years ago19December 04, 201422mitJavaScript
A Node.js module for streaming data to Amazon S3 via the multipart upload API
Alternatives To Graphql Multipart Request Spec
Select To Compare


Alternative Project Comparisons
Readme

GraphQL multipart request specification

GitHub release

An interoperable multipart form field structure for GraphQL requests, used by various file upload client/server implementations.

Its possible to implement:

  • Nesting files anywhere within operations (usually in variables).
  • Operation batching.
  • File deduplication.
  • File upload streams in resolvers.
  • Aborting file uploads in resolvers.

Sync vs async GraphQL multipart request middleware

Multipart form field structure

An operations object is an Apollo GraphQL POST request (or array of requests if batching). An operations path is an object-path string to locate a file within an operations object.

So operations can be resolved while the files are still uploading, the fields are ordered:

  1. operations: A JSON encoded operations object with files replaced with null.
  2. map: A JSON encoded map of where files occurred in the operations. For each file, the key is the file multipart form field name and the value is an array of operations paths.
  3. File fields: Each file extracted from the operations object with a unique, arbitrary field name.

Examples

Single file

Operations

{
  query: `
    mutation($file: Upload!) {
      singleUpload(file: $file) {
        id
      }
    }
  `,
  variables: {
    file: File // a.txt
  }
}

cURL request

curl localhost:3001/graphql \
  -F operations='{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }' \
  -F map='{ "0": ["variables.file"] }' \
  -F [email protected]

Request payload

--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="operations"

{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }
--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="map"

{ "0": ["variables.file"] }
--------------------------cec8e8123c05ba25
Content-Disposition: form-data; name="0"; filename="a.txt"
Content-Type: text/plain

Alpha file content.

--------------------------cec8e8123c05ba25--

File list

Operations

{
  query: `
    mutation($files: [Upload!]!) {
      multipleUpload(files: $files) {
        id
      }
    }
  `,
  variables: {
    files: [
      File, // b.txt
      File // c.txt
    ]
  }
}

cURL request

curl localhost:3001/graphql \
  -F operations='{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }' \
  -F map='{ "0": ["variables.files.0"], "1": ["variables.files.1"] }' \
  -F [email protected] \
  -F [email protected]

Request payload

--------------------------ec62457de6331cad
Content-Disposition: form-data; name="operations"

{ "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }
--------------------------ec62457de6331cad
Content-Disposition: form-data; name="map"

{ "0": ["variables.files.0"], "1": ["variables.files.1"] }
--------------------------ec62457de6331cad
Content-Disposition: form-data; name="0"; filename="b.txt"
Content-Type: text/plain

Bravo file content.

--------------------------ec62457de6331cad
Content-Disposition: form-data; name="1"; filename="c.txt"
Content-Type: text/plain

Charlie file content.

--------------------------ec62457de6331cad--

Batching

Operations

;[
  {
    query: `
      mutation($file: Upload!) {
        singleUpload(file: $file) {
          id
        }
      }
    `,
    variables: {
      file: File // a.txt
    }
  },
  {
    query: `
      mutation($files: [Upload!]!) {
        multipleUpload(files: $files) {
          id
        }
      }
    `,
    variables: {
      files: [
        File, // b.txt
        File // c.txt
      ]
    }
  }
]

cURL request

curl localhost:3001/graphql \
  -F operations='[{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }, { "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }]' \
  -F map='{ "0": ["0.variables.file"], "1": ["1.variables.files.0"], "2": ["1.variables.files.1"] }' \
  -F [email protected] \
  -F [email protected] \
  -F [email protected]

Request payload

--------------------------627436eaefdbc285
Content-Disposition: form-data; name="operations"

[{ "query": "mutation ($file: Upload!) { singleUpload(file: $file) { id } }", "variables": { "file": null } }, { "query": "mutation($files: [Upload!]!) { multipleUpload(files: $files) { id } }", "variables": { "files": [null, null] } }]
--------------------------627436eaefdbc285
Content-Disposition: form-data; name="map"

{ "0": ["0.variables.file"], "1": ["1.variables.files.0"], "2": ["1.variables.files.1"] }
--------------------------627436eaefdbc285
Content-Disposition: form-data; name="0"; filename="a.txt"
Content-Type: text/plain

Alpha file content.

--------------------------627436eaefdbc285
Content-Disposition: form-data; name="1"; filename="b.txt"
Content-Type: text/plain

Bravo file content.

--------------------------627436eaefdbc285
Content-Disposition: form-data; name="2"; filename="c.txt"
Content-Type: text/plain

Charlie file content.

--------------------------627436eaefdbc285--

Implementations

Pull requests adding either experimental or mature implementations to these lists are welcome! Strikethrough means the project was renamed, deprecated, or no longer supports this spec out of the box (but might via an optional integration).

Client

Server

Popular Upload Projects
Popular Multipart Projects
Popular Networking Categories
Related Searches

Get A Weekly Email With Trending Projects For These Categories
No Spam. Unsubscribe easily at any time.
Js
Graphql
Upload
Apollo
Apollographql
Multipart