GraphQL file upload with Shrine

To process a file our server needs to get the client’s form submission containing the URL of the file, download the file, process it and re-upload it to the block-storage server..This uses up bandwidth and IO but it’s necessary.This method should be satisfactory for most use-cases..If your application doesn’t require immediate file processing then the downloading and re-uploading can be done in the background or on a separate machine (using an AWS lambda)..On AWS you can get the best of both world using the Serverless image handler.Shrine supports this feature out-of-the-box through the presign plugin..To get it running you’ll need to add the AWS S3 SDK to your Gemfile, configure a new storage for Shrine, and expose the file presign endpoint — this is explained in detail in the documentation.Once the client uploads the file it needs to send some kind of reference to the server — the URL of the file, or an ID, or the path of the file (I usually send the original file name as well as the URL).GraphQL example mutation of how to upload an avatar imageThe server uses this reference to build a Shrine object and attach it.Code snippet that converts S3/Spaces URLs to Shrine objects using presigned URLsNote that you can use the upload_endpoint plugin instead of the presign_endpoint plugin..I advise against this as it enable anyone to upload any content, at any time, to your block-storage..By presiging we solve the “anyone” and “anytime” issues — we have control over who can request presigned URLs to upload or download files.Base64 encodingThis method is the simplest, yet it’s the worst for real-world applications.Your client can encode the file’s data as Base64 and set it as the value of a mutation’s field.GraphQL example mutation of how to upload an avatar image using Base64 encodingWhile on the surface this seems harmless, since the image has to be uploaded to the server in one way or another, this approach has many unwanted side-effects.The biggest issue is memory consumption..Since the image is now part of your request’s JSON body it will be parsed as a string, which will drive your memory consumption up..E.g..If you upload ten 5MiB images in one mutation you will have a hash that’s at least 50MiB in memory..Storing whole files in memory can and will crash your application.I advise against using this method..If you wish to implement it, you can do so using Shrine’s data_uri plugin.. More details

Leave a Reply