Rails with GraphQL

Rails with GraphQL cover image

Rails is still one of the fastest ways to get an API on disk. This note is the small setup I used for a Rails API app with GraphQL and PostgreSQL.

Install Ruby and Rails

I used rbenv for Ruby versions:

brew install rbenv
rbenv install 3.0.1

Install Rails and Bundler:

gem install rails
gem install bundler

You can list available Ruby versions if you want a different one:

rbenv install --list

Create an API-only app

Start Rails without the default frontend stack and use PostgreSQL:

rails new app --api -d postgresql
cd app

Add the GraphQL gem:

bundle add graphql

Generate the GraphQL skeleton:

rails generate graphql:install

Rails puts the GraphQL code under app/graphql. That is where the schema, object types, mutations, and resolvers live.

Why this shape works

Rails handles the application shell: routing, database config, models, migrations, validations, and environment wiring. GraphQL gives clients a typed query surface without creating a pile of custom REST endpoints for every screen.

The setup is small enough that you can inspect all of it. That matters more than the generator output. The first thing I check after install is the generated schema, the base query type, and how errors are returned. If those are clear, the rest of the app can grow without much ceremony.

What to inspect next

After the generator runs, I would check these files before building features:

  • app/graphql/types/query_type.rb
  • app/graphql/types/mutation_type.rb
  • app/graphql/app_schema.rb
  • the generated controller route for GraphQL requests

The goal is to understand the boundary before adding models. Which errors are returned to clients? Are exceptions hidden or exposed? Where does authorization belong? Are mutations named around domain actions, or are they just CRUD wrappers around tables?

Rails makes it easy to move quickly, but GraphQL schemas age badly when every screen gets its own shape. I prefer starting with a small query surface and a few intentional mutations. The schema should describe product operations, not leak the database one table at a time.