В чем разница синхронного режима FastAPI и классического синхронного приложения на Flask или Django?
Что проверяют
Понимаете ли вы, что FastAPI умеет и то и другое, и знаете ли, что происходит с обычной функцией внутри асинхронного сервера. Здесь чаще всего и путаются.
Как отвечать
FastAPI работает поверх ASGI, то есть внутри цикла событий. Обработчик, объявленный как async def, выполняется прямо в этом цикле. Обработчик, объявленный как обычный def, FastAPI выполняет в пуле потоков, чтобы блокирующий код не остановил цикл событий. Именно это и называют синхронным режимом.
Flask и Django в классическом варианте работают поверх WSGI: цикла событий нет вовсе, каждый запрос обрабатывается рабочим процессом или потоком от начала до конца.
Практическая разница:
- у FastAPI можно смешивать: тяжёлый синхронный вызов (драйвер базы без асинхронной поддержки, обработка изображения) объявляют обычным
def, и он не блокирует остальные запросы. Асинхронные ручки объявляютasync def; - самая опасная ошибка это блокирующий вызов внутри
async def: он останавливает весь цикл событий, и приложение перестаёт отвечать всем сразу. Такой код либо переводят на асинхронную библиотеку, либо уносят черезrun_in_threadpool; - пул потоков не бесконечен: если весь трафик идёт через синхронные ручки, FastAPI по поведению приближается к обычному WSGI-приложению и выигрыш пропадает;
- у Django с версии 3 есть асинхронные представления, но ORM асинхронна лишь частично, поэтому смешанный режим там тоже требует внимания.
Где спотыкаются
Пишут async def, а внутри вызывают requests.get или синхронный драйвер, и удивляются, что производительность хуже, чем у Flask.
Считают, что def в FastAPI это устаревший способ. Для блокирующего кода он как раз правильный.
Ждут ускорения вычислений от асинхронности: она помогает ожиданию, а не расчётам.