-
Notifications
You must be signed in to change notification settings - Fork 32
Feature: File upload? #6
Comments
(Note: the final decision on the best path forward here is up to @evanshauser and @jbaxleyiii, I'm just facilitating!) |
@jaydenseric I 💯 think we should include your work in |
Cool, I'll get familiar with the codebase and the middleware/afterware system. |
Is query batching a consideration here? |
@jaydenseric Currently, batching could be done in a custom fetch function(which merges the http specific headers) or in another stand-alone library(middleware/afterware have access to the batch). Does either option make file upload easier for you now or for a later transition? For now though, servicing a single upload works great! I envision the manipulations would be made before the middleware, so that they have the ability to modify the full request. Or file upload could be a middleware that is exported with the apollo-fetch. Let me know if that fits with your thoughts or you like something better. CC @jbaxleyiii |
We have a choice: Run middleware before, or after the upload process transforms the request to If middleware runs before, it will be able to access the request as an object whether uploads are present or not. Middleware would not have the last say on what gets sent. If it runs after, authors will need to account for the request being a I think it's best to run middleware before uploads are processed. As the codebase is currently, it would not be possible to implement uploads via middleware. The request body is forcibly converted to a JSON string. We could change that to first check if the request is an instance of To get client part done here, the easiest approach is to make it compatible with |
Noting here the current spec for request transforms between This is just a JSON representation of what's going on each step; I have tidied the order of some of the properties, omitted others that we discard anyway (File fields in FormData have a lot going on), and used JSON to represent instances. You can use jaydenseric/apollo-upload-examples to log this behavior. I am working on a new No query batchingNormal request bodyFor context, here is a normal POST request body, as per {
"operationName": "aTest",
"query": "query aTest($arg1: String!) { test(who: $arg1) }",
"variables": { "arg1": "me" }
} Upload request body before
|
@stubailo @evanshauser @jbaxleyiii I just did a lot of edits to my above comment regarding a spec for multipart post requests to |
It's quite late here, so we won't be able to say anything useful until tomorrow. I agree this might not make sense to implement as a middleware right now.... but... As one more question, would it make possible to expand the middleware functionality to enable file upload to be implemented in middleware form? Somehow make it possible for the request options set by the middleware contain multipart form data? If we think there might be multiple ways of encoding and sending files, that might be an advantage. On the other hand, it might also be useful to "enforce" a standard way of sending files so that everyone can be using the same approach. |
There are a few moving parts here, but the more I think about it, the best thing to start with is to standardize a structure for multipart POST requests between a client and Once that is agreed upon, client and server implementations can be decided separately and worked on immediately. The details of how a client generates the multipart request (using middleware, etc.) can be worked out. The details of what a server does after receiving the multipart form (store files to a temp dir like In the short term it would be a win for users if they only had to use |
I really like this idea that we can do batching, since In terms of standardizing the single multipart POST request format, I hesitate to use the structure of "before apollo-upload-server" over the nesting that "after apollo-upload server" exhibits(minus the temporary paths). In my mind, this nesting feels more natural with apollo-fetch's current interface:
I'm not convinced it is better, since it means we wouldn't be immediately compatible with
@jaydenseric what do you think about the standard/does it provide the information the server needs? Would it be reasonable for the upload client and server to follow a similar pattern? Also curious what @jbaxleyiii thinks CC @stubailo |
@evanshauser multipart forms are limited in that the actual files being uploaded can only be top level fields. They have to be extracted from the operation for transport then put back in the right place at the other end. Keep in mind that the file does not actually look like the nice JSON representation when a field in a multipart form, it is a big blob with all the binary data. There is a lot to explain about how to efficiently process the multipart form stream on the server in relation to resolver arguments, but that can be another conversation. Here is a nice explanation for how multipart forms work. |
When batching, the files from each batch together have to occupy top level multipart form fields. That is why in the example the field name |
Thank you for the pointer! I'll take a look at it in the morning and I have to think about the impact of adding fields to the operation passed to fetch, so I should get back to you in a couple hours. Our future plan for apollo-fetch in addition to being a lightweight fetcher is to underlie an http link, which follows the specification of apollo-link. This prompts the thought to make a file upload into a link that ends a chain, similar to httpLink. I think it comes down to where we want to put the file upload complexity. Your thoughts on the best place, inside a link or apollo-fetch, would be really informative and most likely guide the decision. The usage would look like this: const networkInterface = Links.split(
isFileUpload,
new FileUploadLink({uri}),
new HttpLink({uri}),
); |
I expect to have a PR for |
I have published The logic (and It should be pretty easy now to implement it here. I never use Typescript though so that will really slow me down. Lets see. |
A work in progress. Fixes apollographql#6.
Hey guys, anyone got this working with TypeScript? I'm getting this error: |
I think
apollo-fetch
has an opportunity to be the only simple GraphQL client library out there with support for file uploads. Looks likeapollo-upload-client
is quite simple implementation-wise, so it would be fine to build that stuff right in!@jaydenseric @evanshauser @jbaxleyiii let's talk here, I think this would be a big win not only for Apollo Client having file upload capability, but also for
apollo-fetch
as a standalone utility!The text was updated successfully, but these errors were encountered: