DEV Community

Cover image for File uploading in GraphQL API in Rails with ActiveStorage
Sulman Baig
Sulman Baig

Posted on • Originally published at sulmanweb.com

File uploading in GraphQL API in Rails with ActiveStorage

ActiveStorage was launched with Rails 6.0 that is a built-in file manager for local, S3, or any other storage platforms. ActiveStorage own documentation is quite extensive to explain how it manages file uploads and how to call them.

While working with GraphQL in Rails, there, arises a problem with uploading a file to the system. One way is to upload the file through REST API but what if we want solely in GraphQL then there is a gem to do that. ApolloUploadServer.

Document Model:

I usually create a polymorphic associated document model for file uploading and then attach them after upload. So, my model looks like this:
app/models/document.rb
This model also verifies the content type for images and pdfs uploading only. With documentable, we can use polymorphism with other models.

GraphQL Document Type:

Now we are creating the GraphQL type for document output. Mine looks like below:

app/graphql/types/objects/document\_type.rb

I have url, and I am using s3 service so showing the service url. But in other environment I am using local storage, that is why I have different document URLs for the environment. All other parameters are fairly descriptive.

Apollo Upload Server:

Now, comes the point to create a mutation resolver for uploading the file to the system. The complete documentation of ApolloUploadServer is here. After adding the gem to the Gemfile now we can create our mutation. My mutation looks like this:

app/graphql/mutations/create\_document.rb

Here, doc is the active storage parameter saving the file, so, it is being used of ApolloUploadServer. The output will be the type we created before.


The code is at https://gist.github.com/sulmanweb/aae082a30c3b7f2264895f7376ecdca8

Happy Coding!

Discussion (1)

Collapse
phawk profile image
Pete Hawkins

Hey Sulman, this is really helpful, in my current app using GraphQL I handled this by getting a presigned S3 URL and uploading from the client directly to S3. In the future I might take a look at refactoring this to use your approach and be more "The Rails Way".