Всем привет, меня зовут Абай. Я являюсь Back-End разработчиком в 13LAB.

После прочтения интересной статьи со сравнением NodeJS и FastAPI, у меня появилось желание высказать свое личное мнение об удобстве разработки бэкенда на Python и фреймворке FastAPI. В данной статье будут описаны мои личные ощущения, поэтому мое мнение может отличаться от вашего.

FastAPI - является легковесным асинхронным фреймворком для Python, который используют преимущественно для разработки API-сервисов. Фреймворк довольно молодой и существует всего лишь 5 лет. До 2021 года не имел большой популярности по сравнению с Flask и Django, но на данный момент уже стал намного востребованнее, что его стали использовать в МAANG компаниях (к примеру, Netflix). Создателем фреймворка является Sebastián Ramírez Montaño, разработав на базе микрофреймворка Starlette, в отличии от которого предоставляет больший функционал из коробки, что освобождает разработчиков от некоторой рутины.

Плюсы разработки на FastAPI:

  1. Скорость работы. FastAPI обходит все Python-фреймворки по производительности (по данным TechEmpower)

     Бенчмаркинг с TechEmpower
    Бенчмаркинг с TechEmpower
  2. Гибкость на уровне Flask. У вас нет какой-либо утвержденной архитектуры, что дает волю вашей фантазии и различным подходам разработки, по сравнению с Django (использует MVC), в котором проект часто превращается в странную субстанцию из папок в папках.

  3. Автоматическая OpenAPI документация. В Django и Flask, нужно подключать отдельные пакеты и создавать специальные классы для подключения документации к ним. Еще замечу, что к Flask очень мало информации на эту тему, а сама версия документации зачастую устаревшая. На Django это сделать уже намного проще, но также занимает некоторое время, в то же время в FastAPI все доступно из коробки.

  4. Асинхронность. FastAPI использует ASGI-сервера по умолчанию, когда в том же Django нужно заниматься конфигурацией приложения с WSGI на ASGI, что занимает достаточно времени. Flask, к сожалению, не поддерживает асинхронность и работает лишь под WSGI.

  5. Встроенная валидация данных. Недавно вышла поддержка Pydantic V2 в FastAPI, что ускоряет валидацию данных в 20 раз. Pydantic предоставляет готовые типы данных для валидации email, uuid, url и т.д. Вместо того, чтобы вручную писать проверки для содержимого json-файлов и обрабатывать ошибки валидации, он автоматизирует эти процессы.

  6. Проработанная документация. В случае других фреймворков и библиотек приходится смотреть обучающие ролики из-за невнятной и громоздкой документации. У FastAPI таких проблем нет. Документация разделена на две части: для новичков и более продвинутых разработчиков. В ней большое количество примеров и лучших практик, что также является несомненным плюсом.

Минусы разработки на FastAPI:

  1. Мало информации. Это относится к JWT-токенам, S3 облачным хранилищам, сборке образа в Docker Compose и другим технологиям. Зачастую вам приходится изучать реализации на других фреймворках, так как информации не все всегда бывает достаточно в документации FastAPI.

  2. Плохая реализация асинхронных библиотек. У асинхронных библиотек на Python зачастую нечитабельная документация, из-за чего их подключении к FastAPI иногда отнимает кучу времени. Часто это проявляется, когда приходится использовать асинхронные драйвера или ORM для баз данных. В AsyncIOMotor (асинхронный драйвер для MongoDB) не работают тайпхинты, которые подсказывают, как прописываются методы, из-за чего неоднократно возвращаешься к документации, потому, что не можешь правильно написать название метода. В AsyncSQLAlchemy (асихронный ORM для SQL) есть неприятный момент в том, что метод .query() не является асинхронным и приходится прописывать все через.execute(),как и другие методы:.select(), .update(), .delete(), хотя это уже больше дело привычки.

  3. Нет удобной смены root_path. У меня никак не получалось его сменить с (“/”) на (“/api”), сколько не пытался прописывать в атрибутах самого объекта и менять настройки uvicorn. Единственный рабочий метод, который я обнаружил, это создавать объект класса APIRouter() и прописывать внутри атрибута prefix нужное вам значение, чтоб изменить начальную точку, но это надо делать во всех объектах, что очень неудобно.

    # Как работает
    app = FastAPI(docs_url="/api/docs", redoc_url="/api/redoc", openapi_url="/api/openapi.json")
    
    # Как хотелось бы
    app = FastAPI(root_path = "/api")
  4. Трудоустройство в СНГ. Вакансий для разработчиков на FastAPI все же мало на рынке, по сравнению с давно устоявшимися фреймворками, как Django, DRF и Flask, из-за чего проблематично найти работу. Понятное дело, что никто не хочет переписывать старые монолиты и сервисы, поскольку недостаточно хороших специалистов на рынке, которые умеют на нем писать.

