Routing¶
spangle
provides simple and flexible routing powered by parse
.
Static routing¶
# routing.py
from spangle import Api
api = Api()
@api.route("/path/to/page")
class StaticRoute:
async def on_request(self, req, resp):
pass
Dynamic routing¶
You can get values from URL by using f-string style routing. To get params in a method, call use_params
.
# routing.py
@api.route("/path/to/{name}")
class DynamicRoute(object):
async def on_request(self, req, resp):
name = use_params()["name"]
# `spangle` tries to get a view from static routes first.
assert name != "page"
@api.route("/use/{multiple}/{allowed}")
class Multiple:
async def on_request(self, req, resp):
params = use_params()
assert "multiple" in params
assert "allowed" in params
Convert values¶
View methods accept URL arguments as str
by default. You can change this behavior to set converters.
# routing.py
# `default`, `int` and `float` are built-in converters.
# `str` is an alias of `default`.
@api.route("/use/{dynamic:int}")
class IntArg:
async def on_request(self, req, resp):
dynamic = use_params()["dynamic"]
assert isinstance(dynamic, int)
# `default` match does not contain slash(`/`).
# `*rest_string` converter matches any characters including slash.
@api.route("/{for_spa:*rest_string}")
@api.route("/")
class SpaView:
async def on_get(self, req, resp):
...
# You can define custom converters as `Dict[str,Callable]` .
def month(v:str) -> int:
m = int(v)
if not (1<=m<=12):
raise ValueError
@api.route("/articles-in-{m:month}", converters={"month":month})
class CustomConverter:
async def on_request(self, req, resp):
m = use_params()["m"]
assert 1<=m<=12
# You can use regular expression to set pattern to `converter.pattern` .
def regex(x):
return x
regex.pattern = r"[A-Za-z]+(/[A-Za-z]+)+"
# convert must start with `*` to include slash for its pattern.
@api.route("/accept/custom-pattern/{path:*regex}", converters={"*regex":regex})
class SlashRequired:
async def on_request(self, req, resp):
path = use_params()["path"]
assert "/" in path
See parse
for more details.
Routing Strategies¶
spangle
has 4 strategies about trailing slash.
"no_slash"
(default): always redirect from/route/
to/route
with308 PERMANENT_REDIRECT
."slash"
: always redirect from/route
to/route/
with308 PERMANENT_REDIRECT
."strict"
: distinct/route
from/route/
."clone"
: return same view between/route
and/route/
.
To change default strategy, create Api
instance with an argument like Api(routing="clone")
.
If you need to set different strategy against views, use route(view, routing="{strategy}")
.
@api.route("/flexible/rules", routing="clone")
class Strategy:
...