So, in my quest to convert an existing system (slowly) over to Ash, I’m trying to figure out how to replicate certain patterns in the system.
For reading a single resource or updating, the Ash flow is pretty obvious with authorization. The resource is in the context and I can do whatever. Awesome.
I’m not seeing a clear example of how to handle “collection” operations.
(And by the way, now that I’m really digging in, it’s all kind of overwhelming! In good and bad ways, lol. It’s much easier to build something to learn it, which is what’s up right now.)
For instance, creating a resource. In my existing system, most of our collection type functions look like this:
defmodule Comments
def create(context_resource, attrs, actor, opts \\ []) do
...
end
def query(context_resource, query_params, actor, opts \\ []) do
...
end
end
If I’m going to create a comment, I’m likely going to want to authorize create in relation to the article. “Does this article allow comments? Is the user a real user?” This also goes really well with REST APIs that actually make use of the URL.
POST /articles/:id/comments
“Create a comment where the context is the article.”
My code is going use something in Ecto like put_assoc/3
, in many cases, to attach the context to the newly created resource. The changset functions also typically take the same form: create_changeset(context_resource, attrs, user, opts \\ [])
. I have to imagine, thinking about your own JSON:API support, that there’s definitely a path for this, even where the implementation is different.
Queries work similarly. In the system I’m working on, I rarely deal with a collection of things in context to a user (and when I do, I pass in the user as the context resource and maybe a different one as the actor). It’s usually some children of a thing that the user has access to. So in an API example:
GET /articles/:id/comments
“I want all the comments for a blog.” Where does that play out in actions? (I probably won’t dive into relationships until I get policies working a bit better, so maybe I am ahead of myself.) I want to authorize against the article and then get the appropriate comments.
Consider this example from the docs. In this create, the only context I have is the concept of a beer. What if I wanted to create a beer in context of being in France versus the US in terms of determining the drinking age? What’s the “proper” way to provide that to the action?
I know this is long. I sense a combination of relationships and your own context stuff is how this goes together.
Also, I got hung up in authorization, lol. The answer might be, “Bruh, just go read up in on relationships.” That’s probably not on the menu till Saturday.