# `Malla.Plugins.Request`
[🔗](https://github.com/netkubes/malla/blob/main/lib/malla/plugins/request.ex#L21)

Server-side plugin for handling incoming requests via the Malla request protocol.

This plugin defines the `c:malla_request/3` callback that is invoked when a
remote service makes a request using `Malla.Request.request/4`. It provides
the default implementation that creates tracing spans, checks service status,
executes the target function, and normalizes responses.

Plugins can override this callback to add cross-cutting concerns like
authentication, rate limiting, validation, and logging.

## Callback

- `c:malla_request/3` - Handle incoming request, return standardized response

## Default Implementation

The default `malla_request/3`:

1. Checks if service is running (returns error if not)
2. Creates "request-in" span (child of caller's "request-out" span)
3. Calls the target function with provided arguments
4. Normalizes response via `Malla.Status.public/1`
5. Emits `[:malla, :request, :in]` telemetry event
6. Returns standardized response

## Plugin Interception

Override `malla_request/3` to intercept requests:

```elixir
defmodule AuthPlugin do
  use Malla.Plugin

  defcb malla_request(fun, args, opts) do
    case verify_auth_token(opts[:auth_token]) do
      {:ok, user_id} ->
        # Add user_id to opts and continue
        {:cont, [fun, args, Keyword.put(opts, :user_id, user_id)]}

      {:error, _reason} ->
        {:error, :unauthorized}
    end
  end
end
```

## Response Protocol

Functions called via the request protocol must return:

- `:ok` | `:created` - Success without data
- `{:ok | :created, map | list}` - Success with data
- `{:error, term}` - Error (normalized via `Malla.Status`)
- `{:status, term}` - Custom status (normalized via `Malla.Status`)

## Callback Chain

When a request arrives:

```
malla_request/3 call
├─ ValidationPlugin.malla_request/3
├─ AuthPlugin.malla_request/3
├─ RateLimitPlugin.malla_request/3
└─ Default implementation
   ├─ Check service status
   ├─ Create "request-in" span
   ├─ Call target function
   ├─ Normalize response
   └─ Emit telemetry
```

## Telemetry

Emits `[:malla, :request, :in]` events with:
- Measurements: `:counter`, `:duration`
- Metadata: `:op`, `:result`, plus standard fields

## For Complete Documentation

See the [Request Handling](guides/08-distribution/04-request-handling.md) guide
for comprehensive examples including:
- Authentication plugins
- Rate limiting plugins
- Validation plugins
- Composing multiple plugins
- Conditional plugin logic
- Testing strategies

## See Also

- `Malla.Request` - Client-side request API
- `Malla.Plugin` - Plugin development guide
- `Malla.Status` - Response normalization

# `malla_request`
*optional* 

```elixir
@callback malla_request(atom(), list(), keyword()) ::
  {:ok | :created, map()}
  | {:error | :status, Malla.Status.t()}
  | {:error, :malla_service_not_available}
  | {:error, {:malla_rpc_error, any()}}
```

Default implementation for incoming requests.

* First it checks if service is running, returning `{:error, :malla_service_not_available}` in that case
* It tries to use base span_id in option `base_span_id`

---

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