zoedsoupe
In our app, we are trying to apply a hexagonal architecture. We have the concept of internal schemas, generally ecto embedded schemas or schemaless changesets that perform some validation or data transformation. Its easier to transport internal data with this logic.
The workflow:
- App receives an incoming message (API, Kafka)
- Controller uses an Adapter to parse an internal schema
- Controller passes this schema to the context
- Render response
However, we have some problems:
- We have several external providers (Kafka, other APIs, frontend) that can have different fields.
- We would need a way to create different versions of a schema, for an API
- We would like to move this validation with schemas more to the edge of our web layer
The idea is somewhat the same as a DTO (Data Transfer Object), but it would be only flat maps only to do validation and maybe reject the invalid incoming message.
Does anyone make something similar to this? Does this make sense at all?
Trending in Discussions
There has been a thread to discuss the Stack Overflow Developer Survey on this forum every year since 2018, so here’s yet another one for...
New
Hi there! :wave:
@frigidcode and I (but mostly him) have been running an Elixir Book club, we’re almost done with Designing Elixir Syste...
New
I love Elixir. It’s one of 2 programming languages I’ve ever fallen in love with.
But I don’t use it anymore.
Serverless was the promis...
New
What IDE or editor are you using for Elixir development?
Personally, I use Zed, and I really like it, but sometimes I wish there were a ...
New
Fly’s CEO posted this recently - Turn And Face The Strange · The Fly Blog
It says that Fly is going all-in on sprites, which is a worry ...
New
This was an interesting post by Jose. Curious to hear what others think. Evolving programming languages in the AI era - Dashbit Blog
Gen...
New
In my third year of college, around 2010, I found Erlang. A few years later, I found Elixir. I liked the ideas at once: many small proces...
New
Other Trending Topics
I fully migrated to my own harness from Anthropic/Gemini and I think it’s time to share it. Welcome DSH, the DeepSeek Harness, fully writ...
New
Hey. Is there anyone here who creates agents in their apps? Not talking about using agents, but creating them. I’m finding it pretty diff...
New
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Emily is an Elixir library that runs Nx computations on Apple’s MLX. Install it as the default Nx backend and Nx, defn, Axon, Nx.Serving,...
New
(I just needed to vent somewhere and LinkedIn is full of hope, or hype, I’m not sure which exactly)
AI dream has many faces, but general...
New
In 2021 I started a new library called Tempo with the objective of modelling time as a set of intervals - not as instants. In 2022 I gave...
New
Categories:
Sub Categories:
Forums
Popular Tags
- #ecto
- #liveview
- #troubleshooting
- #learning-elixir
- #library
- #deployment
- #erlang
- #testing
- #genserver
- #mix
- #absinthe
- #remote-other
- #otp
- #plug
- #how-to-question
- #macros
- #postgres
- #elixirconf
- #channels
- #exunit
- #discussion
- #code-sync
- #podcasts
- #javascript
- #onsite
- #dialyzer
- #docker
- #authentication
- #ai
- #umbrella
- #full-time-contract
- #podcasts-by-brainlid
- #ecto-query
- #blog-post
- #elixirconf-us
- #elixir-ls
- #phoenix_html
- #iex
- #graphql
- #genstage
- #websockets
- #supervisor
- #advent-of-code
- #distillery
- #processes
- #elixirconf-eu
- #api
- #forms
- #security
- #hex











