Hopefully, then, you can see why having quite literally every single file here create Ecto.Querys is a code smell? To re-iterate, in case it isn't clear, Ecto.Querys are basically a way for you to write SQL queries to read/write from your database. my_loader.ex is a Dataloader specific concept think of it as a way of batching GraphQL requests to avoid the N+1 problem.resolvers/my_entity_resolver.ex and types/my_entity_types.ex are relatively normal Absinthe files which are effectively the equivalent of our Phoenix controller, but for GraphQL.controllers/my_entity_controller.ex is a standard Phoenix controller which lets us trigger code in response to certain REST-like actions.Modules defined in these files will simply wrap one or more functions defined by contexts in my_project/, maybe doing some mapping/rendering/converting of different data formats. Typically, I don't expect very much real business logic to live in this directory. Everything within my_project_web/ is what I'd define as a "consumer application".A more realistic schema name would be user.ex, or admin.ex. my_entity.ex is a standard Ecto.Schema, something that maps records in your database into standard Elixir structs.A better example to name my_context.ex would be something like accounts.ex which exposes functions such as Accounts.register_new_user/N, Accounts.create_login_token_for_user/N, nd_forgot_password_email/N. my_context.ex is a standard Phoenix style context, which in other words, is just a simple Elixir module that we treat as the public API for doing "things" concerning context.This is the real meat and potatoes and our app this is where we would read/write stuff to/from the database, where we'd write code to actually do stuff (as nebulous as that sounds). Everything within my_project/ is what I'd define as "application logic". To make things even worse, these files don't just contain any old Ecto code, but they go as far as to define new Ecto.Querys! In my mind, this is a huge no–no.īefore I get ahead of myself, I'll briefly explain how I interpret the different roles of the files shown in the directory structure example: When projects use libraries such as Absinthe (especially with Dataloader), problems usually end up compounding even more.įor (a surprisingly realistic) example's sake, imagine we're working on a standard Elixir project which uses Phoenix and Absinthe it'll usually end up having a directory structure not very different from this:Īnd while organization wise this is what we've come to expect when following standard Elixir conventions, the shocking thing is that every file I've listed here usually contains Ecto code. Unfortunately, on most projects I've worked on, Ecto code tends to be strewn all across the codebase with little regard for how/why it's being strewn about. One of the things I optimize for as a developer is separating my concerns whenever possible and creating boundaries/domains to isolate different "ideas" and "concepts" in whatever codebase I'm working on. Hopefully, that clears up the title of this post-today we'll be focusing on ways to make the most out of Ecto.Query specifically □ A Common Problem On a high level, Ecto is a collection of three different bits and pieces: Ecto.Schema, Ecto.Query, and Ecto.Changeset providing you with the means of mapping between Elixir structs and your database schema, an extremely robust query builder, and data validation library respectively. While Ecto isn't strictly and ORM, you can think about it doing the same basic job: you define schemas and queries which allow you to read/write records stored in your database of choice (most commonly Postgres) using standard Elixir structs. Obviously, for a much more fully-featured introduction to Ecto, I recommend jumping right in and reading the official docs/guide as well as Programming Ecto, but a brief and abridged overview I can do.Įcto is effectively the equivalent of an ORM that you'll find used in, or bundled with, popular web frameworks. I've written high-level posts about patterns I particularly like, such as railway–oriented programming and ways to make your Elixir code more composable, but today I felt like going on a little bit of a deep-dive into getting the most out of one of the most common Elixir libraries in common usage: Ecto! ELI5-Ecto A direct result of this led me to hone in on a set of Elixir patterns and conventions that I end up pulling into just about every single new project I get my hands on. When I was a consultant, one of the opportunities I was most grateful for was the chance to get myself knee's deep in a dizzying variety of Elixir codebases.
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |