Mutiny!

January 04, 2021

Tags: Elixir, Open Source, Programming

I’d like to announce our second open source Elixir library—Mutiny. It helps ensure that records you consider immutable from a business perspective behave as such in your database.

To start using Mutiny, simply add it to your mix.exs dependencies:

def deps do
  [
    {:mutiny, "~> 0.1.0"}
  ]
end

Let’s have a look at how Mutiny works in practice. Consider the following example.

You’re building an event sourcing feature into your Postgres-backed Elixir app, so you create a table using an Ecto migration that looks something like:

defmodule MyApp.Repo.Migrations.CreateEvents do
  use Ecto.Migration

  def change do
    create table("events") do
      add :type, :string
      add :data, :map
      add :last_viewed, :utc_datetime
    end
  end
end

You go on to begin capturing events, comfortable in the knowledge that you can use them in the future to reconstruct arbitrary application states. You are delighted with your work and move on to the next thing.

But then doubt begins to cloud your mind… If any one of the records in the events table are modified, the entire system you’ve built could be compromised. Sure, you’ve written application-level checks to ensure that event data isn’t changed once recorded, but your gut tells you need deeper assurance. Listen to your gut.

It’s common practice that crucial data be validated at the application level and at the database level. Mutiny is here to assist. It allows you to protect certain database tables or columns from updates by calling simple functions in your Ecto migrations. Let’s revisit our original migration, this time incorporating Mutiny:

defmodule MyApp.Repo.Migrations.CreateEvents do
  use Ecto.Migration
  use Mutiny, adapter: Mutiny.Adapters.Postgres

  def change do
    create table("events") do
      add :type, :string
      add :data, :map
      add :last_viewed, :utc_datetime
    end
  end

  table("events")
  |> protect([:type, :data])
  |> execute()
end

Now, the type and data columns are immutable—that is to say, unable to be UPDATEd once INSERTed. Any update commands that would modify those columns will now result in a database-level error. Thanks, gut!

Currently, PostgreSQL is the only supported database, but the library is designed in such a way that adding support for other databases, e.g. MySQL, SQL Server.

Check the docs for even more examples and, of course, feel free to open bug reports or enhancement PRs on GitHub.

Links

Nicholas Scheurich

Senior Developer

Scholar of arcane mysteries such as computer programming, game design, and the Vim text editor. Feed your Nick one cortado each morning to maintain its shiny coat and joie de vivre. he/him

let's talk.

Together we can make something great.

contact us about new work

Contact

225-407-4520

hello@newaperio.com

Social Media