If so for what kind of projects? What do you think of it?
Iām definitely really interested in aspects of Ash and really impressed with the documentation and effort that has gone into it. I really appreciate that it integrates with Phoenix as opposed to trying to replace it. The main two reasons I havenāt jumped in yet are a) I donāt feel any pain around contexts and actually really quite like them, and b) the DSL gives me pause. My worry around the DSL isnāt that it isnāt flexible (from reading the docs it seems quite flexible) itās that if Iām going to learn it, I want to expend the energy to go deep and I just donāt have that energy to throw at it right now. Are there any reasonably fleshed out demo repos using Ash Ć la LiveBeats?
Iām not using Ash but Iām using Spark, the library to build DSLs that Ash builds upon, and Iām having a good time with it so far. Itās extremely flexible and itās criminally easy to build DSLs with it.
So by extension it seems Ash is also super flexible and extensible, with lots and lots of escape hatches. Iād probably give it a shot in a new project. So far, Iām happy using Spark.
The new documentation site is written with Ash! https://ash-hq.org itās fully open source available here: GitHub - ash-project/ash_hq: The Ash Framework homepage and documentation site.
Innnnnterrrresting. Ok, ya amazing, I will dig into this. A cursory glance is throwing some ideas about phoenix Iāve had for a bit of a loop, but in a possibly good way. It was a very cursory glance!
Pertinent aside: Are you aware your site is down (which the ash docs link to)? https://zachdaniel.dev/
I was not, thanks for letting me know!
Looks like I let the domain name expire Google was gracious enough to let me renew it after expiration, they had a grace period or something. Really appreciate the heads up
No prob! Alerting people to their expired domains?āāThis is what I do.ā
Well, no, this is like the third time everā¦ possibly just the secondā¦ Iāve just been watching a lot of Seinfeld lately.
Its working on my phone, but it might take some time for the DNS to get figured out/might have its DNS cached still. Hopefully fixed by tomorrow.
Iāve looked at it several times. It looks enticing, but when reading through docs it looks intimidating.
Iām eagerly looking forward to the ābuild X in 15 minutesā video the author metnioned in a comment Because otherwiseā¦ I wouldnāt even know where to start or if I even need it
Still building up to that, but on Friday weāve got a video coming with LiveView Mastery that is a bit of a ātourā through an example app that shows the various building blocks
I havenāt tried Ash but reading the docs it looks similar to Lucky Framework for Crystal.
A lot of macros and remembering the right incantation instead of working with primitives. What happens if I have to go off the beaten path? Thatās my main concern with trying to use Lucky and something like Ash.
Has anyone used it in prod for anything? Whatās the day to daylike? Where can you cut yourself?
I am in the process of writing a new version of Schulferien Deutschland Webpage (a page with school vacations of some 40,000 German schools) with Ash. I like the whole idea of the clean DSL. It feels like a one stop shop to me. I only have to take care of one thing and get a lot of things for free (e.g. the RESTful JSON and the graphql API).
I hope so save a lot of time in future projects by using Ash. Right now I am not there yet. It is a bumpy ride. @zachdaniel is very responsive on Discord but I have trouble with some documentation.
Bottom line: I think Ash has the potential to become a game changer. Faster and more secure development.
Does mix phx.gen.auth
supports Ash resources?
How can we handle authentication?
If you donāt want to use ash_authentication
then your best bet is to use mix phx.gen.auth
and then adapt it to work with your resources. Alternatively, you can just use mix phx.gen.auth with ecto schemas and use the produced user as the āactorā.
I use it for a proprietary ERP weāre developing in house (LiveView and GraphQL API), and for numerous personal LiveView projects, some of which will eventually be open-sourced.
Iāve been using it for a few years, closely following the development. It is indeed a massive project, can be intimidating at first, but itās not necessary to understand the full capability of the project to start leveraging it, and itās certainly worthwhile!
Right off the bat, I have to say that the Discord community on the Ash server is very active, several devs that use it in prod keep an eye on things and jump in w/ help in addition to Zach. Thereās lots of help if you get stuck or arenāt sure how to do something in Ash.
Very hard to do an elevator pitch, but hereās an attempt:
Instead of working with tooling (like Ecto, Absinthe) directly, you define resources with a DSL.
A resource is both a definition for a struct of data, as well as a place to configure all extensions for that data (APIs, auth policies, DB config, etc.). A short list of polished, official extensions/features you get (opt-in) out of the box:
- Ecto schemas
- Postgres datalayer w/ migration generation
- Attribute and schema-based multi-tenancy (including DB migration tooling!)
- CSV datalayer
- ETS datalayer
- Internal Elixir API (w/ pagination, sorting, filtering)
- JSON API (w/ pagination, sorting, filtering)
- GraphQL API (w/ pagination, sorting, filtering)
- Calculated fields (supporting sorting and filtering)
- Aggregate fields (supporting sorting and filtering)
- Dead-simple soft-delete
- Custom validations, can be action-specific
- Can join relationships across different datalayer types (e.g. CSV & postgres ā uses dataloader pattern for efficiency)
- Very smart notifications for PubSub, and custom stuff like Emails
- Powerful authorization policies that work w/ Internal, JSON and GraphQL APIs (has an expression language)
- You can set authorization rules on an API like:
# This prevents the footgun of forgetting to authorize an API call. # To bypass authz, you will have to explicitly set authorize?: false in the call. # Other options are available to fit your requirements. authorization do authorize :by_default require_actor? true end
- Phoenix tooling w/ incredibly powerful and simple API for dealing w/ nested forms.
- A (new) authentication extension (customizable) as an alternative to
phx.gen.auth
- Many of these features have strong compile-time validations for config
- DSL formatter, customizable so you can pick the order of the DSL sections!
- Elixir LS integration ā does lots of smart auto-complete!
- Any extension you want to write on your own
Iād compare it to Tailwind in a way: It has patterns and tooling that can be easily used to create bespoke apps. It creates a tremendous amount of consistency across your app and API, and allows you add features later that donāt break your API. For example, if you start out without using authorization, pagination, filtering or sorting, then add it later, no problem! Those arguments are additional opts to pass, so you donāt break anything by enabling it later.
Itās hard to get a feel from examples in the docs, but it really does NOT nail you down to a formulaic CRUD pattern. You can have any number of actions. There are basic action types (:create
, :read
, :update
, :destroy
), but no limit on how many of each type, and they can have different args and/or accepted attributes. There are also tons of escape hatches that give you multiple levels of intervention if the OOTB options arenāt cutting it for your needs. For example, in API actions, you have access to before_action
and after_action
hooks to manipulate the changeset before it hits the DB, or you can do a fully manual action and handle persistence on your own. Another example, in calculated fields, you can use an expression syntax and even use SQL fragments:
calculations do
calculate :name_full,
:ci_string,
expr(
fragment(
"concat_ws(' ', ?, ?, ?, ?, ?)",
name_title,
name_first,
name_middle,
name_last,
name_suffix
)
)
end
As an example of how far you can go, Iāve been using my own extension that adds a user_interface
section to the DSL which allows you to define how forms/tables/cards should be generated for LiveView (e.g. custom classes, how to group fields in forms, etc) and some smart components that can derive the forms based on what resource you pass it. I hope to open source this somewhat soon, BTW.
This really just scratches the surface. Thereās a ton to learn about Ash, but you can start very simple and build your knowledge/usage over time.
As an addendum to drive home the point that this is not like other frameworks w/ lock in, before settling on Ash, I tried and rejected:
- GraphCool/Prisma
- Postgraphile
- Hasura
Ash it far, far less restrictive than all of those options. (Which is of course not to cast shade on them ā theyāre pretty cool too, especially Postgraphile!) With each of those, I ended up feeling boxed in, not to mention they required the SPA route. With Ash, Iāve been able to develop for LiveView without feeling too boxed in, then later added in a GraphQL API very easily (just adding one section to the DSL and setting up the Absinthe entry point/routes) later for 3rd party use
Iām thinking of writing a commenting system with LiveView or LiveState with Ash for fun and for my blog (mainly for fun. There are already very good options available in this space like isso)
Iām sold. Any example I can look at?
We started using Ash right around the time the 2.0 Release hit. To be honest, I was quite sceptic at first. After using NestJS in Node for the backend before, I did not want to have a Framework that would make it hard to do things differently than the Framework creator had envisioned.
But Ash allowed us to get started really fast, just declaring our Resources and exposing them, using AshGraphql. The Support I received in Discord was immensely helpful and often made my day at work.
After Starting with writing your own actions/changes/calculations to keep the code clean, you can go further into extensions and data layers later on, giving you a lot of potential to extract out common functionality and separate those by concern. The way Ash works, it was always possible to jump in at some point in the process and do additional work or just do some custom work with ash still handling stuff like argument validation for you.
So far, Ash has helped us greatly with reducing boring work, while not feeling restrictive in how you can do things.
10/10 would recommend