LINUX.ORG.RU

Выбор перспективного фреймворка для REST Api

 , ,


2

3

Всем привет. Пытаюсь выбрать «идеальный» бэкенд-фреймворк для REST Api либо на Питоне, либо на Go. Конкретные кейсы не озвучу, потому что скажешь «блог» - посоветуют Вордпресс. Выбор между этими языками странный, согласен, но все же. Выбираю между aiohttp (Python), fastapi (Python) и gin/gonic (Golang). Синхронщину типа Flask (Python) я отмёл, потому что, мне кажется, в плане производительности их в 2019 уже не особо перспективно использовать. Тем более, что особой разницы в плане «удобства» разработки, что на Flask, что на aiohttp нет (оба микрофреймворки), а второй явно шустрее. В Django много лишнего, а drf для него медленный очень - тоже отмел. Помогите определиться с выбором, на чем из перечисленного на текущий момент пилить REST Api более перспективно и удобно сайты среднего размера различной тематики у которых фронтенд в виде SPA? Ну, скажем, современный интернет-магазин. Есть ли вообще смысл юзать питоновскую асинхронщину нынче, когда есть го?

В приоритете - гармония между производительностью полученного проекта, моей производительностью в плане скорости разработки и потреблении ресурсов сервера.

В приоритете - гармония между производительностью полученного проекта, моей производительностью в плане скорости разработки и потреблении ресурсов сервера.

GraphQL

anonymous ()

fastapi кал. там pydantic в качестве валидатора используется. в marshmallow мы можем сделать load(partial=True) и обязательные поля будут проигнорированны. в пидоте нужно создавать отдельные схемы для всех операций. + неудобство отладки. я вот не нашел способа отлаживать приложение, запускаемое через uvicorn в vscode (если кто знает скиньте пример launch. json и tasks. json). с асинхронщиной вообще беда: нет нормальных orm для postgres. для mysql есть, монги есть, а для слона нет (у меня на работе все под это дерьмо завязано, люди застряли в конце нулевых, начале 10-х, когда postgres был топом). на flask писать в разы удобнее пока тебя не попросят прикрутить оповещение по веб-сокетам. это что касается python. go кал. работа с json боль. orm нет. если не останавливает, то флаг в руки. посмотри в сторону node. js, postgraphile.

tz4678 ()
Ответ на: комментарий от paganmind

это для тех у кого нет отвращения к pascal case. в c# есть linq. linq == ненависть. есть неплохой orm entity. да он быстр, но скорость разработки на нем не очень большая. нет модульной архитектуры. node js лучше.

tz4678 ()

ЭЭЭ?? а что мешает тебя писать на фласке используя асинхронные вызовы и асинхронный же wsgi сервер? недостаточно по хипстерски и мало сахара? дык тогда сразу на го надо

genryRar ★★ ()

Хотел было посоветовать, но требование go и python делает мой совет, неактуальным. Так вот если это будет Node.js, то однозначно fastify, который можно назвать вообще самым лучших фреймворков с которыми я работал, хотя бы потому, что он не пытается резко навязать тебе свою парадигму (ну или потому-что наши парадигмы достаточно близки)

anonymous_sama ★★★★★ ()
Ответ на: комментарий от genryRar

Асинхронные вызовы во фласке - это как костыль. А производительность Фласка сопоставима с той же Джангой, что в принципе не становится аргументом юзать Фласк вместо нее. Разве что только ради Алхимии.

На гошке я пишу микросервисы, но не в восторге от самого языка. От его синтаксиса кровь из глаз к вечеру течь начинает: код состоит на 80% из if err != nil {return err}. Работа с json - отдельная тема. Когда начинаешь писать на Питоне после го - это как глоток свежего воздуха. Да, в го нормальная многопоточность, строгая типизация, высокая производительность и прочие преимущества, но сам язык... Да и писать более-менее крупное рест апи достаточно неудобно - проект превращается в набор велосипедов, потому что нет особо «лучших» практик и прочего. Кто как хочет - так и делает.

dimuska139 ()
Ответ на: комментарий от dimuska139

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

