Upload Images to S3 in GraphQL Using Rails and Paperclip
graphqlme.com
graphqlme.com
I tend to think uploading files via GraphQL is an anti-pattern. The downsides outweigh the benefits over just using presigned URLs.
Advantages:
* Possibly simpler to get a simple case up and running
* No need to use a file store that supports presigned URLs
* Can perform processing of files during upload.
Disadvantages:
* No progress events during upload, so you can't show a progress bar
* A GraphQL server wants to be as lightweight as possible, and not keep requests open for long. The common resolution strategies tend to involve creating a lot of file descriptors, dealing with files in the form of base64 strings or attachments is asking for trouble.
* Simplicity benefits don't last long.
* Perceptively slower for clients.
Basic pattern is:
Client: Hey API server, I want to upload a file
API: Sure, here's a URL you can PUT the file directly to. It will expire in 10 minutes, you can always ask for another if you run out of time
Client: Thanks!
-- Client uploads file directly to URL --
That said, I have no idea what paperclip is and I wouldn't even consider using a framework like rails for such a simple task.
The question is why doing it by base64 encoding those images through the GraphQL API, but not all tutorials show useful examples.
BTW, paperclip is a gem that allows to add files to a model, with extensions to handle several backends (S3 among them) and process those files (convert formats, crop images with frontend integration, etc). It's probably the oldest gem in that genre, the main alternative being Carrierwave.
Alternatively, if you needed to allow some user to upload files, you might want to guard against abuse and generate expiring links.
There are a few reasons you might want uploads to go through the server, and they basically amount to having more control. Imagine that you have an API that's being used by multiple sources - maybe a web app and a mobile app. The initial work to create uploads to S3 directly for each might not be too bad, but what happens if you want to change something later? Maybe you decide to move from S3 to something else, or maybe you decide that each upload should actually generate 3 different sizes of the image. If you do it through the server, this is all relatively simple. On the other hand, if you do it directly to S3, then not only do you have to change it in two places now, but you also have to navigate the issue of app versions - your original app version is uploading to S3 but your new one is uploading to some other hosting service, so how do you really get off of S3? And how do you keep them in sync? Definitely possible, but much more painful than changing a few configuration options on the server and migrating the existing data, etc.
This doesn't seem secure. How are you confident you don't allow people to misuse your s3 bucket?
[1]: http://docs.aws.amazon.com/AmazonS3/latest/API/sigv4-HTTPPOS...