Adding Persistence as a Boundary Service

Look at some entanglements we may encounter when implementing the data layer and how we'll correct them in Mastery.

Challenges in implementing the data layer

In most Elixir projects, we inevitably begin our data layer with schemas and go from there. We tack on queries and services that use them to do the following:

  • Count

  • Save

  • Summarize things

The persistence framework Ecto makes that much easy. What emerges might be a unified API, but it will be one that combines the issues of boundary and core. The problem is that when we build a software like this, we take on too much at once. Our software doesn’t benefit from the separation of concerns, and each code reader is doomed to deal with too much complexity at once.

This approach is not a functional one. We’re making several commitments, often from the first few hours of developments:

  • Our database schemas will have the same shape as our projects.

  • Our core code will be thin, and our boundary code will be thick.

  • Often, we won’t have a separate core layer.

The data layer in mastery

Sometimes, this early database coupling mentioned above doesn’t work against us. In some cases, a struct exists purely as a conduit in a tightly coupled flow that passes straight from an API and directly into a database. Think audit records, for example.

Other times, it pays to think ahead. For example, building Mastery without considering Ecto integration led us to an interesting design. The foundational quiz design allows us to advance from question to question based on correct answers without the benefit of a database at all.

It turns out that the main things we might want to persist are quiz designs and responses. In this section, we’ll focus on persisting responses. Our persistence solution will allow us to save responses as a user takes a quiz. Then, admins can review reports of the responses to quizzes.

Managing concurrency

Get hands-on with 1200+ tech skills courses.