про го - ну тоже вкусовщина. у меня глаза кровоточат от проверок на err и писать чтото серьезное я на нем не хочу и обьективных причин делать это не вижу. но есть парочка товарищей, которых проверка на err не напрягают и они вполне успешно им пользуются.

genryRar ★★ ()
Ответ на: комментарий от Deleted

да не переживай ты так, насамом деле всем пофиг, что ты подворачиваеш штаны и пьеш свое смузи - главное штоб не навязывал свою религию другим ;) мир, дружба, жевачка

genryRar ★★ ()

Если с нуля будешь пилить, то бери голанг + prisma. Фреймворки там не нужны.

Есть ли вообще смысл юзать питоновскую асинхронщину нынче, когда есть го?

Нет.

no-such-file ★★★★★ ()
Ответ на: комментарий от dimuska139

Пруфы? Tornado изначально создавался в FriendFeed, чтобы лопатить 10к+ запросов в сек. Tornado и раньше шустрый был, а с тех пор как стало можно использовать его с нативными корутинами, стало ещё лучше. В актуальной мажорной ветке уже от самописного event loop-а отказались в tornado, заменили на враппер вокруг event loop-а из asyncio.

xxblx ★★★ ()
Ответ на: комментарий от genryRar

Да вот изначально и возникла идея создать тут вопрос как раз из-за проверок на err в Go. Сама суть языка неплоха - эдакий простецкий бэкенд-язык с многопоточностью, строгой типизацией и высокой производительностью, но такие его особенности вызывают дикое отвращение. А когда проект разрастается, качество кода, несмотря на мои усилия, на мой взгляд, оставляет желать лучшего.

Во-первых, нет особо стандартов каких-то в написании веб-приложений на го, во-вторых, всякие if err != nil везде и отвратная работа с json. Но если выбирать между ним и Flask, я бы все равно выбрал гошный фреймворк какой-нибудь. Чисто из-за потоков и производительности. Ну и удобства деплоя - делаешь билд, получаешь исполнимый файл и все. Беда в том, что их (вменяемых фреймворков для го) выбор невелик: по сути gin/gonic да beego. А монополия в ORM в виде Gorm тоже удручает, потому что Gorm так себе (сугубо мое личное мнение) - это вам не Doctrine или SQLalchemy. А гошников спросишь на эту тему - отвечают, что Gorm не нужен, фреймворки не нужны и т.п. - еще и гордятся своим говнокодом, где зачастую даже миграции БД не реализованы. Я лет 8 тому назад так на нативном пхп писал - возвращаться к тем временам ради производительности и потоков желания мало. Странно, что гошники считают это нормой.

P.s. Костыльность заключается в том,что Flask сам по себе изначально синхронный. Поэтому впиливать суда асинхронный код - костыль, потому что проще взять любой другой асинхронный микрофреймворк - трудозатраты будут такими же, а велосипеда уже не будет. Это как в Джанго впиливать django-channels. Можно, но зачем?

dimuska139 ()
Ответ на: комментарий от dimuska139

Советую смотреть в код тестов в следующий раз перед тем как ссылаться на них. Мне-то все равно чем ты будешь пользоваться в своих проектах, хоть bottle.py, хоть джангой, но вот в сильном коллективе в будущем может неловко получиться с такими «пруфами».

См. какие корутины в каких app.py в сравнении асинхронных фреймворков использованы, какие библиотеки для работы с базой. Возникает резонный вопрос про знание техчасти тем, кто это самое сравнение проводил.

xxblx ★★★ ()
Ответ на: комментарий от tz4678

ну такто я не про ayncio говорил, а про асинхронный wsgi сервер, тотже pywsgi или манкипатчинг веркзеуга. вопрос то ТС сформулировал какбэ немножко не «как мне фласк юзать с асинкио». я и тригенрулся - если ему нравится фласк, но он не отказывается от него изза «синхронности» то это чуш. мне фласк не нравится, такой проблемы для меня не стояло никогда ^^

ну а если очень хочется всетаки асинкио и сахар - почемубы не сделать декоратор или примитивное расширение для фласка в 5 строк, которое будет оборачивать в экзекутор само.

