Public Route Flagging¶
The decision for this functionality is to provide a list of endpoints that should be open to the public. This functionality is to facilitate the API Gateway pattern when planning for a microservice architecture.
Note
Usage of Insanic
’s router is exactly the
same as Sanic’s Router, so please refer to their documentation
for exact usage.
public_facing
usage¶
The only difference with Sanic’s Router is the routes_public
attribute that insanic.router.InsanicRouter
possesses.
To register a public route, we must decorate it with a
insanic.scopes.public_facing
decorator. This
is to “flag” certain views’ http request methods on whether
it should be public or not.
# in view.py
from sanic.response import json
from insanic.scopes import public_facing
from insanic.views import InsanicView
class GottaGoFastView(InsanicView):
@public_facing
def get(self, request, *args, **kwargs):
return json({"method": "get"})
@public_facing
def post(self, request, *args, **kwargs):
return json({"method": "post"})
def put(self, request, *args, **kwargs):
return json({})
@public_facing
def delete(self, request, *args, **kwargs):
return json({"method": "delete"})
# in app.py
from .views import GottaGoFastView
app = Insanic(__name__, __version__='0.0.0')
app.add_route(GottaGoFastView.as_view(), "/fast")
Note we only have 3 of the 4 methods decorated with
the public_facing
decorator.
When accessing the routes_public
attribute from
the InsanicRouter
, the application’s router is analyzed, iterating
through all the registered routes and route methods looking
for the public_facing
decorator where the
attribute scope
is attached with the
value "public"
.
In our example,
the methods ["GET", "POST", "DELETE"]
with the
route /fast are decorated.
>>> from example.app import app
>>> app.router
<insanic.router.InsanicRouter object at 0x100ff3e48>
>>> app.router.routes_public
{'^/fast$': {'public_methods': ['DELETE', 'GET', 'POST']}}
Additional Usages¶
The public_facing
decorator can be configured to only
accept a list of defined query parameters.
-
@
public_facing
(fn=None, *, params=None)¶ depending on usage can be used to validate query params
@public_facing
: Does not validate query params and anything is allowed.@public_facing()
: Same as above.@public_facing(params=[])
: does not allow any query_params. Returns 400 Bad Request Exception if any query params are included in the reuqest.@public_facing(params=['garbage'])
: Only allows query param “garbage”.- Parameters
fn (
Optional
[Callable
]) – view to decorateparams (
Optional
[Iterable
]) – params to validate against
- Raise
BadRequest if query_params doesn’t validate
- Return type
Callable
So if we modify our example above and run our code like so…
class GottaGoFastView(InsanicView):
@public_facing(params=["trash",])
def get(self, request, *args, **kwargs):
return json({"method": "get"})
$ curl "http://localhost:8000/fast?trash=1"
{"method":"get"}
$ curl -i "http://localhost:8000/fast?trash=1&garbage=1"
HTTP/1.1 400 Bad Request
Content-Length: 147
Content-Type: application/json
Connection: keep-alive
Keep-Alive: 60
{
"message":"Bad request.",
"description":"Invalid query params. Allowed: trash",
"error_code":{
"name":"insanic_invalid_query_params",
"value":999400
}
} # formatted for readability