Use aiohttp
Getting started with building asynchronous web services
Why choose it?
In the world of asynchronous programming in Python,asyncioIt is the core framework for single-threaded concurrent I/O in the standard library. andaiohttpIt is the most mature asynchronous HTTP client + server double-ended library in this ecosystem. If you are used to writing synchronization frameworks such as Flask and Django, you may feel that high concurrency can only be achieved through multi-threading/multi-process; butaiohttpWithout these additional overheads, you can easily hold thousands of concurrent connections with a single thread.
Its main advantages:
- Lightweight and High Concurrency: Completely asynchronous and non-blocking, the memory usage is much lower than that of synchronous multi-threading solutions.
- Native growing connection support: Good support for real-time communication scenarios such as WebSocket and SSE.
- Full-duplex HTTP: It can be used as both a server and an HTTP client. A set of dependencies solves the front-end and back-end communication.
- ECO-FRIENDLY: with
asyncioDeeply integrated, compatible withuvloop、aiohttp-session、aiohttp-jinja2Wait for expansion.
It is very suitable for building I/O-intensive applications such as API gateways, real-time message push, asynchronous crawler services, and BFF layers.
Environment preparation
-
Basic Requirements Python 3.7 and above (
asyncioIntroduced after 3.7, the more conciseasync/awaitSyntax enhancement and more stable event loop implementation, it is recommended to go directly to 3.10+). -
Install aiohttp
If you need performance tuning later, you can install it together.uvloopandgunicorn, but the entry stage only requiresaiohttp。
The first asynchronous web server
Let's start with a minimal yet fully functional dual routing server:
/→ Returns an HTML homepage with title/{nickname}→ Return a personalized greeting based on the nickname in the URL
After running, the terminal will output something like:
Browser accesshttp://localhost:8080/andhttp://localhost:8080/Alice, you can see the corresponding greeting page.
Code details disassembly
1. Asynchronous processing function
- Must be
async def: This way the event loop can schedule it freely without blocking the main thread. - Forced reception
web.RequestObject: This object contains all request information - URL, request headers, Body, Cookie, etc. The processing logic starts here. - must be returned
web.Responseor its subclasses: A string or dictionary cannot be returned directly, the response object must be explicitly constructed. Also commonly used areweb.json_response()、web.FileResponse()wait.
2. Routing configuration
- Create application core:
web.Application()It is the "brain" of the entire service. - Add Route: Supported
web.get()、web.post()、web.put()、web.delete()、web.patch()and other methods, you can also useapp.router.add_route()Unified registration. - Batch vs Single: used in the example
add_routes()Batch addition is suitable when there are many routes; it can also be used for a small number of routesapp.router.add_get()Wait to be added separately. - URL placeholder:
{nickname}It is a dynamic part and will be automatically injected intorequest.match_info, you can also add regular constraints, such as{nickname:\w+}Matches only alphanumeric underscores.
3. Apply factory function
Specifically used in the examplemake_app()Instead of directly creating it globallyapp, which is a common practice in production environments:
- Isolated environment: You can create instances with different configurations for testing/development/production.
- Avoid global state: Avoid implicit dependencies caused by module-level variables.
- Easy to deploy and integrate: When working with servers such as Gunicorn and uWSGI, they will call this factory function to obtain application instances.
Run and quick test
1. Local startup
The console will print the listening address, pressCtrl+Cto stop the service.
2. Browser/command line access
- Browser
front page:
http://localhost:8080/
Dynamic page:http://localhost:8080/Alice - Command line
curltest
You will see the HTML content returned, indicating that the service is working properly.
Several commonly used advanced configurations
Customize the listening port and address
When developing, you may only want to access it locally, or avoid port conflicts:
Return JSON response quickly
aiohttpBuilt-injson_response, no need to manually setContent-Typeand serialization:
Add to routeweb.get("/api", handle_api)That's it, the client will receive a standard JSON string.
Add middleware
Middleware can perform pre/post unified logic on all requests, such as logging, permission verification, cross-domain settings, etc.:
Now each request will output the request path and final response code in the terminal, which is very convenient for debugging.
Production environment deployment suggestions
-
Do not use it directly
web.run_app()Online Its own server is only suitable for development and debugging, and its performance and stability are not enough to handle online traffic. -
Recommended combination: Gunicorn + uvloop
app:make_appExpresses fromappmodule importmake_appFactory function.GunicornUVLoopWebWorkerWill be used automaticallyuvloopReplacing the default event loop can improve performance by 2 to 4 times.
- The number of workers is generally set to 2 times the number of CPU cores (adjusted based on the I/O intensity of the business).
- Reverse proxy Another layer of Nginx is hung in front, which is responsible for static file processing, SSL termination, load balancing and request buffering, allowing the Python process to focus on dynamic logic.
Summarize
Through this tutorial, you have masteredaiohttpCore usage on the server side:
- How to define an asynchronous route and return an HTML/JSON response.
- How to use middleware to handle common logic.
- How to prepare deployment scenarios for production environments.
aiohttpIts capabilities go far beyond that, it also has built-in clients (can be used for asynchronous crawlers), WebSocket support, and rich third-party extensions (such as template engines, Session management). If your project requires lightweight, efficient, asynchronous-first web services,aiohttpWould be an excellent choice.

