Зачем мне создавать API с асинхронной/неблокирующей инфраструктурой?

Я рассматривал Play Framework как возможный кандидат на помощь в создании простого API. Тем не менее, Django Rest Framework (DRF) также кажется довольно сильным конкурентом.

Насколько я могу судить, DRF не рекламирует себя как асинхронную (или неблокирующую) структуру, такую как Play Framework, но меня интересует, имеет ли значение это даже. Ситуация, о которой я продолжаю думать, отправляет электронное письмо пользователю через Mandrill - я не хочу, чтобы мой API был увяз в ожидании API-интерфейса Mandrill, чтобы сообщить ему, было ли отправлено электронное письмо.

Таким образом, я думаю, что вопрос можно суммировать следующим образом: есть ли преимущество с точки зрения клиента, которое возникнет из-за моего создания API с асинхронной/неблокирующей инфраструктурой, такой как Play over DRF, или я пропущу точку?

Ответ 1

Я сторонник разработки Django REST (и пользователь), поэтому моя перспектива предвзята к этому.

Структура Django REST построена на Django, которая является синхронной платформой для веб-приложений. Если вы уже используете синхронную структуру, такую как Django, наличие синхронного API - это не проблема.

Теперь, только потому, что это синхронно, это не означает, что за один раз можно обрабатывать только один запрос. Большинство веб-серверов, которые обрабатывают приложения Django, могут обрабатывать несколько запросов, некоторые из них даже делают это несколько асинхронно для нескольких потоков. Обычно это не проблема, так как ваш веб-сервер обычно может обрабатывать множество параллельных запросов, даже если некоторые из них блокируются. И когда у вас есть длинные, блокирующие вызовы, как правило, не хотят, чтобы сделать в API - вы должны быть делегированием, что фоновые работникам как сельдерей или Resque.

Это не просто специфично для Django, многие из тех же принципов применяются к другим синхронным фреймворкам, таким как Rails и ASP.NET MVC. Если у вас есть длительные запросы, вы обычно должны делегировать работу другим процессам, а не поддерживать запрос. Обычно используется код ответа 202 для этих случаев.

Теперь это не обязательно означает, что асинхронные структуры бесполезны. Во время выполнения, например Node.js, большинство фреймворков обрабатывают запросы асинхронно. Не имеет смысла использовать синхронную структуру на этих языках, поэтому большинство библиотек построены как асинхронные.

То, что вы выбираете, зависит от инструментов, которые вы уже используете.

Ответ 2

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

Предположим, что следующий сценарий: запрос, который проверяет, является ли токен доступа FB/Google/etc действительным, а затем использует его для получения социального профиля вашего пользователя и затем возвращает что-то обратно.

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

Обратите внимание, что для решения этой "проблемы" вам не понадобится структура ANB, просто клиент HTTP ANB. Таким образом, вы должны больше смотреть на те операции, которые у вас будут в вашем приложении, и проверить, как будет работать ваша выбранная инфраструктура. Например: если ваше приложение состоит почти из операций DB CRUD, а драйвер DB блокируется (например, JDBC в Java и, вероятно, те, которые используются Django), это действительно не имеет большого значения, если структура асинхронна или нет, вы будете блокировать большинство времени на этом конкретном компоненте.

В вашем примере электронной почты, возможно, Django + Celery будет так же хорошо, как Play/Akka.

Ответ 3

Неасинхронные структуры обычно выполняют многолетние задачи, передавая их некоторому внешнему процессу (например, Resque/DelayedJob/sidekiq для разработки Rails)

просто хотел добавить, что Mandrill API поддерживает параметр async для отправки электронных писем. Вот что говорят их документы:

включить режим отправки фона, который оптимизирован для массовой отправки. В асинхронном режиме сообщения/отправка немедленно возвращают статус "очереди" для каждого получателя. Чтобы обрабатывать отклонения при отправке в асинхронный режим, настройте webhook для события "reject".

Поэтому в случае использования async, установленного в true, вы получите дескриптор сразу после выполнения вызова API, не дожидаясь отправки всех писем.

https://mandrillapp.com/api/docs/messages.JSON.html#method-send

(Я использовал JSON версию API как пример)