đź‘‹

Thoughts On Moving Away From Ash

Straight out of the gate I need to express how freaking cool an idea Ash really is.

This is not a hit piece. I love it as a technology.

First encounters

I first came across Ash when I watched this video from it’s creator Zach Daniel

https://www.youtube.com/watch?v=7P_crH_M_AE

import Quote from ’../../components/markdown/Quote.astro’

Spaghetti belongs in the kitchen, not in your codebase

What a quote!

And a great talk, I thoroughly recommend giving it a watch as its one of those videos which gets your mind ticking over the various possibilities he raises for long after it finishes.

What Ash promises

Ash has a really nice story around generalising data structures and entities. It sees itself as the highest level, low code framework for Elixir.

By modelling all of your data as Resources you are able to make high level abstractions which manipulate these resources and generate code based on them. Since everything is abstracted into these resources, you get the full power of composability.

This is really impressive when you see it in action, being able to join and query across disparate data sources and even spit out Graphql resolvers with full role/user based access control is extremely powerful.

The community

The Ash discord is a top notch forum for discussion. I dipped in at one point to ask about how you would model a third party API as an Ash Resource, and Zach (the author of the framework) replied to me within an hour - not many frameworks where you’ll get an answer so quickly!

A quick aside on wrapping the Dropbox API in a Resource

I wanted to build a Resource which didn’t hook into Postgres for its data, but was instead built from the Dropbox API. A Resource representing a document in Dropbox basically.

This can be done with Ash preparations. These prepare blocks are ran before/after any read action takes place on your resource.

preparations do
	prepare(fn query, _ ->
		Ash.Query.before_action(query, fn query ->
			# code here for accessing the data
			data = documents 
			|> Enum.map(file -> 
				__MODULE__
				|> Ash.Changeset.for_create(:local, %{
					path: file.path,
					name: file.name,
					content: file.content
				})
				|> Sinclair.Vault.create!()
			end)

		Simple.set_data(query, data)
	end)
end

Simple here is Ash’s Simple datalayer. Its exact as it sounds, simple. It has an API for forceably setting data for a given query.

With the data in place we can do all the normal magic Ash is good for, filtering and composing with other Resources.

Ash’s rough edges

The tooling

Let’s be honest, Elixir’s LSP can be flakey at the best of times. Autocomplete and jump-to-definition can be broken in many different places for many different reasons.

A prime example is the Phoenix router files. No chance will you be able to hop gracefully from a specified route to the module which is points to!

It’s just the cost of doing business.

I think in that case its down to the tall stack of macros which combine to give you that “nice” authoring experience with the DSL for writing routes. The LSP just can’t resolve them all and keep reference to the original code which called it. That’s my guess anyway.

Ash suffers from a similar problem. Everything is a DSL. That’s kind of the point.

This means autocomplete is going to be a long lost friend for you whilst you entangle yourself with Ash’s slick embrace.

The learning curve

It feels almost like Rust. It will take a long time to get over the hump, but once you do there’s a shit ton of value to be gained. You just have to do the investment up front.

Unfortunately this links back to my previous point however, at least with Rust there is the compile to give you seriously top notch googling material. That coupled with every dev and his dog writing (trying to write) Rust these days, there’s plenty of material to correct your bad assumptions and unstick you when needed.

Documentation

Since the framework is still in its infancy and hasn’t hit language-wide adoption (yet), resources other than the official docs are hard to come by. If you start needing to do something which doesn’t fit nicely into the official guide you’re fighting an up hill battle.

For example, in the Dropbox API Resource I wrote about above, that took a LOT of debugging, perusing docs which didn’t help until I finally gave in and asked in the Discord (what?! I’m shy ok!)

Now its definitely a me problem here, but in Arc browser the docs site is unusable. I think its down to how much content there is on the page, but scrolling through any of the big pages is just freakishly slow.

O’ What could have been

Honestly, I’m quite disappointed with myself that I’m not pushing ahead and becoming an evangelist for the framework.

I know. I can see the value.

When I started playing with Ash I had grand ideas of educating everyone at work about it and us swapping it in to our platform, and the huge impact it would have of being able to live in that abstraction. But alas, it is not to be. Although I got reactions of interest from team members, the amount of change and education realistically doesn’t make it feasible.

I’m at a stage in my career and in my personal life when I need to minimise the complexity. I’ve just had a child and so the time I have for tech is very limited. So building up the requisite knowledge to absolutely fly using this framework just doesn’t feel possible.

Luckily for me, the project I’m using (this very website you are reading this piece) is pretty simple in scope, so ripping out and rebuilding the data layer is not an insurmountable task. Am I the only one who likes stripping things down and starting again? That’s probably why none of my personal projects are ever finished!

Anyway look out for the next instalment of “I build my blog in X technology, here’s my takeaways” coming soon to a feed near you!