coverghoul
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
Trending in Questions
I having some trouble figuring out if I have set myself too strict of standards for my production server. Currently I can handle 75% of r...
New
Hello,
I’m trying to build a basic Phoenix web-app, and I’d like to use Tailwind.
However, when I launch mix phx.server, I get an error...
New
Hi everyone.
My team and I have been working on a fairly modest app based around video streaming and chat, but we’ve landed a customer t...
New
I really like the adapter patterns that ecto, nebulex, waffle, etc. use and would love find something similar for a key management servic...
New
Hello folks!
So at work, we are seeing some situations where we have to define some “fixed” strings that are used across the codebase in...
New
I’m working on a small exercise involving update_in/3, and I came up with this solution:
data = %{
name: "Periodic Table",
category:...
New
How Can I Optimise Compile Time Dependencies
I have been building an elixir application for about 2 years now. Many modules and files ha...
New
Other Trending Topics
Edit: 2026 May 15 - This post is archived.
Mob is alive!!
Main docs: mob v0.7.11 — Documentation
A bit of explanation for the slightly c...
New
Hobbes is a low-level distributed database for the Elixir programming language.
Hobbes provides a simple, safe, and scalable storage lay...
New
A little off-topic, but I feel like people here have a good head on their shoulders.
I used to be quite good at making software. Was luc...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
ExRatatui lets you cook up rich terminal UIs in Elixir, powered by Rust’s ratatui via Rustler NIFs. Build interactive terminal applicatio...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #umbrella
- #full-time-contract
- #ai
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #metaprogramming










Showing Posts 1 to 8- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
zachdaniel
When you use
postwith a generic action it expects the generic action to respond with an instance of the resource. So you’d returnstruct(__MODULE__, your_data)coverghoul
Hey Zach,
Thanks for taking the time to help.
I did what you suggested and it started insisting i need a primary key despite the resource non-primary key I had above, and also that read must be implemented so I changed it to the following:
And I added to the function –
When posting with –
This now returns a 200 and –
But logs –
Any thoughts? Or am I doing a non-storage based API completely wrong with ash?
Thanks,
Paul
zachdaniel
Ah, right. So in this case since you’re not using something that has a primary key (i.e non-storage backed as you say), your best bet is not to use routes like
postandget, as those are meant to following specific patterns described here https://jsonapi.orgSpec compliant JSON:API requires ids. However, we provide a facility for doing generic routes that don’t have to strictly follow those formats, which looks like this:
What you can additionally do to simplify is something like this:
Then you can simplify the resource to require no state/attributes.
And you can then use
route/3to define the route:coverghoul
Thanks for the reply, due to my new born haven’t had the time to try implementing. Hopefully he settles down tonight and I’ll be able to let you know how it goes. Thanks you again for all the help.
coverghoul
Hey Zach,
So this worked, I get a return with the right depth, the arguments well defined etc. Thank you for your help! I was debating about typing this up as a tutorial for your docs if you’d accept that PR.
While debating about steps to present it, I found that the return type isn’t displayed it just says “string” and the mathanswer isn’t a type in the swagger definitions. Is there a way to override openapi types on a specific route without doing it at the router level?
Another question would be, if we wanted to host both open_api_spex and ash routers, is there a clean way to combine their auto-generated api docs? I think that would be useful to present to people as an “escape hatch/advanced use cases” thing.
Thanks,
Paul
zachdaniel
In your AshJsonApi router, you can do:
and then you could add your custom open api spex code to our generated one, and that would effectively be merging them.
As for showing
string, I’ve pushed a fix tomainofash_json_apiwhich should address this and show proper type information.Bumbus
Actually I got stuck with this:
GET requests to `http://localhost:4000/api/json/cards/test\` keep returning 404 - no_route_found.
Help please!
Bumbus
Hmm, damn I forgot to add the domain in `AshJsonApiRouter`