HTTP¶
Creating an HTTP Interface – be it RESTful or otherwise – is done using the
BaseHttpController
class.
API
-
class
aioli.controller.
BaseHttpController
(pkg)[source]¶ HTTP API Controller
- Parameters
pkg – Attach to this package
- Variables
pkg – Parent Package
config – Package configuration
log – Controller logger
-
async
on_shutdown
()¶ Called when the Application is shutting down gracefully
-
async
on_startup
()¶ Called after the Package has been successfully attached to the Application
Example – Controller without route handlers
from aioli.controller import BaseHttpController
from .service import VisitService
class HttpController(BaseHttpController):
def __init__(self):
self.visit = VisitService()
self.log.debug("Guestbook opening")
async def on_startup(self):
self.log.debug(f"Guestbook opened at {self.package.path}")
async def on_request(self, request):
self.log.debug(f"Request received: {request}")
Routing¶
Route handlers are standard Python methods decorated with the @route.
API
-
aioli.controller.decorators.
route
(path, method, description=None)[source]¶ Prepares route registration, and performs handler injection.
- Parameters
path – Handler path, relative to application and package paths
method – HTTP Method
description – Endpoint description
- Returns
Route handler
Example – Route handler without transformation helpers
from aioli.controller import BaseHttpController, Method, route
from .service import VisitService
class Controller(BaseController):
def __init__(self):
self.visit = VisitService()
@route("/", Method.GET, "List of entries")
async def visits_get(self, request):
# Just pass along the query params as-is.
#
# Serialize and return whatever get_many() returns.
return await self.visit.get_many(**request.query_params)
Transformation¶
Transformation is implemented on route handlers using @takes and @returns. These decorators offer a simple yet powerful way of shaping and validating request data, while also making sure API endpoints only returns expected data.
This makes the API more secure and consistent.
Takes¶
The @takes decorator is used to instruct Aioli how to deserialize and validate parts of a request, and injects the resulting dictionaries as arguments to the decorated function.
API
-
aioli.controller.decorators.
takes
(props=None, **schemas)[source] Takes a list of schemas used to validate and transform parts of a request object. The selected parts are injected into the route handler as arguments.
- Parameters
props – List of Pluck targets
schemas – list of schemas (kwargs)
- Returns
Route handler
Example – Route handler making use of @takes
from aioli.controller import (
BaseHttpController, ParamsSchema, RequestProp,
Method, route, takes
)
from .service import VisitService
class Controller(BaseController):
def __init__(self):
self.visit = VisitService()
@route("/", Method.GET, "List of entries")
@takes(query=ParamsSchema)
async def visits_get(self, query):
# Transform and validate query params against ParamsSchema,
# then pass it along to get_many().
#
# Serialize and return whatever get_many() returns.
return serialize(await self.visit.get_many(**query))
Returns¶
The @returns decorator takes care of serializing the data returned by the route handler.
API
-
aioli.controller.decorators.
returns
(schema_cls=None, status=200, many=False)[source] Returns a transformed and serialized Response
- Parameters
schema_cls – Marshmallow.Schema class
status – Return status (on success)
many – Whether to return a list or single object
- Returns
Response
Example – Route handler making use of @takes and @returns
from aioli.controller import (
BaseHttpController, ParamsSchema, RequestProp,
Method, route, takes, returns
)
from .service import VisitService
class Controller(BaseController):
def __init__(self):
self.visit = VisitService()
@route("/", Method.GET, "List of entries")
@takes(query=ParamsSchema)
@returns(Visit, many=True)
async def visits_get(self, query):
# Transform and validate query params against ParamsSchema,
# then pass it along to get_many().
#
# Transform and dump the object returned from get_many() -
# according to the Visit schema, as a JSON encoded response
return await self.visit.get_many(**query)