хотя последнее решение таксебе, это уже какието костыли. нужен асинкио - юзай аиошттп, если такого требования нет, вполне можно и фласк асинхронно поюзать. тотже gevent молотит ничуть не хуже (в половине бенчмарков еще и лучше).

genryRar ★★ ()
Ответ на: комментарий от dimuska139

извиняюсь, а что за нагрузка такая планируется, что сил пистона заведомо будет нехватать? даже с pypy? не часто им приходится пользоваться (мы обычно если нужна скорость или цитон или пайтран используем) но когда необходимость возникла - никаких проблем запустить бекенд через него не было и скорость после прогрева там сумасшедшая получилась - для вебни как помне джит самое то.

про го спасибо - всегда интересно получить фидбек «с той стороны» ^^

про синхронность фласка не понял - фласк создавался, когда встроенной асинхронщины в питоне небыло, но она прекрасно реализовывалась через асинхронные сервера. сам фласк в рамках этой модели никак не ограничивает асинхронность. но да, если конкретно фласк тебе ненужен (ну малоли) то сейчас нет причин им пользоваться. но это ведь не значит что «нельзя» или «костыль», вполне себе работает и как по мне неменее удобно чем async\await

genryRar ★★ ()
Ответ на: комментарий от xxblx

За совет спасибо. Я ничего насчет статьи на Хабре не могу сказать, но по поводу второй ссылки: а что с пруфом не так? Там есть ссылка на подробное описание тестов - «For a more detailed description of the requirements, see the Source Code and Requirements section.» (Source Code and Requirements - это ссылка). А там есть ссылка на репозиторий тестов на Гитхабе (зависимости можно увидеть там же, соответственно). Что с ними не так? Почему мне должно быть неловко? Я считаю, что пруф достаточно авторитетный.

dimuska139 ()
Ответ на: комментарий от genryRar

Никакой нагрузки не планируется, я поэтому изначально и написал «Конкретные кейсы не озвучу, потому что скажешь «блог» - посоветуют Вордпресс.». Просто при схожести каких-либо фреймворков в плане количества готовых реализованных в них решений (я имею в виду не сравнивая микрофреймворки с фулстек-фреймворками с кучей батареек) вполне логично отдать предпочтение тому, что пошустрее, несмотря на то, что основные проблемы скорости веб-бекендов обычно кроются не тут. Причем вне зависимости от того, что за проект делаешь. Потому что скорость важна везде. Даже если у тебя блог, то на ранжирование в результатах выдачи скорость загрузки страницы играет достаточно большую роль.

dimuska139 ()
Ответ на: комментарий от dimuska139

на мой взгляд логичнее отдать предпочтение инструменту, который позволит решить задачу с максимальной эффективностью. и производительность тут лишь один из критериев, приоритет которого определяется какраз задачей.
ато для крестов вон тоже есть вебфреймворки, почемуж тогда сразу не на нем?
но решать тебе. просто удивился столь странной логической цепочке «хочу на пистоне, и вродебы скорости наверное хватит - но го быстрее - буду писать на го» :)

genryRar ★★ ()

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

Синхронщину типа Flask (Python) я отмёл, потому что, мне кажется, в плане производительности их в 2019 уже не особо перспективно использовать

Основные тормоза это получение данных из базы данных, а не сама работа python/go. Это надо помнить при написании асинхронного приложения.

dicos ()
Ответ на: комментарий от genryRar

Да тут дело даже не столько в скорости, сколько еще в удобстве деплоя, количестве потребляемой памяти и т.п. В гошке билд делаешь, получаешь бинарь и запускаешь его в виде демона. И все, не нужны всякие uwsgi, gunicorn и т.п. Иногда некоторые вещи удобно делать отдельным потоком, например, отправку почты или, скажем, запись в лог. Конечно, для отправки почты правильнее запилить очередь вообще - и тут не важно, на го ты писал бэкенд, питоне или пхп. Но очередь тоже жрать просит, а если у тебя пет-проект с гигом озу на сервере, то вся эта связка с тем же докером выжрет почти всю оперативку в ноль. А если тебе нужно просто отправить письмо восстановления пароля и все? Проще горутину запустить - и все. Экономия памяти сервера явная ж. При использовании асинхронных фреймворков питона, вроде, тоже можно юзеру отдать http ответ, а уже в фоне слать имейл.

