EctoFacade– handling multiple ecto repositories

Photo by henry perks on Unsplash

EctoFacade is an idea I got from researching how to handle multiple database setup. I found an issue from the ecto repository (link here) and got an idea from Jose to create ecto_facade — a little library that separates writes and reads for ecto repositories. This assumes that:

  1. Master ecto repository is used for writes
  2. Read repositories are repositories for replica databases

EctoFacade allows customizing what repositories should be used for read operations, what is master repository used for write operations, select algorithm by which read repository should be used for your next query and it does all that with the same Ecto.Repo interface you were using all along.

Why should I use it?

I made it with replication setup in mind so profits of such setup are profits of ecto_facade:

  1. Since there are more multiple databases that are replicated, you increase fault tolerance.
  2. Performance — most web applications are 90% reads, 10% writes. You can separate those actions and scale read replicas to handle additional traffic (or perhaps specific part of your application that is really database heavy)
  3. Separate of writes and reads
  4. It doesn’t really cost you anything — you use the same interface that Ecto.Repo provides

How do I use it in my app?

First, you need to create a module that will use EctoFacade.Repo with right options:

defmodule MyApp.FacadeRepo do
use EctoFacade.Repo,
master_repo: MyApp.MasterRepo,
read_repos: [MyApp.ReadReplicaOne, MyApp.ReadReplicaTwo],
algorithm: MyApp.Repo.ReadAlgorithm
end

Then you can just use it as any normal Ecto repo:

MyApp.FacadeRepo.all(MyApp.SomeSchema) # and other operations that you would do with ecto repo
from u in MyApp.Accounts.User, where: u.age > 18, limit: 1
|> MyApp.FacadeRepo.get()

How do I use it in tests?

Since most likely since Ecto 2.0 you will use Ecto.Adapters.SQL.Sandbox you will need a single repository for read and writes. This is really easy — just configure your ecto_facade in the test environment without any read repositories — it will use master repository by default then for all your read operations.

Contributions

If you have any propositions how to improve ecto_facade, just create an issue on GitHub and we will see from there. :)

You can find GitHub here.