Hey Ash Community,
I found ash and the json api and immediately thought of robust documenting APIs like fastapi in python, or spring in java. I’ve been playing with it, and for resources I’m backing into postgres this makes total sense/works. I’m trying to sent up a “calculation only” api (a bunch of recursive math calls), that I don’t need to store into the DB, this is what I came up with:
The domain –
defmodule App.Math do
@moduledoc """
This establishes our ash domain so that we track what is in scope
"""
use Ash.Domain, extensions: [AshJsonApi.Domain]
resources do
resource App.Math.Answer
end
json_api do
routes do
# in the domain `base_route` acts like a scope
base_route "/math/fibonacci", App.Math.Answer do
post :calculate_fibonacci
end
end
end
end
The resource –
defmodule App.Math.Answer do
@moduledoc """
This will showcase an API endpoint that does not store into the database,
but instead does a calculation and returns to the user this value
"""
use Ash.Resource,
domain: App.Math,
extensions: [AshJsonApi.Resource]
attributes do
attribute :problem, :string
attribute :answer, :integer
end
resource do
require_primary_key? false
end
defp calc_fibonacci(0) do
[0 | 0]
end
defp calc_fibonacci(1) do
[1 | 0]
end
defp calc_fibonacci(depth) when is_integer(depth) and depth >= 0 do
[head | tail] = calc_fibonacci(depth - 1)
[head + tail | head]
end
def calculate_fibonacci(depth) when is_integer(depth) and depth >= 0 do
hd(calc_fibonacci(depth))
end
json_api do
type "answer"
end
actions do
action :calculate_fibonacci, :struct do
constraints instance_of: __MODULE__
argument :depth, :integer do
constraints [min: 0]
allow_nil? false
end
run fn input, _context ->
{:ok, %{problem: "fibonacci", answer: calculate_fibonacci(input.arguments.depth)}}
end
end
end
end
When I post to this with -
{
"data": {
"attributes": {
"depth": 3
}
}
}
I get -
[error] ** (ArgumentError) Could not determine a resource from the provided input: %{answer: 2, problem: "fibonacci"}
I could be approaching this the wrong way (and would welcome that feedback/a steer in the right direction), but was hopeful to have something that takes advantage of the swagger/redoc generation ash-json has. Thanks for reading this.
Paul