处理请求
lessweb.Bridge
类的对象支持add_route
方法,可以指定一类请求应该由哪个「端点(endpoint)」来处理。所谓端点,是一个异步函数。用lessweb.(get|post|put|delete|patch|rest)_mapping()
修饰这个异步函数,设置它绑定的方法和路径,它就成为了「端点(endpoint)」。
Endpoint的参数可以被框架“注入”,最简单的用法是用一个aiohttp.web.Request
类型的变量,就能获取各种请求参数。端点可以返回aiohttp.web.Response
对象,也可以直接返回dict|list
类型的变量,框架会序列化为JSON返回。
示例如下:
from lessweb import Bridge, get_mapping, post_mapping, rest_mapping
from aiohttp.web import Request
@rest_mapping('GET', '/pet/{pet_id}')
async def get_pet_detail(request: Request):
return {'pet_id': request.match_info['pet_id']}
@get_mapping('/pet')
async def get_pet_list(request: Request): #注意必须用async,否则访问时会报错
return {'name': request.query['name']}
@post_mapping('/pet')
async def create_pet(request: Request):
pet = await request.json()
return pet
if __name__ == '__main__':
bridge = Bridge()
bridge.add_route(get_pet_detail)
bridge.add_route(get_pet_list)
bridge.add_route(create_pet)
bridge.run_app()
自动搜索端点
实际项目中endpoint可能非常多,要用add_route
把每个endpoint调用一次是非常麻烦的。lessweb框架提供了根据包名(package name)自动搜索endpoint的能力。例如,我们先建立一个多文件的项目:
index.py
myapp/
myapp/endpoint/
myapp/endpoint/__init__.py
myapp/endpoint/get_pet_list.py
myapp/endpoint/create_pet.py
get_pet_detail.py文件内容为:
from lessweb import get_mapping
from aiohttp.web import Request
@get_mapping('/pet/{pet_id}')
async def get_pet_detail(request: Request):
return {'pet_id': request.match_info['pet_id']}
create_pet.py文件内容为:
from lessweb import post_mapping
from aiohttp.web import Request
@post_mapping('/pet')
async def create_pet(request: Request):
pet = await request.json()
return pet
index.py文件内容为:
from lessweb import Bridge
if __name__ == '__main__':
bridge = Bridge()
bridge.add_route_scan('myapp.endpoint')
bridge.run_app()
路径高级规则
lessweb的路径规则完全基于aiohttp的路径规则。
除了普通的固定路径,aiohttp支持有“可变资源”的路径。例如,一个路径为/a/{name}/c
的资源将匹配所有路径为/a/b/c
、/a/1/c
和/a/etc/c
的请求。变量部分是以{identifier}
的形式指定的,其中identifier部分的匹配值可以在以后的请求处理程序中用Request.match_info
获取。
默认情况下,每个{identifier}
都以正则表达式[^{}/]+
进行匹配。你也可以用{identifier:regex}
的形式指定一个自定义的正则。例如,上面例子中的get_pet_detail()
可做如下修改,以保证传入的pet_id
一定是数字:
@get_mapping('/pet/{pet_id:[0-9]+}')
async get_pet_detail(request: Request):
...