Have you used or are thinking about using the Ash Framework?

If so for what kind of projects? What do you think of it? :smiley:

https://elixirforum.com/t/ash-framework-a-declarative-resource-oriented-application-development-framework-for-elixir/51119

4 Likes

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?

5 Likes

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.

8 Likes

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.

7 Likes

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!

1 Like

Looks like I let the domain name expire :man_facepalming: Google was gracious enough to let me renew it after expiration, they had a grace period or something. Really appreciate the heads up :smiley:

3 Likes

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.

5 Likes

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 :slight_smile: Because otherwiseā€¦ I wouldnā€™t even know where to start or if I even need it :slight_smile:

1 Like

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 :smiley:

6 Likes

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.

6 Likes

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. :slight_smile:

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.

25 Likes

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

4 Likes

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)

3 Likes

Iā€™m sold. Any example I can look at?

1 Like

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 :wink:

10 Likes