-
Notifications
You must be signed in to change notification settings - Fork 55
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move file uploads doc to its own page (#98)
- Loading branch information
1 parent
1a055d8
commit be73682
Showing
4 changed files
with
91 additions
and
88 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
--- | ||
title: File uploads | ||
description: Enabling file uploads in Apollo Client for iOS | ||
--- | ||
|
||
Apollo iOS supports file uploads via the [GraphQL multipart request specification](https://github.com/jaydenseric/graphql-multipart-request-spec) with a few caveats: | ||
|
||
- Uploading files with GraphQL is most often suitable for proof-of-concept applications. In production, using purpose-built tools for file uploads may be preferable. Refer to this [blog post](https://www.apollographql.com/blog/backend/file-uploads/file-upload-best-practices/) for the advantages and disadvantages of multiple approaches. | ||
- The [Apollo Router](/router/) doesn't support `multipart-form` uploads. | ||
|
||
### Uploading files with Apollo iOS | ||
|
||
Apollo iOS only supports uploads for a single operation, not for batch operations. You can upload multiple files with a single operation if your server supports it, though. | ||
|
||
To upload a file, you need: | ||
|
||
- A `NetworkTransport` which also supports the `UploadingNetworkTransport` protocol on your `ApolloClient` instance. If you're using `RequestChainNetworkTransport` (which is set up by default), this protocol is already supported. | ||
- The correct `MIME` type for the data you're uploading. The default value is `application/octet-stream`. | ||
- Either the data or the file URL of the data you want to upload. | ||
- A mutation which takes an `Upload` as a parameter. Note that this must be supported by your server. | ||
|
||
Here is an example of a GraphQL query for a mutation that accepts a single upload, and then returns the `id` for that upload: | ||
|
||
```graphql | ||
mutation UploadFile($file:Upload!) { | ||
singleUpload(file:$file) { | ||
id | ||
} | ||
} | ||
``` | ||
|
||
If you want to use this to upload a file called `a.txt`, it looks something like this: | ||
|
||
```swift | ||
// Create the file to upload | ||
guard let fileURL = Bundle.main.url(forResource: "a", withExtension: "txt"), | ||
let file = GraphQLFile( | ||
fieldName: "file", // Must be the name of the field the file is being uploaded to | ||
originalName: "a.txt", | ||
mimeType: "text/plain", // <-defaults to "application/octet-stream" | ||
fileURL: fileURL | ||
) else { | ||
// Either the file URL couldn't be created or the file couldn't be created. | ||
return | ||
} | ||
|
||
// Actually upload the file | ||
client.upload( | ||
operation: UploadFileMutation(file: "a"), // <-- `Upload` is a custom scalar that's a `String` under the hood. | ||
files: [file] | ||
) { result in | ||
switch result { | ||
case .success(let graphQLResult): | ||
print("ID: \(graphQLResult.data?.singleUpload.id)") | ||
case .failure(let error): | ||
print("error: \(error)") | ||
} | ||
} | ||
``` | ||
|
||
A few other notes: | ||
|
||
- Due to some limitations around the spec, whatever the file is being added for should be at the root of your GraphQL query. So if you have something like: | ||
|
||
```graphql | ||
mutation AvatarUpload($userID: GraphQLID!, $file: Upload!) { | ||
id | ||
} | ||
``` | ||
|
||
it will work, but if you have some kind of object encompassing both of those fields like this: | ||
|
||
```graphql | ||
# Assumes AvatarObject(userID: GraphQLID, file: Upload) exists | ||
mutation AvatarUpload($avatarObject: AvatarObject!) { | ||
id | ||
} | ||
``` | ||
|
||
it will not. Generally you should be able to deconstruct upload objects to allow you to send the appropriate fields. | ||
|
||
- If you are uploading an array of files, you need to use the same field name for each file. These will be updated at send time. | ||
- If you are uploading an array of files, the array of `String`s passed into the query must be the same number as the array of files. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters