Skip to Content
GuidesServer-side Middleware

Server-side Middleware

Middleware on the Emitter runs before any patch reaches the client. This is where you resolve placeholders, strip restricted fields, inject database values, and normalise formats.

The middleware signature

def my_middleware(patch: StreamingChunk, next_fn: Callable) -> None: # transform, drop, or fan out next_fn(patch) emitter.use(my_middleware)

Call next(patch) to pass through. Return without calling next to drop. Call next multiple times to fan out. Middleware runs in registration order.

Common patterns

Resolve placeholders

def resolve_images(patch, next_fn): if patch.op == 'add' and isinstance(patch.value, str): if patch.value.startswith('{{img:'): filename = patch.value[6:-2] patch = patch.replace(value=get_presigned_url(filename)) next_fn(patch) emitter.use(resolve_images)

Strip restricted fields

def strip_internal(patch, next_fn): if 'internal' not in patch.path: next_fn(patch) emitter.use(strip_internal)

Inject a database value

def inject_author(patch, next_fn): next_fn(patch) if patch.path == 'authorId' and patch.op == 'complete': author = db.get_user(patch.value) next_fn(StreamingChunk(path='author', value=author, op='add')) emitter.use(inject_author)

Middleware receives all four ops

Middleware sees add, append, insert, and complete patches. Drop a complete patch to suppress pathcomplete events for that path on the client.

Last updated on