EctoMiddleware.Repo behaviour (ecto_middleware v2.0.0)
View SourceEnables middleware support for Ecto.Repo modules.
Add use EctoMiddleware.Repo to your Repo to enable middleware pipelines for
database operations.
Setup
defmodule MyApp.Repo do
use Ecto.Repo, otp_app: :my_app
use EctoMiddleware.Repo
@impl EctoMiddleware.Repo
def middleware(action, resource) when is_insert(action, resource) do
[NormalizeEmail, HashPassword, AuditLog]
end
def middleware(action, resource) when is_delete(action, resource) do
[SoftDelete, AuditLog]
end
def middleware(_action, _resource) do
[AuditLog]
end
endDefining Middleware
Implement the middleware/2 callback to specify which middleware run for each operation.
Pattern Matching on Actions
The first argument is the action atom (function name without arity):
@impl EctoMiddleware.Repo
def middleware(:insert, _), do: [ValidateEmail]
def middleware(:get, _), do: [EnrichData]
def middleware(:delete, _), do: [SoftDelete]Available actions:
- Read:
:get,:get!,:get_by,:get_by!,:one,:one!,:all,:reload,:reload!,:preload - Write:
:insert,:insert!,:update,:update!,:delete,:delete!,:insert_or_update,:insert_or_update!
Pattern Matching on Resources
The second argument is the resource being operated on:
# Specific schema
def middleware(:insert, %User{}), do: [NormalizeEmail, HashPassword]
# Multiple schemas with same middleware
def middleware(:insert, %{__struct__: schema})
when schema in [User, Admin], do: [AuditLog]
# Changesets
def middleware(:update, %Ecto.Changeset{data: %User{}}), do: [CheckOwnership]Using Guards
You can use EctoMiddleware.Utils guards in your middleware/2 definitions:
@impl EctoMiddleware.Repo
def middleware(action, resource) when is_insert(action, resource) do
[SetCreatedAt, AuditLog]
end
def middleware(action, resource) when is_update(action, resource) do
[SetUpdatedAt, AuditLog]
end
def middleware(_action, _resource), do: []See EctoMiddleware.Utils for available guards.
Default Middleware
Always provide a catch-all clause:
def middleware(_action, _resource), do: []Middleware Execution
Middleware execute in the order specified. If any middleware returns {:halt, value},
execution stops immediately.
Summary
Functions
Enables the ability for a given Ecto.Repo to define and execute middleware.
Returns the configured middleware for the given repo.
Types
@type action() ::
:all
| :delete!
| :delete
| :get!
| :get
| :get_by!
| :get_by
| :insert!
| :insert
| :insert_or_update!
| :insert_or_update
| :one!
| :one
| :reload!
| :reload
| :preload
| :update!
| :update
@type middleware() :: module()
@type resource() :: %Ecto.Queryable{} | %Ecto.Changeset{} | %{__meta__: Ecto.Schema.Metadata} | {%Ecto.Queryable{}, Keyword.t()}
Callbacks
@callback middleware(action :: action(), resource :: resource()) :: [middleware()]
Functions
Enables the ability for a given Ecto.Repo to define and execute middleware.
@spec middleware(repo :: module(), action(), resource()) :: [middleware()]
Returns the configured middleware for the given repo.