chapps.rest.routers.domains module
Domain record management implemented by factories
This module defines the various routes for manipulating Domain records. It
also defines the JoinAssoc
between Domain and User
tables.
Normally, each API route would be a decorated function or coroutine definition.
However, in this case, all the routes are created by factories from
common
. This makes it impossible to attach docstrings.
In order to provide basic documentation and some examples how to use those
common
API route coroutine factories, the routes will be described
below, as part of the api
docstring.
- chapps.rest.routers.domains.api = <fastapi.routing.APIRouter object>
FastAPI
APIRouter
object for domainsI will include a few examples here, rather than copy in all of the code. It seems important to provide and annotate at least a few examples in order to ensure that others, or my later self, will understand how this is all intended to work.
First, a simple example: the listing route. Domain objects, like just about any object represented this way, need to be listable by API so that they can be viewed by a user before being modified, linked to other objects, queried, destroyed, etc. In
chapps.rest.routers.common
, coroutine factories are defined to create all of these API routes.Listing Domains
Normally this would look like the route definitions in the
live
module, a decorated coroutine definition. Something like this:@api.get("/", response_model=DomainsResp) async def list_domains( item_id: int, qparams: dict = Depends(list_query_params) ): ... some code ... return DomainsResp.send(response, [...])
Instead, we invoke the decorator directly as a function. As a decorator-with-arguments, its return value is a closure which is the actual decorator. That real decorator expects our route function or coroutine as an argument. A factory from
common
is used to create that route coroutine.Therefore, the actual route is created on the
APIRouter
like so:api.get("/", response_model=DomainsResp)( list_items(Domain, response_model=DomainsResp) )
Please note that the main data model class is provided. All of the routes in this module regard Domain as the main data model. Because this route is for listing objects/records, it uses a response type which includes a list.
What about a route which makes changes, especially one which is sensitive to the model’s associations to other models? Things become a little bit more complicated, but not by much.
Updating Domains
To update a Domain, we need to receive the data within a Domain object, plus optionally a list of User IDs, to associate with the Domain instead of whatever is currently associated with the Domain.
api.put("/", response_model=DomainResp)( update_item(Domain, response_model=DomainResp, assoc=domain_join_assoc) )
In order to specify the associations to support in the route, a list of
JoinAssoc
objects may be provided to theassoc
parameter.(The following parameters and return type correspond to the
APIRouter
instance, which is callable. Sphinx autodoc makes it quite difficult to suppress this output.)- Parameters
scope (MutableMapping[str, Any]) –
receive (Callable[[], Awaitable[MutableMapping[str, Any]]]) –
send (Callable[[MutableMapping[str, Any]], Awaitable[None]]) –
- Return type
None
- chapps.rest.routers.domains.domain_join_assoc = [JoinAssoc(Domain, User, users, typing.List[int])]
Join association list for Domain objects