Graphql-ruby connections

From wikinotes

Connections between nodes are expressed as edges.
Edges can be abstracted as connections to support query params, filters, pagination, etc.

Connections are a schema design pattern, rather than a part of the graphql spec.
They were designed primarily to handle pagination.

Documentation

pagination docs https://graphql-ruby.org/guides#pagination-guides

Basics

Define a User type

module Types
  class User < GraphQL::Schema::Object
    field :id,   Integer, null: false
    field :name, String,  null: false
  end
end

Define a connection field

class QueryRoot < GraphQL::Schema::Object
  field :users,
    Types::User.connection_type,
    null: false

  def users
    return [
      {id: 100, name: "Alex"},
      {id: 101, name: "Amelia"},
      {id: 102, name: "Jessie"},
      {id: 103, name: "Paul"},
      {id: 104, name: "Carol"},
    ]
  end
end

Produces this graphql SDL schema

SDL schema


schema {
  query: QueryRoot
}

type QueryRoot {
  users(
    after:  String  # elements after cursor.
    before: String  # elements before cursor.
    first:  Int     # first N elements from list
    last:   Int     # last N elements from list
  ): UserConnection!
}

type User {
  id:   Int!
  name: String!
}

type UserConnection {
  edges:    [UserEdge]
  nodes:    [User]
  pageInfo: PageInfo!
}

type UserEdge {
  cursor: String!
  node:   User
}

type PageInfo {
  endCursor:       String    # When paginating forwards, the cursor to continue.
  hasNextPage:     Boolean!  # When paginating forwards, are there more items?
  hasPreviousPage: Boolean!  # When paginating backwards, are there more items?
  startCursor:     String    # When paginating backwards, the cursor to continue.
}


You can then perform queries on either the Connection (supports pagination) or the Node (users only)

Sample Query on Connection


Connections have cursors, to support pagination.

query {
  users(first: 2) {  # Userconnection
    edges {          # UserEdge
      cursor
      node {         # User
        id
        name
      }
    }
  }
}

result

{
  "data": {
    "users": {
      "edges": [
        { "node": { "id": 100, "name": "Alex" } },
        { "node": { "id": 101, "name": "Amelia" } }
      ]
    }
  }
}


Sample Query on Node


Nodes simply return results.

query {
  users(first: 2) {
    nodes {
      id
      name
    }
  }
}
{
  "data": {
    "users": {
      "nodes": [
        { "id": 100, "name": "Alex" },
        { "id": 101, "name": "Amelia" }
      ]
    }
  }
}