TypedGql.OperationInfo (typedGql v0.12.0)

Copy Markdown View Source

Tags outgoing requests with their originating defgql operation so that multiple requests can be told apart — most usefully inside Req.Test stubs.

This is a Req plugin: attach it to opt in, then read the info back from the test conn.

Opt in

Attach from your client's prepare_req/1 callback. Define it conditionally so it only takes effect in the environments you want (e.g. :test):

defmodule MyApp.GitHub do
  use TypedGql, otp_app: :my_app, source: "priv/schemas/github.json"

  if Mix.env() == :test do
    def prepare_req(req), do: TypedGql.OperationInfo.attach(req)
  end

  defgql :get_user, "query GetUser($id: ID!) { user(id: $id) { name } }"
end

Read it back

Req.Test.stub(MyApp.GitHub, fn conn ->
  case TypedGql.OperationInfo.get(conn) do
    %{function: "get_user"} -> # ...
  end
end)

Use in tests

The main use is telling apart multiple operations that share one Req.Test stub/expect, so a single mock can answer each defgql function differently:

test "page renders user and their posts" do
  Req.Test.expect(MyApp.GitHub, 2, fn conn ->
    case TypedGql.OperationInfo.get(conn).function do
      "get_user" -> Req.Test.json(conn, %{"data" => %{"user" => %{"name" => "Alice"}}})
      "list_posts" -> Req.Test.json(conn, %{"data" => %{"posts" => []}})
    end
  end)

  # ... exercise code that calls both MyApp.GitHub.get_user/1 and list_posts/1
end

Without it, a shared stub cannot distinguish requests whose only difference is which defgql function produced them (anonymous operations have no operationName in the body to branch on).

When attached, every request carries up to three headers:

  • x-typed-gql-function — the defgql function name (e.g. get_user)
  • x-typed-gql-client — the client module (e.g. MyApp.GitHub)
  • x-typed-gql-operation — the GraphQL operation name (omitted for anonymous operations)

Summary

Functions

Attaches the operation-info request step. Opt in from prepare_req/1.

Functions

attach(request)

@spec attach(Req.Request.t()) :: Req.Request.t()

Attaches the operation-info request step. Opt in from prepare_req/1.