In the Grandmetric development team, we regularly use the aiohttp library as our asynchronous HTTP client/server for Python. This D&C shows how to use and register request handlers in the aiohttp application.
In particular, we would like to focus on paths order. That’s why you might find other solutions simplified for the sake of our example.
Let’s consider the oversimplified aiohttp server, which has two endpoints:
We can mock the data using simple Python’s dict:
data = [ {"name": "Andy"}, {"name": "Bob"}, {"name": "Charlie"}, {"name": "Duncan"}, ]
To handle each of the endpoints, we can use one of the two methods listed below.
import json from aiohttp import web async def get_single(request): instance_id = int(request.match_info['id']) return web.Response(body=json.dumps(data[instance_id]), content_type="application/json")
import json import json from aiohttp import web async def get_all(request): return web.Response(body=json.dumps(data), content_type="application/json")
After that, we can simply register endpoints and run the application:
app = web.Application() app.add_routes([web.get('/names/all', get_all)]) app.add_routes([web.get('/names/{id}', get_single)]) web.run_app(app)
This is where we might consider two variants.
It is important to notice that the first pattern that matches the path will be used to handle a particular request.
In the first scenario /names/{id} pattern will match requests like:
/names/0 /names/2 /names/any_string /names/all
As you can see, it catches everything, so it shadows the second route i.e. /names/all, and its handler will never be reached.
The second scenario, when /names/all comes first solves this issue as it matches only literal /names/all, and other paths are matched by the second route.
Of course, this is not the only solution to this problem, as in this particular case, we could register the path to match only digits as follows:
app.add_routes([web.get('/names/{id:\d+}', get_single)])
As you could see in the example above, it’s important which order of registering paths in the aiohttp library you choose. The best way to avoid issues related to this is to define the path as narrow as possible, e.g., by adding regex as an identifier.
Take a look at this complete GIST example and play around with the order of the routes.
Leave a Reply