@@ -151,17 +151,6 @@ family are plain shortcuts for :meth:`UrlDispatcher.add_route`.
151151 Introduce resources.
152152
153153
154- .. _aiohttp-web-custom-resource :
155-
156- Custom resource implementation
157- ------------------------------
158-
159- To register custom resource use :meth: `UrlDispatcher.register_resource `.
160- Resource instance must implement `AbstractResource ` interface.
161-
162- .. versionadded :: 1.2.1
163-
164-
165154.. _aiohttp-web-variable-handler :
166155
167156Variable Resources
@@ -331,6 +320,69 @@ viewed using the :meth:`UrlDispatcher.named_resources` method::
331320 :meth: `UrlDispatcher.resources ` instead of
332321 :meth: `UrlDispatcher.named_routes ` / :meth: `UrlDispatcher.routes `.
333322
323+
324+ Alternative ways for registering routes
325+ ---------------------------------------
326+
327+ Code examples shown above use *imperative * style for adding new
328+ routes: they call ``app.router.add_get(...) `` etc.
329+
330+ There are two alternatives: route tables and route decorators.
331+
332+ Route tables look like Django way::
333+
334+ async def handle_get(request):
335+ ...
336+
337+
338+ async def handle_post(request):
339+ ...
340+
341+ app.router.add_routes([web.get('/get', handle_get),
342+ web.post('/post', handle_post),
343+
344+
345+ The snippet calls :meth: `~aiohttp.web.UrlDispather.add_routes ` to
346+ register a list of *route definitions * (:class: `aiohttp.web.RouteDef `
347+ instances) created by :func: `aiohttp.web.get ` or
348+ :func: `aiohttp.web.post ` functions.
349+
350+ .. seealso :: :ref:`aiohttp-web-route-def` reference.
351+
352+ Route decorators are closer to Flask approach::
353+
354+ routes = web.RouteTableDef()
355+
356+ @routes.get('/get')
357+ async def handle_get(request):
358+ ...
359+
360+
361+ @routes.post('/post')
362+ async def handle_post(request):
363+ ...
364+
365+ app.router.add_routes(routes)
366+
367+ The example creates a :class: `aiohttp.web.RouteTableDef ` container first.
368+
369+ The container is a list-like object with additional decorators
370+ :meth: `aiohttp.web.RouteTableDef.get `,
371+ :meth: `aiohttp.web.RouteTableDef.post ` etc. for registering new
372+ routes.
373+
374+ After filling the container
375+ :meth: `~aiohttp.web.UrlDispather.add_routes ` is used for adding
376+ registered *route definitions * into application's router.
377+
378+ .. seealso :: :ref:`aiohttp-web-route-table-def` reference.
379+
380+ All tree ways (imperative calls, route tables and decorators) are
381+ equivalent, you could use what do you prefer or even mix them on your
382+ own.
383+
384+ .. versionadded :: 2.3
385+
334386Custom Routing Criteria
335387-----------------------
336388
@@ -483,58 +535,6 @@ third-party library, :mod:`aiohttp_session`, that adds *session* support::
483535 web.run_app(make_app())
484536
485537
486- .. _aiohttp-web-expect-header :
487-
488- *Expect * Header
489- ---------------
490-
491- :mod: `aiohttp.web ` supports *Expect * header. By default it sends
492- ``HTTP/1.1 100 Continue `` line to client, or raises
493- :exc: `HTTPExpectationFailed ` if header value is not equal to
494- "100-continue". It is possible to specify custom *Expect * header
495- handler on per route basis. This handler gets called if *Expect *
496- header exist in request after receiving all headers and before
497- processing application's :ref: `aiohttp-web-middlewares ` and
498- route handler. Handler can return *None *, in that case the request
499- processing continues as usual. If handler returns an instance of class
500- :class: `StreamResponse `, *request handler * uses it as response. Also
501- handler can raise a subclass of :exc: `HTTPException `. In this case all
502- further processing will not happen and client will receive appropriate
503- http response.
504-
505- .. note ::
506- A server that does not understand or is unable to comply with any of the
507- expectation values in the Expect field of a request MUST respond with
508- appropriate error status. The server MUST respond with a 417
509- (Expectation Failed) status if any of the expectations cannot be met or,
510- if there are other problems with the request, some other 4xx status.
511-
512- http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.20
513-
514- If all checks pass, the custom handler *must * write a *HTTP/1.1 100 Continue *
515- status code before returning.
516-
517- The following example shows how to setup a custom handler for the *Expect *
518- header::
519-
520- async def check_auth(request):
521- if request.version != aiohttp.HttpVersion11:
522- return
523-
524- if request.headers.get('EXPECT') != '100-continue':
525- raise HTTPExpectationFailed(text="Unknown Expect: %s" % expect)
526-
527- if request.headers.get('AUTHORIZATION') is None:
528- raise HTTPForbidden()
529-
530- request.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n")
531-
532- async def hello(request):
533- return web.Response(body=b"Hello, world")
534-
535- app = web.Application()
536- app.router.add_get('/', hello, expect_handler=check_auth)
537-
538538.. _aiohttp-web-forms :
539539
540540HTTP Forms
@@ -1108,6 +1108,69 @@ To manual mode switch :meth:`~StreamResponse.set_tcp_cork` and
11081108be helpful for better streaming control for example.
11091109
11101110
1111+ .. _aiohttp-web-expect-header :
1112+
1113+ *Expect * Header
1114+ ---------------
1115+
1116+ :mod: `aiohttp.web ` supports *Expect * header. By default it sends
1117+ ``HTTP/1.1 100 Continue `` line to client, or raises
1118+ :exc: `HTTPExpectationFailed ` if header value is not equal to
1119+ "100-continue". It is possible to specify custom *Expect * header
1120+ handler on per route basis. This handler gets called if *Expect *
1121+ header exist in request after receiving all headers and before
1122+ processing application's :ref: `aiohttp-web-middlewares ` and
1123+ route handler. Handler can return *None *, in that case the request
1124+ processing continues as usual. If handler returns an instance of class
1125+ :class: `StreamResponse `, *request handler * uses it as response. Also
1126+ handler can raise a subclass of :exc: `HTTPException `. In this case all
1127+ further processing will not happen and client will receive appropriate
1128+ http response.
1129+
1130+ .. note ::
1131+ A server that does not understand or is unable to comply with any of the
1132+ expectation values in the Expect field of a request MUST respond with
1133+ appropriate error status. The server MUST respond with a 417
1134+ (Expectation Failed) status if any of the expectations cannot be met or,
1135+ if there are other problems with the request, some other 4xx status.
1136+
1137+ http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.20
1138+
1139+ If all checks pass, the custom handler *must * write a *HTTP/1.1 100 Continue *
1140+ status code before returning.
1141+
1142+ The following example shows how to setup a custom handler for the *Expect *
1143+ header::
1144+
1145+ async def check_auth(request):
1146+ if request.version != aiohttp.HttpVersion11:
1147+ return
1148+
1149+ if request.headers.get('EXPECT') != '100-continue':
1150+ raise HTTPExpectationFailed(text="Unknown Expect: %s" % expect)
1151+
1152+ if request.headers.get('AUTHORIZATION') is None:
1153+ raise HTTPForbidden()
1154+
1155+ request.transport.write(b"HTTP/1.1 100 Continue\r\n\r\n")
1156+
1157+ async def hello(request):
1158+ return web.Response(body=b"Hello, world")
1159+
1160+ app = web.Application()
1161+ app.router.add_get('/', hello, expect_handler=check_auth)
1162+
1163+ .. _aiohttp-web-custom-resource :
1164+
1165+ Custom resource implementation
1166+ ------------------------------
1167+
1168+ To register custom resource use :meth: `UrlDispatcher.register_resource `.
1169+ Resource instance must implement `AbstractResource ` interface.
1170+
1171+ .. versionadded :: 1.2.1
1172+
1173+
11111174.. _aiohttp-web-graceful-shutdown :
11121175
11131176Graceful shutdown
0 commit comments