Subscriptions Triggers

Learn how to use GraphQL to trigger subscriptions.

Introduction to trigger subscriptions

Since we have already built our context and schema, we can jump directly to building the relevant mutation fields in the GraphQL schema and filling out each resolver.

Press + to interact
mutation do
field :ready_order, :order_result do
arg :id, non_null(:id)
resolve &Resolvers.Ordering.ready_order/3
end
field :complete_order, :order_result do
arg :id, non_null(:id)
resolve &Resolvers.Ordering.complete_order/3
end
# «Other fields»
end

Our :ready_order and :complete_order fields use new resolver functions from PlateSlateWeb.Resolvers.Ordering. Let’s add those:

Press + to interact
def ready_order(_, %{id: id}, _) do
order = Ordering.get_order!(id)
with {:ok, order} <- Ordering.update_order(order, %{state: "ready"}) do
{:ok, %{order: order}}
else
{:error, changeset} ->
{:ok, %{errors: transform_errors(changeset)}}
end
end
def complete_order(_, %{id: id}, _) do
order = Ordering.get_order!(id)
with {:ok, order} <- Ordering.update_order(order, %{state: "complete"}) do
{:ok, %{order: order}}
else
{:error, changeset} ->
{:ok, %{errors: transform_errors(changeset)}}
end
end

Subscribing to these events is slightly different from before because now we’re trying to handle events for specific orders based on ID. When the client is notified about new orders by a new_order subscription, we want to allow them to subscribe to future updates for each subscription.

We want to support a GraphQL document that looks like this:

Press + to interact
subscription {
updateOrder(id: "13") {
customerNumber
state
}
}

Notably, we want to use this one subscription field to get updates triggered by both the :ready_order and :complete_order mutation fields. While it’s important to represent the mutations as different fields, we often just need a single subscription that lets us get all the state changes for ...