Thumbnail art by fabio on Unsplash.

Quick GraphQL Tutorial For Beginners! Get Started Fast With GraphQL And Rails 6 | Week 12 – 20in20

GraphQL - What Is It?

I had barely been exposed to GraphQL when I was first asked to cover it over on the Deanin YouTube channel. My only experience was a brief demo done in one of my IT classes in College. Not one to shy away from a challenge, however, I finally decided to tackle it.

But what actually is GraphQL? Well, according to its website:

GraphQL is a query language for APIs and a runtime for fulfilling those queries with your existing data. GraphQL provides a complete and understandable description of the data in your API, gives clients the power to ask for exactly what they need and nothing more, makes it easier to evolve APIs over time, and enables powerful developer tools.

It’s always interesting trying a new tech like GraphQL inside of Ruby on Rails. It almost always adds an additional layer of complexity, and demystifying it can be a challenge. Thankfully I managed to stumble my way through my first application in about 5 days though. Hopefully this blog post can serve as a starting point for you to try GraphQL as well.

Video Version Of This Tutorial

I’m including video timestamps again just in case you want to skip to a specific part and save some time!

0:00 Video Overview & Intro
2:30 Create Ruby On Rails With GraphQL App
8:04 Creating Models For GraphQL To Use
11:00 GraphQL Generators inside of Ruby on Rails 6
12:52 GraphQL Types For Queries
19:46 GraphQL Mutators For Data Creation
25:25 Bug Fixes
27:45 GraphQL Demo With Example Queries And Mutations
35:35 Video Summary & Outro

Part 1 - Creating The Rails App

We’re going to be moving pretty quick here, because it’s late and the actual commands and code aren’t too bad. First we’re going to create the Rails app and do some basic GraphQL setup by adding gems. We’ll run some installers, create and modify a few files, and run some model generators. I’ll add comments to the code so you know which file to create/modify for each line.


    # In your terminal, run:
    rails new graphql-postapp --api --skip-test --skip-spring
    cd graphql-postapp
    bundle add graphql
    bundle add graphiql-rails
    rails g graphql:install
    
    rails g model Post title body:text
    rails g model Author name
    rails g migration add_author_to_posts author:references
    
    rails db:migrate
    
    # Next, open up a rails console and create an author.
    # In your terminal, type:
    rails c
    author = Author.new
    # Change Dean to whatever you want
    author.name = "Dean"
    author.save
    # Press CTRL + D to exit the rails console.

Next, inside of your application, create the typical assets folder inside of /app. Inside of that assets folder, create a config folder. Finally, inside of that config folder you’ll want to create a manifest.js file and include the following links. Afterwards, you’ll need to modify your /config/application.rb file.


    # config/application.rb
    # uncomment the following
    require "sprockets/railtie"
    
    # Inside your routes.rb file, configure GraphiQL
    
    Rails.application.routes.draw do

      if Rails.env.development?
        mount GraphiQL::Rails::Engine, at: "/graphiql", graphql_path: "/graphql"
      end
    
      post "/graphql", to: "graphql#execute"
      # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html
    end
    

Part 2 - Creating The GraphQL Types

Next up we’re going to be running some GraphQL generators. These will create the necessary files inside of your graphql folder in your project. There’s two types of actions to worry about: Queries and Mutations. The queries we create will be to retrieve data. The mutations are to create, update, or destroy data.


    # In your terminal, run the following to create your types
    rails g graphql:object Post
    rails g graphql:object Author
    
    # Run these commands to create your mutations
    rails g graphql:mutation CreateAuthorMutation
    rails g graphql:mutation CreatePostMutation
    
    # Next, in app/graphql/types/query_type.rb
    # change it to match the following:
    
    module Types
      class QueryType < Types::BaseObject
        field :posts, [Types::PostType], null: false do
          description "Query that selects all posts."
        end
    
        field :postsCount, Integer, null: false do
          description "Query that returns the total number of posts."
        end
    
        def posts
          return Post.all
        end
    
        def postsCount
          return Post.count
        end
    
      end
    end

    

