Getting Started with GraphQL

Lesson Overview

Welcome to the first lesson of our "Introduction to GraphQL with Ruby" course! In this lesson, we will introduce you to GraphQL and graphql-ruby and guide you through setting up a basic GraphQL server.

GraphQL and graphql-ruby

GraphQL is a query language for APIs that allows you to request only the data you need, unlike REST, which often requires multiple endpoints. graphql-ruby is the most popular GraphQL implementation for Ruby, known for its robustness and excellent documentation. In this course, we'll use Sinatra, a lightweight web framework, to handle HTTP requests and serve our GraphQL API.

Basic Structure of a GraphQL Server

Key components of a GraphQL server:

  • Schema: Defines data types and the shape of queries. For example, a QueryType with a hello field that returns a String.
  • Resolvers: Methods that fetch data as per the schema. For example, the resolver for hello returns "Hello, GraphQL!".

When handling a query, the server:

  1. Validates the query.
  2. Resolves fields using resolvers.
  3. Returns the resulting data.

Creating the Basic GraphQL Server

In this section, we'll set up a basic GraphQL server step by step.

  1. Require Necessary Libraries.

    Ruby
    require 'sinatra'
    require 'graphql'
    require 'json'

    Load the necessary modules to create and define the GraphQL server.

  2. Define Schema.

    Ruby
    class QueryType < GraphQL::Schema::Object
      field :hello, String, null: false
      def hello
        'Hello, GraphQL!'
      end
    end

    This defines a simple schema with a QueryType that has a single field hello, returning a String. The null: false parameter indicates that this field will always return a value and never return null — this is a GraphQL type constraint that helps clients know they can rely on receiving a string. The resolver method hello returns the string "Hello, GraphQL!".

  3. Create the Schema.

    Ruby
    class MySchema < GraphQL::Schema
      query QueryType
    end

    This creates the GraphQL schema using the QueryType we defined.

  4. Set Up Sinatra Endpoint.

    Ruby
    post '/graphql' do
      request_payload = JSON.parse(request.body.read)
      query = request_payload['query']
      variables = request_payload['variables'] || {}
      result = MySchema.execute(query, variables: variables)
      content_type :json
      result.to_json
    end

    This creates a POST endpoint at /graphql that accepts GraphQL queries, executes them against our schema, and returns the results as JSON. The variables handling allows clients to send dynamic values separately from the query string, making queries reusable and more secure (similar to parameterized SQL queries). The content_type :json line sets the HTTP response header to indicate that the server is returning JSON-formatted data, ensuring clients parse the response correctly.

  5. Start the Server.

    Ruby
    set :port, 4000

    When you run the server file with ruby server.rb, Sinatra will start, and you should see:

    text
    == Sinatra (v3.0.0) has taken the stage on 4000 for development with backup from Puma

Querying the Server

Now that your server is running, let's query it to test if everything works correctly by querying the server in a separate file.

  1. Require Necessary Libraries.

    Ruby
    require 'net/http'
    require 'json'
    require 'uri'

    These modules help in making HTTP requests to your server.

  2. Define URL and Query.

    Ruby
    url = URI('http://localhost:4000/graphql')
    query = '
      query {
        hello
      }
    '

    Specify the URL of your GraphQL server and the query you want to run.

  3. Create a Function to Execute the Query.

    Ruby
    def fetch_graphql_data(url, query)
      begin
        http = Net::HTTP.new(url.host, url.port)
        request = Net::HTTP::Post.new(url.path, { 'Content-Type' => 'application/json' })
        request.body = { query: query }.to_json
        response = http.request(request)
        data = JSON.parse(response.body)
        puts JSON.pretty_generate(data)
      rescue => error
        puts "Error: #{error.message}"
      end
    end
    fetch_graphql_data(url, query)

    The rescue => error block provides error handling for common issues that can occur when making HTTP requests, such as the server not running, network connection problems, invalid JSON responses, or incorrect URLs. Without this error handling, the script would crash with an unhelpful error message if any of these issues occurred. Instead, it catches any errors and displays a user-friendly message, making it easier to diagnose and fix problems.

    Running this function should give you the output:

    JSON
    {
      "data": {
        "hello": "Hello, GraphQL!"
      }
    }

This confirms the server correctly handles your query and provides the expected response.

Lesson Summary

Up next, you'll practice creating more complex schemas and queries. This hands-on practice will solidify your understanding and prepare you for advanced topics.

Sign up

Join the 1M+ learners on CodeSignal

Be a part of our community of 1M+ users who develop and demonstrate their skills on CodeSignal