GraphQL Query Generation

GraphQL Request and Response

Following where we left off from Getting Started with GraphQL, we'll explore what the GraphQL requests and responses look like for different queries defined with the AshGraphql DSL.

defmodule Helpdesk.Support.Ticket. do
  use Ash.Resource,
    ...,
    extensions: [
      AshGraphql.Resource
    ]

  attributes do
    # Add an autogenerated UUID primary key called `:id`.
    uuid_primary_key :id

    # Add a string type attribute called `:subject`
    attribute :subject, :string
  end

  actions do
    # Add a set of simple actions. You'll customize these later.
    defaults [:read, :update, :destroy]
  end

  graphql do
    type :ticket

    queries do
      # create a field called `get_ticket` that uses the `read` read action to fetch a single ticket
      get :get_ticket, :read 
    end
  end
end

For the get_ticket query defined above, the corresponding GraphQL would look like this:

query($id: ID!) {
  get_ticket(id: $id) {
    id
    subject
  }
}

And the response would look similar to this:

{
  "data": {
    "get_ticket": {
      "id": "",
      "subject": ""
    }
  }
}

Let's look at an example of querying a list of things.

  graphql do
    type :ticket

    queries do
      # create a field called `get_ticket` that uses the `read` read action to fetch a single ticket
      get :get_ticket, :read 

      # create a field called `list_tickets` that uses the `read` read action to fetch a list of tickets
      list :list_tickets, :read 
    end
  end

This time, we've added list :list_tickets, :read, to generate a GraphQL query for listing tickets. The request would look something like this:

query {
  list_tickets {
    id
    subject
  }
}

And the response would look similar to this:

{
  "data": {
    "list_tickets": [
      {
        "id": "",
        "subject": ""
      }
    ]
  }
}

Now, let's say we want to add query parameters to list_tickets. How do we do that? Consider list :list_tickets, :read and the actions section:

  actions do
    # Add a set of simple actions. You'll customize these later.
    defaults [:read, :update, :destroy]
  end

  graphql do
    type :ticket

    queries do
      # create a field called `list_tickets` that uses the `read` read action to fetch a list of tickets
      list :list_tickets, :read 
    end
  end

The second argument to list :list_tickets, :read is the action that will be called when the query is run. In the current example, the action is :read, which is the generic Read action. Let's create a custom action in order to define query parameters for the list_tickets query.

We'll call this action :query_tickets:

  actions do
    defaults [:read, :update, :destroy]
    
    read :query_tickets do
      argument :representative_id, :uuid

      filter(
        expr do
          is_nil(^arg(:representative_id)) or representative_id == ^arg(:representative_id)
        end
      )
    end
  end

  graphql do
    type :ticket

    queries do
      # create a field called `list_tickets` that uses the `:query_tickets` read action to fetch a list of tickets
      list :list_tickets, :query_tickets
    end
  end

In the graphql section, the list/2 call has been changed, replacing the :read action with :query_tickets.

The GraphQL request would look something like this:

query($representative_id: ID) {
  list_tickets(representative_id: $representative_id) {
    id
    representative_id
    subject
  }
}

More GraphQL Docs

If you haven't already, please turn on the documentation tag for AshGraphql. Tags can be controlled at the top of the left navigation menu, under "Including Libraries:".