Skip to content

Do we need behaviours? #16

@SimonLab

Description

@SimonLab

The example is using behaviours to define the structure of the API interface:

@callback insert(struct) :: {:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
@callback get(integer) :: Ecto.Schema.t() | nil | no_return()
@callback all() :: [Ecto.Schema.t()]
@callback update(Ecto.Schema.t(), struct) ::
{:ok, Ecto.Schema.t()} | {:error, Ecto.Changeset.t()}
@callback get_history(Ecto.Schema.t()) :: [Ecto.Schema.t()] | no_return()

The implementation of the API is then done in the before_compile macro:

defmacro __before_compile__(_env) do
quote do
import Ecto.Query
def insert(attrs) do
%__MODULE__{}
|> __MODULE__.changeset(attrs)
|> Repo.insert()
end
def get(entry_id) do
sub =
from(
m in __MODULE__,
where: m.entry_id == ^entry_id,
order_by: [desc: :inserted_at],
limit: 1,
select: m
)
query = from(m in subquery(sub), where: not m.deleted, select: m)
Repo.one(query)
end

...
However I'm not sure behaviours are needed for the append only example.
From my understanding it makes sense to use behaviours when multiple modules need to provide the same functions but with a different logic of implemention. In our example only the AppendOnlyLog module is implementing the behaviours.

For a learning purpose it makes sense to see how behaviours works 👍 but I'm not sure if they provide a lot of values for this repository?

Should we still keep them to demonstrate how they can be used?

ref: https://elixir-lang.org/getting-started/typespecs-and-behaviours.html#behaviours

Metadata

Metadata

Assignees

No one assigned

    Labels

    discussquestionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions