diff --git a/docs/applications.md b/docs/applications.md index aac8592e..0092a3b4 100644 --- a/docs/applications.md +++ b/docs/applications.md @@ -17,6 +17,10 @@ app.mount('/static', StaticFiles(directory="static")) def homepage(request): return PlainTextResponse('Hello, world!') +@app.route('/user/me') +def user_me(request): + username = "John Doe" + return PlainTextResponse('Hello, %s!' % username) @app.route('/user/{username}') def user(request): diff --git a/docs/routing.md b/docs/routing.md index 8464a085..6d640ddb 100644 --- a/docs/routing.md +++ b/docs/routing.md @@ -43,3 +43,23 @@ app = Router([ The router will respond with "404 Not found" or "405 Method not allowed" responses for requests which do not match. + +Incoming paths are matched against each `Route` in order. + +If you need to have a `Route` with a fixed path that would also match a +`Route` with parameters you should add the `Route` with the fixed path first. + +For example, with an additional `Route` like: + +```python +Route('/users/me', endpoint=UserMe, methods=['GET']) +``` + +You should add that route for `/users/me` before the one for `/users/{username}`: + +```python +app = Router([ + Route('/users/me', endpoint=UserMe, methods=['GET']), + Route('/{username}', endpoint=User, methods=['GET']), +]) +``` diff --git a/tests/test_routing.py b/tests/test_routing.py index 8df5a039..712b796e 100644 --- a/tests/test_routing.py +++ b/tests/test_routing.py @@ -19,6 +19,16 @@ def user(request): return Response(content, media_type="text/plain") +def user_me(request): + content = "User fixed me" + return Response(content, media_type="text/plain") + + +def user_no_match(request): # pragma: no cover + content = "User fixed no match" + return Response(content, media_type="text/plain") + + def staticfiles(request): return Response("xxxxx", media_type="image/png") @@ -29,7 +39,12 @@ app = Router( Mount( "/users", app=Router( - [Route("/", endpoint=users), Route("/{username}", endpoint=user)] + [ + Route("/", endpoint=users), + Route("/me", endpoint=user_me), + Route("/{username}", endpoint=user), + Route("/nomatch", endpoint=user_no_match), + ] ), ), Mount("/static", app=staticfiles), @@ -103,6 +118,14 @@ def test_router(): assert response.status_code == 200 assert response.text == "User tomchristie" + response = client.get("/users/me") + assert response.status_code == 200 + assert response.text == "User fixed me" + + response = client.get("/users/nomatch") + assert response.status_code == 200 + assert response.text == "User nomatch" + response = client.get("/static/123") assert response.status_code == 200 assert response.text == "xxxxx"