DEV Community

Cover image for Setting Up GraphQL and GraphiQL in Rails: A Comprehensive Guide
Sulman Baig
Sulman Baig

Posted on • Originally published at sulmanweb.com

Setting Up GraphQL and GraphiQL in Rails: A Comprehensive Guide

GraphQL is becoming increasingly popular as an alternative to REST APIs, offering more flexibility and efficiency in data fetching. In this guide, we'll walk through setting up GraphQL and GraphiQL in a Rails application, using practical examples from a real-world implementation.

Prerequisites

  • Ruby on Rails 7.2+

  • Ruby 3.3+

  • Basic understanding of Rails applications

Step 1: Adding Required Gems

First, add the necessary gems to your Gemfile:

gem 'graphql', '2.3.14' gem 'graphiql-rails', '1.10.1' 
Enter fullscreen mode Exit fullscreen mode

Step 2: Installing GraphQL

Run the following commands to install GraphQL and generate the base files:

bundle install rails generate graphql:install 
Enter fullscreen mode Exit fullscreen mode

This will create the basic GraphQL structure in your Rails application:

app/ └── graphql/ ├── types/  ├── base_object.rb  ├── base_enum.rb  ├── base_input_object.rb  ├── base_interface.rb  ├── base_scalar.rb  ├── base_union.rb  ├── query_type.rb  └── mutation_type.rb ├── mutations/  └── base_mutation.rb └── [your_app]_schema.rb 
Enter fullscreen mode Exit fullscreen mode

Step 3: Setting Up GraphQL Controller

Create a GraphQL controller to handle requests:

class GraphqlController < ApplicationController def execute variables = prepare_variables(params[:variables]) query = params[:query] operation_name = params[:operationName] context = { current_user: current_user # This comes from ApplicationController } result = YourAppSchema.execute(query, variables: variables, context: context, operation_name: operation_name) render json: result rescue StandardError => e raise e unless Rails.env.development? handle_error_in_development(e) end private # ... [rest of the controller code] end 
Enter fullscreen mode Exit fullscreen mode

Authentication Setup

The current_user method is defined in your ApplicationController. Here's how to set it up:

class ApplicationController < ActionController::API def auth_header request.headers['Authorization']&.split&.last end def current_user Current.user = User.find_by_token_for(:auth_token, auth_header) @current_user ||= Current.user end end 
Enter fullscreen mode Exit fullscreen mode

This setup allows you to:

  1. Extract the authentication token from the request headers

  2. Find the corresponding user

  3. Make the user available throughout your GraphQL resolvers via context

You can then access the current user in any resolver or mutation:

module Mutations class BaseMutation < GraphQL::Schema::RelayClassicMutation def current_user context[:current_user] end def authenticate_user! raise GraphQL::ExecutionError, 'Not authenticated' unless current_user end end end 
Enter fullscreen mode Exit fullscreen mode

Step 4: Configuring GraphiQL

Add GraphiQL configuration in config/initializers/graphiql.rb:

GraphiQL::Rails.config.header_editor_enabled = true GraphiQL::Rails.config.title = 'Your API Name' 
Enter fullscreen mode Exit fullscreen mode

Update your config/application.rb to handle cookies for GraphiQL:

config.middleware.use ActionDispatch::Cookies config.middleware.use ActionDispatch::Session::CookieStore config.middleware.insert_after(ActionDispatch::Cookies, ActionDispatch::Session::CookieStore) 
Enter fullscreen mode Exit fullscreen mode

Step 5: Setting Up Routes

Add GraphQL routes to config/routes.rb:

Rails.application.routes.draw do post "/graphql", to: "graphql#execute" if !Rails.env.production? mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "/graphql" end end 
Enter fullscreen mode Exit fullscreen mode

Step 6: CORS Configuration

If you're building an API, configure CORS in config/initializers/cors.rb:

Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins "*" resource "*", headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head] end end 
Enter fullscreen mode Exit fullscreen mode

Best Practices

1. Structured Type Definitions

Organize your types in a modular way:

module Types class BaseObject < GraphQL::Schema::Object edge_type_class(Types::BaseEdge) connection_type_class(Types::BaseConnection) field_class Types::BaseField end end 
Enter fullscreen mode Exit fullscreen mode

2. Implement Base Mutations

Create a base mutation class for common functionality:

module Mutations class BaseMutation < GraphQL::Schema::RelayClassicMutation argument_class Types::BaseArgument field_class Types::BaseField input_object_class Types::BaseInputObject object_class Types::BaseObject end end 
Enter fullscreen mode Exit fullscreen mode

3. Error Handling

Implement consistent error handling across your GraphQL API:

module Mutations class BaseMutationWithErrors < BaseMutation field :errors, [String], null: true field :success, Boolean, null: false def handle_errors(record) { success: false, errors: record.errors.full_messages } end end end 
Enter fullscreen mode Exit fullscreen mode

Testing Your Setup

After completing the setup, you can access GraphiQL at http://localhost:3000/graphiql in development. Try this query:

query { __schema { types { name } } } 
Enter fullscreen mode Exit fullscreen mode

GraphiQL view in Rails

Security Considerations

  1. Limit GraphiQL to non-production environments

  2. Implement proper authentication

  3. Use query depth limiting to prevent complex nested queries

  4. Consider implementing rate limiting

Conclusion

With this setup, you have a solid foundation for building a GraphQL API in Rails. The included GraphiQL interface provides a powerful tool for testing and documenting your API during development.

Remember to:

  • Keep your schema well-organized

  • Implement proper error handling

  • Follow security best practices

  • Write comprehensive tests for your GraphQL endpoints

This setup provides a robust starting point for building scalable GraphQL APIs with Rails.


Happy Coding!

Top comments (0)