Showing Posts 1 to 9- Show Best Posts
- Show All (oldest first)
- Show All (newest first)
dimitarvp
Your question is somewhat unclear. Providing more context, and especially coding / implementation woes would help understanding the actual challenge.
Sure, but don’t your internal schemas need to have a unified format? If not, then you just have N versions of a similar logic – kinda verbose but nothing unheard of.
Meaning? In Javascript? If not, then nothing stops you from just having Ecto Changesets do all the work just before rendering a response – which, granted, will require slight change of how you do things but if you are implying that this is a lot of work then I admit I can’t see it.
Basically every other project I ever participated in. Extremely normal.
zoedsoupe
Ok, so let’s take this model, that is what is persisted in the database
We could receive data for this entity from two different providers, so let’s create an adapter to convert from params to internal data and an internal schema to make only calculations and data transformations (this can be skipped if no complex transformation flow is required):
So we achieve the application edge, where data is inputted, now we create a “schema” only for validation, maybe with schemaless changesets for each provider:
And the second one:
On the controller it would look like this:
And then create a
ProviderBControllerfollowing same logic.Somehow is similar to rails string params?
It come more clear?
kokolegorille
Your structure is not conventional, and it looks You are trying to do Ruby in Elixir, but Elixir is not Ruby.
Changesets are the usual way to deal with DTO, and You might have many in the same schema. For example one for kafka, one for another provider, etc. Each one with custom validation, and casting rules.
Is there a reason to have business logic in the controller?
zoedsoupe
yeah, I feel this structure is far-fetched and kinda verbose while business logic is spread in all the app. This structure was the main suggestion
I was trying to search more about this case (actually I don’t even know how to name this problem) and how it can be solved in functional programming languages.
I’ll try to focus on changesets.
zoedsoupe
What do you think about this article?
https://milan-pevec.medium.com/the-only-constant-is-a-change-or-how-the-explicit-architecture-can-save-the-day-part-i-85da40dafc64
Could you suggest to me any books or articles about how to understand better different ways of arthicteture in the functional land? Actually, I see many go with event-sourcing and/or CQRS and I would like to study more about it
kokolegorille
You might find this highly related
and
I prefer CQRS/ES because I think it fits well with signal and processes.
This book, although not in Elixir, but in F#, is in my recommendation list
dimitarvp
You have way too many modules. Basically when you have 2 or more shapes of data coming in that you want to parse and validate into your own internal data structure then you just have 2 or more
*_changesetfunctions in yourEcto.Schemamodule. That’s where I’d start.And I am with @kokolegorille here: you’re trying to do big Ruby on Rails app (or Java “enterprise” app) in Elixir which will only serve to make it harder to evolve and change the app.
Start with dropping some weight off of the app IMO.
beepbeepbopbop
The biggest takeaway I’ve personally found implementing these sort of patterns in Elixir (or probably in any functional language), is the concept of “functional core, imperative shell”. I would go on to say that it is the overriding principle in your classic hexagonal architecture, CQRS included (especially in Commanded aggregates).
“Functional core, imperative shell” as a concept does not require as much ceremony as one would think. Certainly nothing on the level of classic OOP languages, although there are a couple of discussion points to have had.
One such argument is the value of persistence and transactionality in your core application. Storage is such a key component to a vast majority of applications that they are intrinsically link to the core. Proponents point out that this is a serialisation process, an imperative shell that needs to be completely isolated from the core system. In the book Designing Elixir Systems with OTP: Write Highly Scalable, Self-Healing Software with Layers by James Edward Gray, II and Bruce A. Tate, it pushes it to a different layer as implied in the table of contents:
In this case, your core systems have no idea about database structures and this requires an encoding/decoding layer that you’ll have to write. While somewhat tedious, it is “technically” correct and if there’s one word to summarise the process of implementing application with the “functional core, imperative shell”, tedious could be a word one would use.
Maybe you don’t really need all this and you place transactionality as part of the domain itself. This certainly makes the rules simpler. In that case, you can model your code in a “light” style of functional core that contexts give you. An excellent primer to get your head in this zone are a series of articles by Sasa Juric:
Just don’t use it as the “source of truth” for all things related to code structure and standards. It’s a set of very well explained decisions, but it would be wrong to conflate it as the “canonical way” to build Elixir applications.
kokolegorille
You might think of your data first. And functions to transform them. Functions are first class citizen.
input → function → output
If You can remember input type, and output type of your functions, You can build pipelines of composable functions.
Then, You might think of where You want to add concurrency to your application, because You are on the BEAM.
This is not mandatory if You use Phoenix, because it’s done for You.
In Your case…