Next we’ll have to create both the PostType and the AuthorType. We’ll be adding descriptions to our data. This makes it easier to see inside localhost:3000/graphiql what code does what. If you add a description to a var and it shows up describing a thing in a query, you know that file is for queries!


    # graphql/post_type.rb
    module Types
      class PostType < Types::BaseObject
        field :id, ID, null: false do
          description "This post's id."
        end
        field :title, String, null: true do
          description "This post's title."
        end
        field :body, String, null: true do
          description "This post's body, the main content of the post."
        end
        field :created_at, GraphQL::Types::ISO8601DateTime, null: false do
          description "The date/time that this post was created at."
        end
        field :updated_at, GraphQL::Types::ISO8601DateTime, null: false do
          description "The date/time that this post was last updated at."
        end
        field :author_id, Integer, null: false do
          description "The id of this post's author."
        end
        field :author, AuthorType, null: true do
          description "This post's author in object form."
        end
      end
    end
    
    # graphql/author_type.rb
    module Types
      class AuthorType < Types::BaseObject
        field :id, ID, null: false
        field :name, String, null: true
        field :post, [PostType], null: true
        field :created_at, GraphQL::Types::ISO8601DateTime, null: false
        field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
      end
    end

Part 3 - GraphQL Mutations!

For this next part we’ll be creating the post mutation. I’ve left the author mutation intentionally blank so that you have something to practice with. In all honesty, you could just mostly copy paste from post mutation to get this working. That said, copy pasta is how I got this far in life, so it should help you too haha.


    # Inside graphql/create_post_mutation.rb
    module Mutations
      class CreatePostMutation < BaseMutation
        field :post, Types::PostType, null: false
    
        argument :title, String, required: true do
          description "The title field is a string type and is required for a new Post to be created."
        end
    
        argument :body, String, required: true do
          description "This is the post's main content, it is called the body and it expects a string."
        end
    
        argument :author, Integer, required: true do
          description "The id of this post's author."
        end
    
        def resolve(title:, body:, author:)
          @post = Post.new(title: title, body: body, author: Author.find_by_id(author))
    
          if (@post.save)
            {
              post: @post,
              errors: []
            } else {
              post: nil,
              errors: @post.errors.full_messages
            }
          end
        end 
      end
    end
    
    # Inside graphql/create_author_mutation.rb
    module Mutations
      class CreateAuthorMutation < BaseMutation
        # TODO: define return fields
        # field :post, Types::PostType, null: false
    
        # TODO: define arguments
        # argument :name, String, required: true
    
        # TODO: define resolve method
        # def resolve(name:)
        #   { post: ... }
        # end
      end
    end


Part 4 - Some Example GraphQL Queries And Mutations

So you made it this far and now you’re wondering, “Dean, How do I test this GraphQL app and actually use it?” Well don’t worry, because if there’s one thing I’m great at it’s answering easy questions to seem like an expert! I’ll include the example queries as well as instructions on how to execute them from what we did in the video. Hopefully this answers your questions a bit.

Just remember though, the reason why your application works is because we manually created that one author! You’ll want to mutate a few extra authors and set up your author mutations/types for more advanced functionality. This will probably mirror what we did in posts quite a bit!


    # Inside your terminal, run:
    rails s
    # Then open a browser and navigate to localhost:3000/graphiql
    # That's graphiql, not graphql. Remember the i!
    
    # In your browser, you can run the following mutation to create a post or two:
    mutation {
      createPostMutation(input: {
        title:"Test",
        body:"test",
        author:1
      }) {
        post {
          authorId,
          title,
          body
        }
      }
    }
    
    # And you can run variations of this query to query your GraphQL Database
    query {
      postsCount,
      posts {
        title,
        body,
        authorId,
        author {
          id,
          name
        }
      },
    }

Conclusion - GraphQL Is Awesome!

So there you have it, that’s what I came up with while learning GraphQL this week! I’m really impressed with the technology and happy with how much I’ve learned the last 5 days. It’s amazing how much a little API wrapper thing can do.

I’m hoping to maybe carry GraphQL into an upcoming week of the 20in20 Challenge project. Maybe do something with some more advanced mutations and queries. Hey, maybe I’ll even learn enough to get Devise working with GraphQL! Well, thanks for your time and I hope this helped. Until next time, Deanout.

Share this post

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.