Поправьте, если я не прав и живу в мире иллюзий. :)

dimuska139 ()
Ответ на: комментарий от dicos

Это само собой, но та же сериализация в том же django-rest-framework или Джанговская ормка работает достаточно медленно, например. Возможно, это не сопоставимо с операциями работы с бд зачастую, но суммарно эти накладные расходы могут быть ощутимы. Особенно, когда данные берутся не из базы, а из кеша, а потом идет их сериализация в коде.

dimuska139 ()
Ответ на: комментарий от dimuska139

А если тебе нужно просто отправить письмо восстановления пароля и все? Проще горутину запустить - и все. Экономия памяти сервера явная ж. При использовании асинхронных фреймворков питона, вроде, тоже можно юзеру отдать http ответ, а уже в фоне слать имейл.

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

В гошке билд делаешь, получаешь бинарь и запускаешь его в виде демона.

помне это такойсебе плюс, но если тебе так удобнее - можно и питон в бинарь собирать через cx_Freeze.

я не пытаюсь тебя переубедить, если что ;) ля своей петни используй хоть делфи, к чему больше душа лежит. нато она и петня.

genryRar ★★ ()
Ответ на: комментарий от genryRar

Да я, собственно, и не имею четкой позиции, на чем лучше делать апиху в 2019. Поэтому и сделал эту тему.

Недостатки го (для меня): сам синтаксис языка, отсутствие вменяемого ORM (gorm с той же sqlalchemy) рядом не стоял, постоянное ощущение что пилишь велосипед. Плюсы: надежность (обработка ошибок, считаю, удобна - всегда знаешь, что и где отлавливаешь). Ну и низкое потребление памяти, что для петни является реально большим плюсом.

Недостатки питона: жрет он памяти достаточно много. По производительности все же в последнее время никуда не сдвинулся особо. Сделана ориентация на ml, а в вебе, на мой взгляд, стал сдавать позиции совсем с выходом пхп7. Такое ощущение, что язык развивается очень медленно. Очень многие до сих пор сидят на 2.6, то есть сообщество элементарно раскололось на 2 лагеря. Плюсы перечислять не буду, питон просто элементарно приятнее, чем го сам по себе.

dimuska139 ()
Ответ на: комментарий от dimuska139

ну вообщемто все так, однако если в питоне начинает нехватать скорости - за редким исключением это не проблема. есть uvloop, pypy, cython, numbla и еще какаято новая приблуда.
а с памятью да, тухло.

кстати, а пчм рест? просто изза популярности или под задачу хорошо подходит?

genryRar ★★ ()
Ответ на: комментарий от genryRar

Не в популярности дело и не в конкретных задачах. Я просто считаю, что этот подход наиболее правильный - и пришел к нему вполне осознанно, а не на волне моды совать рест везде. В последние годы фронтенд-разработка сильно ушла вперед - и фулстек-разработчикам все сложнее и сложнее поддерживать знания в актуальном состоянии в столь широкой форме. Поэтому удобно фронтенд отдать фронтенд-разрабам, а бэк - бэкенд-разрабам. Так удобней разрабатывать, проще тестировать. Интерфейсы в виде SPA более шустрые, более отзывчивые, более современные и приятные. Использование рест позволяет переписать бэкенд без каких-либо проблем, совершенно не затрагивая интерфейс и наоборот. Можно легко как заменить фреймворк, так и вовсе переписать с одного языка на другой. А попробуй НЕ рест монолит переписать или сильно отрефакторить - офигеешь. Особенно когда он без тестов. При использовании рест проект, как ни странно, сильно упрощается, становится более качественным, очевидным и приятным. Его проще покрывать тестами и отлаживать.

dimuska139 ()
Ответ на: комментарий от dimuska139

А попробуй НЕ рест монолит переписать или сильно отрефакторить - офигеешь.

монолитность не имеет никакого отношения к ресту же :)

Поэтому удобно фронтенд отдать фронтенд-разрабам, а бэк - бэкенд-разрабам.

опять таки никакого отношения к ресту не имеет :)

