Source code for fsh_lib.openapi

"""kiln's openapi-extension keys + their runtime constructor.

Routes the BE generates carry two custom extensions consumed by
the FE codegen layer:

* ``X_CACHE_KEY`` (``"x-cache-key"``) -- string identifying
  the TanStack Query key root the FE should use for this route's
  response cache.  Only emitted on read routes (any GET, plus the
  POST search endpoints that are semantically reads).  Its
  presence *is* the read signal: the FE generates ``useQuery`` /
  ``useSuspenseQuery`` wrappers for any GET or any route carrying
  a cache key, and treats everything else as a mutation -- so no
  separate "this is a query" extension is needed.
* ``X_RESOURCE`` (``"x-resource"``) -- the resource's *singular*
  slug (the model's snake name, e.g. ``"task"`` for the ``tasks``
  resource).  Stamped on *every* CRUD route (reads and writes
  alike, unlike ``X_CACHE_KEY``).  It's the canonical resource
  identity: the FE groups a resource's routes by it (to discover
  the CRUD SDK fns), and derives the saved-view ``resource_type``
  discriminator + default singular display label from it.  The
  plural cache namespace is the separate ``X_CACHE_KEY`` (e.g.
  ``"tasks"``); a read route carries both, which is how the FE
  bridges its plural config key to this singular identity.
* ``X_AUTH_ROLE`` (``"x-auth-role"``) -- ``"login"`` /
  ``"validate"`` / ``"logout"`` on the three auth-router routes.
  Lets the FE derive the auth SDK fns (and, off them, the session
  + credentials types) instead of naming them in fe.jsonnet.

:func:`construct_openapi_extra` builds a dict suitable for
FastAPI's ``openapi_extra=`` kwarg.  Generated handlers call it
inline so the extension keys live in exactly one place (this
module).  Hand-written handlers can use it the same way.
"""

from __future__ import annotations

X_CACHE_KEY = "x-cache-key"
X_RESOURCE = "x-resource"
X_AUTH_ROLE = "x-auth-role"


[docs] def construct_openapi_extra( *, cache_key: str | None = None, resource: str | None = None, auth_role: str | None = None, ) -> dict[str, object]: """Build the ``openapi_extra`` payload for a kiln-generated route. Args: cache_key: TanStack Query key root for the route's response cache. ``None`` skips the ``X_CACHE_KEY`` entry (right for write routes, which don't seed any cache). Its presence doubles as the read signal -- the FE treats any GET or any cache-keyed route as a query, so a read POST (a search endpoint) just sets this. resource: The resource's singular slug (model snake name, e.g. ``"task"``). ``None`` skips the ``X_RESOURCE`` entry. Stamped on both read and write routes; the canonical resource identity the FE groups routes by and derives the saved-view discriminator + label from. auth_role: ``"login"`` / ``"validate"`` / ``"logout"`` on an auth-router route. ``None`` skips the ``X_AUTH_ROLE`` entry. Lets the FE derive its auth SDK fns and the session / credentials types. Returns: A dict suitable for ``@router.<method>(..., openapi_extra=...)``. Empty when no argument is set. """ extra: dict[str, object] = {} if cache_key is not None: extra[X_CACHE_KEY] = cache_key if resource is not None: extra[X_RESOURCE] = resource if auth_role is not None: extra[X_AUTH_ROLE] = auth_role return extra