Boundary, Core, or Script?

Learn the role of Boundary, Core and Script in this lesson.

As we add new functions, we can think about them in this way: any function that deals with process machinery (think “input/output”) or uncertainty will go in the boundary, or context. Functions that have certainty and support the boundary go in the core. Scripts that support operational tasks, such as running tests, migrations, or seeds, live outside the lib codebase altogether. Let’s dive a little deeper.

The context API is for with

The context module is the API for a service. Now we know that the context module acts as the application’s boundary layer. Boundary layers handle uncertainty. This is why one of the responsibilities of the context is to manage the database interactions, for example—database requests can fail.

In Elixir, we can use with statements to manage code flow that contains uncertainty. The with/1 function allows us to compose a series of function calls while providing an option to execute if a given function’s return doesn’t match a corresponding expectation. Reach for with/1 when we can’t pipe our code cleanly.

So, we can think of the boundary as with-land––a place where we want to leverage the with/1 function, rather than the pipe operator, to compose code that deals with uncertainty. That’ advice some may find difficult to follow, let’s explore how it works in practice.

Many Elixir developers fall in love with the language based on the beautiful idea of composing with pipes, but the pipe operator often falls short of our needs in the context or boundary layer. Let’s take a look at why this is the case.

We’ll start by looking at an appropriate usage of the pipe operator in our application’s core. Here’s what a pipe that builds a query might look like:

Get hands-on with 1200+ tech skills courses.