jaydenseric / graphql-multipart-request-spec

A spec for GraphQL multipart form requests (file uploads).
993 stars 54 forks source link

I cant send one file and other data, like a string. #44

Closed SamuelSSan28 closed 3 years ago

SamuelSSan28 commented 3 years ago

Always I receive this error: Variable \"$name\" got invalid value { resolve: [function], reject: [function], promise: {} }; Boolean cannot represent a non boolean value: { resolve: [function], reject: [function], promise: {} }

jaydenseric commented 3 years ago

This repo is for maintaining a specification, it sounds like you have a usage question about a particular (unspecified) implementation.

It looks like you are using the GraphQLUpload scalar from a reasonably modern graphql-upload version, probably your issue is that in variables on the client you are using a File incorrectly for your name variable; probably you meant for the name to be a string. Also, run npm ls graphql-upload and make sure you only have one version installed.

SamuelSSan28 commented 3 years ago

No, Im tryng send other arg with the file. But dont work, and i try all types specifications and dont work.

tbarkley commented 3 years ago

@jaydenseric thank you for your work, could you please clarify or reference how extra form data should be sent? I saw this example and was trying to do the same but not sure of the correct way;

https://medium.com/@vcomposieux/handle-file-uploads-using-a-graphql-middleware-11914ba05bfc

$ curl http://localhost:8000/graphql \ -F operations='{ "query": "mutation DoUpload($file: Upload!, $title: String!) { upload(file: $file, title: $title) }", "variables": { "file": null, "title": null } }' \ -F map='{ "file": ["variables.file"], "title": ["variables.title"] }' \ -F file=@myfile.txt \ -F title="My content title

jaydenseric commented 3 years ago

@tbarkley I have not seen someone trying to send GraphQL multipart requests like that before. There is no mention of this GraphQL multipart request spec in the eko/graphql-go-upload repo, so maybe it's not intended to be compliant?

For this spec, the way to do your example (free-hand, there might be typos):

curl http://localhost:8000/graphql \
  -F operations='{ "query": "mutation DoUpload($file: Upload!, $title: String!) { upload(file: $file, title: $title) }", "variables": { "file": null, "title": "My content title" } }' \
  -F map='{ "file": ["variables.file"] }' \
  -F file=@myfile.txt \

Only file variables should be extracted into separate multipart file fields.

As for the general question of purposely sending extraneous multipart form fields, that is something I can't recall discussing; probably it was considered but in all these years we never encountered a use case. If such custom fields were to go anywhere, maybe at the end after the files? I'm not sure from memory what graphql-upload will do if it encounters non file fields after all the expected file fields.

I think an extraneous file field after operations and map will be safely ignored:

https://github.com/jaydenseric/graphql-upload/blob/1772dddbb99c4fd3764fbd4f289111c075dfeb2d/test/public/processRequest.test.js#L297-L345

Although, they will still count for the maxFiles setting:

https://github.com/jaydenseric/graphql-upload/blob/1772dddbb99c4fd3764fbd4f289111c075dfeb2d/test/public/processRequest.test.js#L435-L499

Potentially the wording of the spec could be updated, saying that operations, map, and mapped file fields must be in that order, but can have extraneous fields before, after or interspersed and that they should be ignored by server implementations. For performance though, the first fields should be operations and map so that resolvers can be run sooner.

jaydenseric commented 3 years ago

For people only reading emails, I made a correction to my previous comment in an edit.

tbarkley commented 3 years ago

Thank you @jaydenseric for the explanation and help.