This post actually have 2 questions that are kinda related one to another.
Here is what I’m trying to solve, I have some read action in my resource that, when called by our GraphQL API, should also do a :telemetry
call to bump our view count metric.
My current solution was to create a manual Absynthe object that calls the read action directly and execute the telemetry as-well:
defmodule Marketplace.Markets.Property.GraphQL do
@moduledoc false
alias Marketplace.Markets.Property
use Absinthe.Schema.Notation
object :markets_property_queries do
field :get_valid_property, :property do
arg :id, non_null(:id)
resolve fn _, %{id: id}, %{context: %{actor: actor}} ->
case Property.get_valid(%{id: id}, actor: actor) do
{:ok, property} ->
execute(property, actor)
{:error, %Ash.Error.Forbidden{}} ->
{:error, :forbidden}
{:error, _} ->
{:error, :not_found}
end
end
end
end
defp execute(%{id: property_id} = property, %{id: actor_id} = _actor) do
:telemetry.execute([:property, :view], %{}, %{
property_id: property_id,
user_id: actor_id
})
{:ok, property}
end
defp execute(%{id: property_id} = property, _actor) do
:telemetry.execute([:property, :view], %{}, %{
property_id: property_id,
user_id: nil
})
{:ok, property}
end
end
This works, but it is very verbose and sits outside the resource.
It also has a problem when the GraphQL user requests to load some other reference inside the resource, it will just fail since the action itself doesn’t load that resource by default.
So, my first question is, can I move this telemetry call inside the action somehow? If it was a create, update, destroy action, I would just simply create a change
with after_transaction
and put the telemetry there, but this is a read action, so I’m not sure if there is anything “similar” to use for this.
My second question is, assuming the first one is possible, does AshGraphQL
add some metadata to the context or somewhere else so I can know that the actions was actually called by my GraphQL API and not by calling the action directly? I just want to trigger the telemetry call when the action is called via my GraphQL API.