ash_graphql/documentation/tutorials/getting-started-with-graphql.md
Riccardo Binetti 513c1ac68f
improvement!: port AshGraphql to Ash 3.0 (#123)
Step 1: update Ash

Step 2: mass rename Api to Domain

Step 3: Ash.Query.expr -> Ash.Expr.expr

Also change ref interpolation

Step 4: remove all warnings

Step 5: remove registries from tests

Step 6: fix filter

Step 7: private? -> !public?

Step 8: Ash.Calculation -> Ash.Resource.Calculation

Step 9: use depend_on_resources/1 -> resources/1

Step 10: add Domain to all resources

Step 11: use Ash module for all actions

Step 12: add public? true all around

Step 13: remove verbose? from options passed during Domain calls

Step 14: add simple_sat

Step 15: Ash.ErrorKind is no more, so remove code from errors

Step 16: sprinkle default_accept :* around tests

Step 17: replace Ash.Changeset.new/2 with Ash.Changeset.for_*

Step 18: calculation fixups

- Context is now a struct and arguments go under the arguments key
- Function based calculations receive a list of records
- Add a select to query-based loads
- select -> load

Step 19: pass the correct name to pass the policy in tests

Step 20: Ash.Query.new/2 is no more

Step 21: add AshGraphql.Resource.embedded? utility function

Use that instead of Ash.Type.embedded_type?(resource_or_type) since resources
are not types anymore

Step 22: handle struct + instance_of: Resource in unions

Resources are not type anymore so they need to be passed this way in unions

Step 23: ensure we only check GraphQL actions for pagination

All reads are now paginated by default, so this triggered a compilation error

Step 24: swap arguments for sort on calculations

Step 25: remove unused debug? option
2024-04-01 14:03:06 -04:00

4.3 KiB

Getting Started With GraphQL

Get familiar with Ash resources

If you haven't already, read the Ash Getting Started Guide. This assumes that you already have resources set up, and only gives you the steps to add AshGraphql to your resources/domains.

Bring in the ash_graphql dependency

def deps()
  [
    ...
    {:ash_graphql, "~> 0.28.0"}
  ]
end

Add some backwards compatibility configuration

in config/config.exs

config :ash_graphql, :default_managed_relationship_type_name_template, :action_name
config :ash_graphql, :allow_non_null_mutation_arguments?, true

This won't be necessary after the next major release, where this new configuration will be the default.

Add the domain Extension

Add the following to your domain module. If you don't have one, be sure to start with the Ash Getting Started Guide.

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

  graphql do
    authorize? false # Defaults to `true`, use this to disable authorization for the entire domain (you probably only want this while prototyping)
  end

  ...
end

Add graphql to your resources

Some example queries/mutations are shown below. If no queries/mutations are added, nothing will show up in the GraphQL API, so be sure to set one up if you want to try it out.

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

  graphql do
    type :ticket

    queries do
      # Examples

      # create a field called `get_ticket` that uses the `read` read action to fetch a single ticke
      get :get_ticket, :read
      # create a field called `most_important_ticket` that uses the `most_important` read action to fetch a single record
      read_one :most_important_ticket, :most_important

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

    mutations do
      # Examples

      create :create_ticket, :create
      update :update_ticket, :update
      destroy :destroy_ticket, :destroy
    end
  end

  ...
end

Add AshGraphql to your schema

If you don't have an absinthe schema, you can create one just for ash.

in lib/helpdesk/schema.ex

defmodule Helpdesk.Schema do
  use Absinthe.Schema

  @domains [Helpdesk.Support]

  use AshGraphql, domains: @domains

  # The query and mutation blocks is where you can add custom absinthe code
  query do
  end

  mutation do
  end
end

Connect your schema

Using Plug

If you are unfamiliar with how plug works, this guide will be helpful for understanding it. It also guides you through adding plug to your application.

Then you can use a Plug.Router and forward to your plugs similar to how it is done for phoenix:

plug AshGraphql.Plug

forward "/gql",
  to: Absinthe.Plug,
  init_opts: [schema: Helpdesk.Schema]

forward "/playground",
  to: Absinthe.Plug.GraphiQL,
  init_opts: [
    schema: Helpdesk.Schema,
    interface: :playground
  ]

Using Phoenix

You will simply want to add some code to your router, like so.

You will also likely want to set up the "playground" for trying things out.

pipeline :graphql do
  plug AshGraphql.Plug
end

scope "/" do
  pipe_through [:graphql]

  forward "/gql", Absinthe.Plug, schema: Helpdesk.Schema

  forward "/playground",
          Absinthe.Plug.GraphiQL,
          schema: Helpdesk.Schema,
          interface: :playground
end

If you started with mix new ... instead of mix phx.new ... and you want to still use phoenix, the fastest path that way is typically to just create a new phoenix application and copy your resources/config over.

What's next?

Topics:

How Tos:

Monitoring