Hey everyone, time for Teaser #2!
If you missed teaser #1, check out out here: Ash 3.0 Teasers!
This is a big one
Ash.Api → Ash.Domain
Ash.Api
as a name has caused users lots of confusion in the past. It is an overloaded term. Also, while we considered it the “API to a given bounded context” as in, you always interacted with a resource through an API, we’ve ultimately decided to change the conceptual role of what we call an API
. With that change, comes a name that is more representative of its function. Shoutout to @lukasender for the suggestion that stuck.
Ash.Domain
represents the configuration of a domain, which includes things like “what resources are available to this domain”, as well as other high level configurations. Instead of calling to an API module, we provide one standard interface, but that interface must always be able to determine what Domain
it is interacting with, in addition to what Resource
it is working with. Keep reading for more on what this looks like.
domain
option to use Ash.Resource
When creating a resource, you pass the domain
option. For example:
defmodule MyApp.Accounts.User do
use Ash.Resource,
domain: MyApp.Accounts
end
This static configuration can be used in various places where you would have previously had to specify an api
. For example, you no longer need to specify define_for
in the code_interface
block.
You will get a warning if you don’t pass the domain
option, as well as if the configured domain doesn’t know about the resource.
Which leads us to one of the more significant changes of 3.0:
Using Ash
instead of MyApp.MyApi
We will be deprecating the functions that we typically on MyApp.MyApi
, in favor of those same functions defined in the Ash
module. This allows us to refactor resources and move them from one domain to another without having to hunt down the calling code that interacts with it. It also helps reduce the cognitive overhead of having to remember what Api you’re working with for any given resource in order to call an action on it.
For example:
MyApp.Helpdesk.Ticket
|> Ash.Changeset.for_create(:open, %{title: "halp"})
|> MyApp.Helpdesk.create
MyApp.Helpdesk.count!(MyApp.Helpdesk.Ticket)
MyApp.Helpdesk.Ticket
|> Ash.Query.for_read(:open)
|> MyApp.Helpdesk.read!()
Would become
MyApp.Helpdesk.Ticket
|> Ash.Changeset.for_create(:open, %{title: "halp"})
|> Ash.create
Ash.count!(MyApp.Helpdesk.Ticket)
MyApp.Helpdesk.Ticket
|> Ash.Query.for_read(:open)
|> Ash.read!()
How to make this change
Good news! You can make this change before upgrading to 3.0. You can do everything stated above by configuring the api
option when calling use Ash.Resource
, and switching your calls to the api to call Ash
! The difference between 2.0 and 3.0 is that in 3.0 the functions defined on the api module will be deprecated, and api
has been renamed to domain
.
Teaser #3: Ash 3.0 Teasers! - #23 by zachdaniel