# flare.grpc.interceptor

> A module of flare_mlake's API.

``flare.grpc.interceptor`` -- chainable unary server interceptors.

An interceptor wraps a :trait:`GrpcUnary` handler so cross-cutting
concerns (auth, logging, metrics, metadata injection) compose without
touching the business handler. Mojo has no first-class closures for a
``handler(ctx, req, next)`` shape, so interception is modeled as a
``before`` / ``after`` pair around the wrapped call:

* :meth:`GrpcInterceptor.before` runs first. Returning a
  :class:`GrpcUnaryReply` short-circuits the call (e.g. an auth
  interceptor rejecting with ``UNAUTHENTICATED``); returning the empty
  :class:`Optional` proceeds to the inner handler.
* :meth:`GrpcInterceptor.after` post-processes the inner handler's
  reply (e.g. attaching trailing metadata or remapping a status).

:class:`Intercepted` adapts ``(interceptor, handler)`` into a new
:trait:`GrpcUnary`, so chains nest:

    Intercepted(authI, Intercepted(logI, EchoHandler()))

The outermost interceptor's ``before`` runs first and its ``after``
runs last (standard onion ordering).

## Structs

### `Intercepted`

```mojo
struct Intercepted[I: GrpcInterceptor & Deinitable, H: GrpcUnary & Copyable & Deinitable]
```

Wrap ``handler`` with ``interceptor`` to form a new :trait:`GrpcUnary`. Nest to chain multiple interceptors.

Example:
```mojo
var svc = GrpcService(
    Intercepted(AuthInterceptor(token), EchoHandler())
)
```

Implements: `Copyable`, `GrpcUnary`, `Movable`

Fields:

- `interceptor: I`
- `handler: H`

#### `__init__`

```mojo
def __init__(out self, var interceptor: I, var handler: H)
```

#### `serve_unary`

```mojo
def serve_unary(mut self, ctx: GrpcCallContext, request_bytes: Span[UInt8]) -> GrpcUnaryReply
```

## Traits

### `GrpcInterceptor`

```mojo
undefined
```

A unary server interceptor: a ``before`` gate + an ``after`` post-processor around a wrapped :trait:`GrpcUnary` handler.

Implements: `Copyable`, `Movable`

#### `before`

```mojo
def before(mut self, ctx: GrpcCallContext, request_bytes: Span[UInt8]) -> Optional[GrpcUnaryReply]
```

Run before the inner handler. Return a reply to short-circuit the call, or the empty ``Optional`` to proceed.

#### `after`

```mojo
def after(mut self, ctx: GrpcCallContext, var reply: GrpcUnaryReply) -> GrpcUnaryReply
```

Run after the inner handler with its reply. Return the (possibly modified) reply.