Использование рест позволяет переписать бэкенд без каких-либо проблем, совершенно не затрагивая интерфейс и наоборот.

не только не имеет отношения к ресту, но и возникает проблемка - если нужны не-HTTP протоколы (например переход на websocket или rsocket), а у вас сейчас рест - это адище, ибо рест полностью завязан на http (в отличии от всех остальных протоколов доступа к апи).

При использовании рест проект становится более очевидным

шта, извините? этож вы сейчас не про коды ошибок, да? иначе откуда у нас тонны велосипедов, десятки статей «какже правильно использовать коды ошибок» противоречащих друг другу и регулярно встречающаяся в различных апи передача кодов ошибок отдельно и статус 200 на все.

рест хорош в конкретных проектах, где все можно представить в виде работы над ресурсами, причем без хитровыдуманной логики работы с этими ресурсами, ну и там где неважна скорость реакции, дуплексная связь. в остальных случаях он явно не на своем месте и иных причин, кроме трендовости\утенковости, этому нет.
Вы ведь пробовали иные варианты реализации апи?

genryRar ★★ ()
Ответ на: комментарий от genryRar

монолитность не имеет никакого отношения к ресту же :)

Да, не совсем правильно выразился. Я под монолитом подразумевал приложение, сохраняющее состояние между запросами. То есть всякие сессии и т.п. подходы, которые имеют место в подавляющем большинстве монолитов. Вся эта мешанина усложняет рефакторинг и возможность дробить приложение на микросервисы, если это требуется.

опять таки никакого отношения к ресту не имеет :)

Ну как бы имеет. Первое требование к архитектуре REST-приложений - это отделение клиента от сервера. Что само по себе дает четкое разделение задач между фронтенд-разработчиками и бэкенд. Разве нет?

не только не имеет отношения к ресту…

Да вот как раз имеет-таки. Опять-таки по причине отделения клиента от сервера, позволяющее их рассматривать, как отдельные приложения вообще. Насчет внедрения веб-сокетов в рест приложение ничего не могу сказать.

шта, извините? этож вы сейчас не про коды ошибок, да? иначе откуда у нас тонны велосипедов, десятки статей «какже правильно использовать коды ошибок» противоречащих друг другу и регулярно встречающаяся в различных апи передача кодов ошибок отдельно и статус 200 на все.

Почему статус 200 на все? 201-created, 204-результат delete запроса, 400 - ошибка во входных данных (в боди в json поле errors с соответствием key => value полей и ошибок в них). И так далее. Какие-то кастомные коды ошибок прямо body в большинстве случаев не нужны. По крайней мере, я такой подход. Да, я считаю, что при использовании рест проект становится более простым и очевидным.

Я совершенно не горю желанием спорить, но то, что я написал, кроме разве что некорректного высказывания про монолит, следует из Википедии. Свое мнение, если что, я не навязываю, просто мне так удобнее. Если вы считаете, что рест не панацея, то я согласен с этим и нигде обратного не утверждал.

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

dimuska139 ()

пилить REST Api

Умирающие убожество.

более перспективно

Перспективность и рест - вещи несовместимое.

удобно

Тоже.

фронтенд в виде SPA?

Использовать адекватный транспорт и протокол. http, рест и всё с этим связанное - убожество, которое уже умирает и скоро умрёт.

В приоритете - гармония между производительностью полученного проекта, моей производительностью в плане скорости разработки и потреблении ресурсов сервера.

Фундаментальной проблемой является синхронизация интерфейса между клиентов/сервером. Тут нужен либо кодоген, либо общий язык. Именно поэтому нынче модны всякие GraphQL и прочие третьи языки, на которых описываются модели данных.

От всех этих проблем можно уйти используя общую кодовую базу. Но, в такое может только какой-нибудь жаваскрипт. Существуют какие-то попытки, но всё это мало кому интересно и мало где применимо.

Единственное, что применимо - это дарт. Дарт умеет в ffi с js/c(частично), это почти жс, общая кодовая база с мобилками, может собираться в бинарники(снапшоты). Скоро сможет компилироваться. По всех параметрам куда лучше го. Разве что он мёртвый и готовых либ там мало.

NishiragiShintaro ()