I’m using ash_json_api and I’m trying to add metadata to the response of a create action, but it doesn’t seem to be included in the meta field. I’ve got the following relevant pieces in my resource:
json_api do
type "asset"
routes do
base "/assets"
get :read
index :read
post :create
end
end
actions do
defaults [:read]
create :create do
# Set the current user as the owner of the asset
change relate_actor(:user)
# Create signed url for the asset
metadata :signed_url, :string, allow_nil?: false
change Swoop.Media.Changes.GeneratePresignedUrl
end
end
In GeneratePresignedUrl I’m returning this in a after_action function:
result = Ash.Resource.put_metadata(result, :signed_url, url)
{:ok, result}
But unfortunately after doing a POST to the endpoint with curl, I’m getting empty meta fields:
At the moment, action metadata isn’t translated to record meta in the JSON:API. Please open a feature request for this
To accomplish what you want, you have two options:
you can use the metadata option on the route to add route-level meta. This is done via a function of the various components of the request. This will be in the top level meta, not the record’s metadata. DSL: AshJsonApi.Resource — ash_json_api v1.4.9
you can use a calculation instead of metadata:
calculate :signed_url, :string, fn records ->
Enum.map(records, fn record ->
signed_url(record)
end)
end
This can then be requested in the fields parameter, i.e fields[type-name]=foo,bar,baz,signed_url.
The way you are attempting to use it is actually its intended use case However, it just hasn’t been hooked up to ash_json_api yet. AshGraphql has a way to expose metadata in exactly that same way. It requires some adjustments to our open api schema generation logic, because we need to do one of three things:
allow you to configure a special type name for the results of the action, i.e asset-with-url
we have to add that meta to all types
we have to keep meta as untyped “object”
Its a solvable problem, just hasn’t been implemented yet