Подведем итоги. FastAPI является одним из самых производительных и комфортных инструментов для веб-разработки на Python, а основные его недостатки проявляются лишь в отсутствии нужного количества информации, из-за его новизны.

Спасибо за помощь в оформлении статьи - @zaurbbb

Комментарии (17)


  1. Nabusteam
    17.07.2023 22:12
    +1

    Flask уже апологет. Но фаст апи норм движется. Обрастет скоро всем, что нужно. Вопрос времени.


  1. whoisking
    17.07.2023 22:12
    +2

    по сравнению с Django (использует MVC), в котором проект часто превращается в странную субстанцию из папок в папках

    Тут вообще не понял. В 2023 появились какие-то другие способы организации проектов?


    1. LaggerIsME Автор
      17.07.2023 22:12

      Чистая архитектура?


      1. whoisking
        17.07.2023 22:12

        Что чистая архитектура? У вас куда-то исчезнут файлы с директориями? Что за решение, какую пользу оно даёт, как это выглядит?


        1. LaggerIsME Автор
          17.07.2023 22:12

          А что непонятного про структуру джанго? Ты не можешь ее изначально менять, ты должен ее придерживаться. В FastAPI же можешь писать, как хочешь, что тебя не ставит в какие-либо рамки.


          1. whoisking
            17.07.2023 22:12

            Фокус был на "странная субстанция из папок в папках". Вы в фастапи где файлы храните? Не в папках? А в чём? И почему вы уверены, что для внешнего наблюдателя ваша организация файлов в фастапи не будет выглядеть некоей субстанцией?


            1. LaggerIsME Автор
              17.07.2023 22:12

              Сравните изначальный темплейт Джанго и ФастАПИ и скажите на каком намного проще и быстрее начать писать новичку. Я не думаю, что наличие одного main.py, да и папки models выглядит также непонятно, как начальный проект в Django.


              1. rSedoy
                17.07.2023 22:12

                "и скажите на каком намного проще и быстрее начать писать новичку" вот как раз новичкам нужна структура как в Django, иначе всё плохо будет, еще со времен Flask это проверенно, ну не могут они сразу, без опыта, нормально это сделать.


                1. LaggerIsME Автор
                  17.07.2023 22:12

                  Ну как говорится, что кому ближе. Я лично начинал с Фласка и мне он понравился больше Джанго, но тут все зависит опять же от личных предпочтений.


  1. economist75
    17.07.2023 22:12

    В скрине бенча от TechEmpower фреймворк Tornado представлен дважды - вверху и внизу списка (6-м и 27-м "номером"). А что, удобно. Надо взять на вооружение. Каждый найдет то что наилучшим образом совпадет с его т. зр.


    1. avkritsky
      17.07.2023 22:12
      +1

      На самом сайте можно просмотреть подробности каждого "испытуемого". В частности, Торнадо с 6 строчки использует uvloop. Тогда как Торнадо с 27 строчки его не использует (или он не указан) и указан pypy2, вместо py3 с 6 строчки. Разные тесты и компоненты.


    1. Jolt
      17.07.2023 22:12
      +2

      на django больно смотреть


  1. pcdesign
    17.07.2023 22:12
    +2

    Flask, к сожалению, не поддерживает асинхронность и работает лишь под WSGI

    https://flask.palletsprojects.com/en/2.3.x/async-await/


    1. LaggerIsME Автор
      17.07.2023 22:12

      Интересно, даже не знал. Flask стабильно работает на ASGI и как по удобству? А то смущает немного пункт в документации, что лучше использовать Quart.


      1. pcdesign
        17.07.2023 22:12
        +2

        Эту фичу в 2021 году добавили. Те роуты, которые надо сделать асинхронными можно сделать асинхронными, а какие-то роуты сделать обычными.

        Мне кажется в большинстве случаев, асинхронность не очень то и нужна.

        Деплоил обычным nginx + gunicorn + gevent


  1. Ryav
    17.07.2023 22:12

    Не понял по 3 минусу, в чём вопрос? Я делаю вот так:

    router = APIRouter(prefix="/api/v1")
    auth_router = APIRouter()  # обычно импортируется из другого файла
    router.include_router(auth_router, tags=["auth"])
    
    app.include_router(router)  # это уже привязка к приложению


    1. LaggerIsME Автор
      17.07.2023 22:12

      Я делаю точно также, но я в том плане, что нельзя изменить сразу через root_path корневой путь. Вам все равно также придется переписывать пути на OpenAPI документацию и т.д., чтоб они не были доступны по /docs, /redoc, /openapi.json.