Keperluan:
Tangkap dan simpan badan JSON mentah tertentu permintaan laluan dan respons, dengan saiz data sekitar 1MB, tanpa menjejaskan tindak balas dengan ketara kali.
Middleware memintas setiap permintaan sebelum ia mencapai titik akhir dan respons sebelum ia pergi kepada pelanggan, membenarkan manipulasi data. Walau bagaimanapun, isu dengan menggunakan strim badan permintaan dalam perisian tengah ialah ia menjadi tidak tersedia untuk titik akhir hiliran. Oleh itu, kami akan menggunakan fungsi set_body() untuk menyediakannya.
Pengelogan boleh dilakukan menggunakan BackgroundTask, yang memastikan pengelogan berlaku selepas respons telah dibuat. dihantar kepada pelanggan, mengelakkan kelewatan dalam masa respons.
# Logging middleware async def some_middleware(request: Request, call_next): req_body = await request.body() await set_body(request, req_body) response = await call_next(request) # Body storage in RAM res_body = b'' async for chunk in response.body_iterator: res_body += chunk # Background logging task task = BackgroundTask(log_info, req_body, res_body) return Response(...) # Endpoint using middleware @app.post('/') async def main(payload: Dict): pass
Dengan mencipta kelas APIRoute tersuai, kami boleh mengawal badan permintaan dan tindak balas, mengehadkan penggunaannya kepada laluan tertentu melalui APIRouter.
Untuk respons besar (cth., media penstriman), laluan tersuai mungkin menghadapi masalah RAM atau kelewatan pihak pelanggan kerana membaca keseluruhan respons ke dalam RAM. Oleh itu, pertimbangkan untuk mengecualikan titik akhir sedemikian daripada laluan tersuai.
class LoggingRoute(APIRoute): async def custom_route_handler(request: Request) -> Response: req_body = await request.body() response = await original_route_handler(request) # Response handling based on type if isinstance(response, StreamingResponse): res_body = b'' async for item in response.body_iterator: res_body += item response = Response(...) else: response.body # Logging task task = BackgroundTask(log_info, req_body, response.body) response.background = task return response # Endpoint using custom APIRoute @router.post('/') async def main(payload: Dict): return payload
Kedua-dua pilihan menyediakan penyelesaian untuk permintaan pengelogan dan data tindak balas tanpa memberi kesan ketara pada masa tindak balas. Pilihan 1 membenarkan pengelogan umum, manakala Pilihan 2 menyediakan kawalan terperinci ke atas laluan yang memerlukan pembalakan.
Atas ialah kandungan terperinci Bagaimana untuk Mencatat Badan Permintaan/Respons HTTP Mentah dengan Cekap dalam FastAPI?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!