-
Notifications
You must be signed in to change notification settings - Fork 272
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Any hint / doc / guide / recipe / tutorial for graphql (with graphql-ruby gem)? #244
Comments
Hi! At the moment there is no official way to upload files using GraphQL (as far as I am aware). You have three options how to solve this problem:
My suggestion would be to use method Personally, I've used method Hope this gets you going in the right direction :) |
@stankec Thank you for chiming in and providing a good writeup on the available options in using Shrine with GraphQL. |
@stankec, thanks a lot for you amazing answer. I think there is another way, but maybe I'm wrong. I think I can have in my single page application client (Apollo, Relay, ember-graphql, whatever) a form to send with graphql normally and an upload component (detached from that main form) that upload to my Shrine endpoint. After the upload I can take metadata (from the Shrine's response) and fullfill an hidden field of my graphql form. Am I totally wrong? Where am I wrong? |
@johnunclesam you are correct. You can do that and it's no different from the approach outlined in method A pre-signed URL doesn't necessarily have to go to S3, it can go to your server, DigitalOcean Spaces, Google Cloud Storage, etc. The point of the approach is "out-of-order upload", that is, that you upload a file first and then send it's location to the server to store it. Be aware of the downsides of this approach. If you don't pre-sign URLs anybody will be able to leave a file on your server and retrieve it at any time - this can cause legal issues since people can effectively use your server as a file repository for illegal materials. This isn't completely solved by pre-signing - pre-signing only solves the "anytime" and "anybody" part since to upload or retrieve a file your server has to be contacted first to generate a URL, and at that point, you can determine to e.g. decline the request to non-logged-in users. Another issue is "shopping cart collection". In a regular upload (multipart) if a client aborts the form submission the file is "lost" in the sense that it wasn't stored on the server. But with pre-signed URLs, a client can abort form submission after they have uploaded a file. To remove those orphaned files you will have to create a script that periodically removes them (e.g. non-attached images older than 24 hours). You can also ignore this issue all together but it may become costly if you are on a service like S3 or it could crash your app if the server's disk gets filled up. |
Hey! @johnunclesam @hmistry can we mark this issue as resolved? |
@janko-m I will trade beer for closed issues :D 🍻 |
@stankec Thank you so much for providing such detailed explanation for using Shrine with GraphQL ❤️. You definitely get a beer for that 🍺 |
Found this guide via search, would be great to move it somewhere to the documentation, so the others could find it much easier than me :) |
I'm not sure whether this belongs in Shrine documentation, because it's about hooking up Shrine with something else. And there are a lot of things you could hook up Shrine to: JSON-API, gRPC, CKEditor, Trix etc. I would rather that someone writes an article about it, and then we can add a link on https://shrinerb.com. I'm hardly the person to do it, though, because I've never used GraphQL. I'm also too busy developing and documenting Shrine features by themselves. |
@janko-m here's the article https://blog.stanko.io/graphql-file-upload-with-shrine-45fa26463c68 |
Another method: inject the uploaded file in the execution context. |
@dmitry can you explain this further? |
@monorkin in the controller's action you can pass file from the result = Schema.execute(
params[:query],
variables: ensure_hash(params[:variables]),
context: {file: params[:file]}
) |
@dmitry This is not that different from the multipart upload method. In face the only difference is that you packed your data in a custom location. I didn't cover what to do after the file gets to your server because there isn't an universally best solution - how you pack your data depends on your use-case. I only covered how to get your data from your client to your server, since this is the unstandardized part of GraphQL. |
Any hint / doc / guide / recipe / tutorial for graphql (with graphql-ruby gem)?
I found nothing here (in the issues) and nothing here: http://shrinerb.com.
Why?
The text was updated successfully, but these errors were encountered: