# `Gno.CommitMiddleware`
[🔗](https://github.com/rdf-elixir/gno/blob/v0.1.0/lib/gno/commit_middleware.ex#L1)

Behaviour for pluggable components in the `Gno.Commit.Processor` pipeline.

The processor calls `c:handle_state/3` on each middleware at every state
transition (see the state machine in `Gno.Commit.Processor`). The callback
receives the new state atom, the middleware struct, and the processor, and
must return `{:ok, processor}` (optionally with an updated middleware) or
an error tuple to abort. On failure, `c:rollback/2` is called on all
middlewares that were already invoked.

The `:state` field on the middleware struct tracks the last state it was
called with, managed automatically by the processor.

## Defining a Middleware

Use `def_middleware/2` to define a Grax schema subclassing this module:

    defmodule MyMiddleware do
      use Gno.CommitMiddleware

      def_middleware MyNS.MyMiddleware do
        property :my_option, type: :string
      end

      @impl true
      def handle_state(:initialized, middleware, processor) do
        # custom logic
        {:ok, processor}
      end
    end

Middlewares are configured in the `Gno.CommitOperation` of a `Gno.Service`.
See `Gno.CommitLogger` for a built-in example.

# `middleware`

```elixir
@type middleware() :: %{
  :__struct__ =&gt; type(),
  :__id__ =&gt; term(),
  :state =&gt; term(),
  optional(atom()) =&gt; term()
}
```

# `t`

```elixir
@type t() :: %Gno.CommitMiddleware{
  __additional_statements__: term(),
  __id__: term(),
  state: term()
}
```

# `type`

```elixir
@type type() :: module()
```

# `handle_state`

```elixir
@callback handle_state(state :: atom(), middleware(), Gno.Commit.Processor.t()) ::
  {:ok, Gno.Commit.Processor.t()}
  | {:ok, Gno.Commit.Processor.t(), middleware()}
  | {:error, term()}
  | {:error, term(), Gno.Commit.Processor.t()}
```

# `rollback`

```elixir
@callback rollback(middleware(), Gno.Commit.Processor.t()) ::
  {:ok, Gno.Commit.Processor.t()}
  | {:ok, Gno.Commit.Processor.t(), middleware()}
  | {:error, term()}
  | {:error, term(), Gno.Commit.Processor.t()}
```

# `build`

# `build`

# `build!`

# `build!`

# `build_id`

# `def_middleware`
*macro* 

# `from`

```elixir
@spec from(Grax.Schema.t()) :: {:ok, t()} | {:error, any()}
```

# `from!`

```elixir
@spec from!(Grax.Schema.t()) :: t()
```

# `load`

```elixir
@spec load(
  RDF.Graph.t() | RDF.Description.t(),
  RDF.IRI.coercible() | RDF.BlankNode.t(),
  opts :: keyword()
) :: {:ok, t()} | {:error, any()}
```

# `load!`

```elixir
@spec load!(
  RDF.Graph.t() | RDF.Description.t(),
  RDF.IRI.coercible() | RDF.BlankNode.t(),
  opts :: keyword()
) :: t()
```

# `set_state`

# `type`

Returns the middleware module for the given IRI, or `nil` if not a middleware.

# `type?`

```elixir
@spec type?(module()) :: boolean()
```

Checks if the given `module` is a `Gno.CommitMiddleware`.

## Example

    iex> Gno.CommitMiddleware.type?(Gno.CommitLogger)
    true

    iex> Gno.CommitMiddleware.type?(Gno.Commit)
    false

    iex> Gno.CommitMiddleware.type?(NonExisting)
    false

---

*Consult [api-reference.md](api-reference.md) for complete listing*
