16

I have been looking into the Play Framework as a possible candidate for helping me to build a simple API. However, the Django Rest Framework (DRF) also seems to be a pretty strong contenter.

As far as I can tell, the DRF does not advertise itself to be an asynchronous (or non-blocking) framework like the Play Framework does, but I am interested in whether or not this even matters. The situation that I keep thinking of is sending an email to a user via Mandrill -- I do not want my API to get bogged-down waiting for the Mandrill API to tell it whether or not the email was sent.

Thus, I think the question can be summarized like this: is there a benefit from the client's perspective that will result from my building an API with an asynchronous/non-blocking framework like Play over the DRF, or am I missing the point?

nmagerko
  • 6,586
  • 12
  • 46
  • 71
  • I'm hoping it won't be too subjective, since I'm not asking about which framework to use so much as I'm asking about which type of framework to use. Play/Django are just my examples, so please feel free to correct the tags if that's troubling you – nmagerko Jan 10 '15 at 22:25

4 Answers4

25

I'm a Django REST framework contributor (and user), so my perspective is biased towards that.

Django REST framework is built on Django, which is a synchronous framework for web applications. If you're already using a synchronous framework like Django, having a synchronous API is less of an issue.

Now, just because it is synchronous, that doesn't mean that only a single request can ever be handled at a time. Most web servers that are handling Django applications can handle multiple requests, some of theme even do it somewhat asynchronously across multiple threads. Usually this isn't actually an issue, as your web server can typically handle many concurrent requests, even if some of them are blocking. And when you have long, blocking calls you usually don't want that done within the API - you should be delegating that to background workers like Celery or Resque.

This isn't just specific to Django, many of the same principles apply to other synchronous frameworks like Rails and ASP.NET MVC. If you have long-running requests, you generally should be delegating work to other processes instead of holding up the request. It's common to use the 202 response code for these cases.

Now, that doesn't necessarily mean that asynchronous frameworks are useless. In runtimes such as Node.js, most frameworks handle requests asynchronously. It doesn't make sense to use a synchronous framework in these languages, so most libraries are built to be asynchronous.

What you choose very much depends on the tools that you are already using.

Community
  • 1
  • 1
Kevin Brown-Silva
  • 40,873
  • 40
  • 203
  • 237
  • Nice -- that makes a lot of sense. I wasn't really sure of how to handle those long-lasting processes, but you explained it well – nmagerko Jan 10 '15 at 23:04
  • This answer doesn't explain the difference between Async/Sync. The answer from Salem explains it very well and should be choosen as correct answer. – akkie Jan 12 '15 at 06:26
  • This answer responds to the question in a "here is why you usually don't need to worry" perspective, which appeared to appeal to the question asker's needs ("I am interested in whether or not this even matters"). I assumed that if they are asking about why one is better than the other, they typically know what the major difference is (blocking vs non-blocking). – Kevin Brown-Silva Jan 12 '15 at 14:42
  • 1
    Sorry, I've expressed myself wrong. I meant the assets and drawbacks between Sync/Async instead of the differences. Also there are other issues in your answer. Node.js isn't a language but rather a server side runtime environment based on the JS language. Node.js is completely async because it runs only on a single thread. And a non-async server that runs only on a single thread could only handle one request simultaneously. Async applications have generally a higher throughput, because they require fewer threads. And therefore they can handle a higher number of requests simultaneously. – akkie Jan 12 '15 at 16:32
  • I'll add also that ASP.NET MVC and WebAPI have full async capabilities. – Bon Jun 02 '15 at 17:25
5

Regarding the clients connecting to your app there should be no difference at all if your server uses asynchronous/non-blocking (ANB) technologies or not. But it may make a lot of difference in the number of requests your app can handle.

Suppose the following scenario: a request that checks if a FB/Google/etc access token is valid, and then uses it to get the social profile of your user and then returns something back.

If you are using a blocking http client in your server, during each of the 2 http requests the thread serving that request can be blocked a lot of time doing nothing. If you are using a non-blocking http client (like the one Play brings) while the HTTP request is made and the response comes back the thread can be used to do something else (ex: process part of another request).

Note that to solve this "problem" you wouldn't need an ANB framework, just an ANB http client. So you should look more to the kind of operations you will have in your app and check how your chosen framework will deal with them. For example: if your app consists almost of DB CRUD operations and the DB driver is blocking (like JDBC in Java and probably the ones used by Django) it really does not matter much if the framework is asynchronous or not, you will be blocking most of the time on that specific component.

In your email example probably Django+Celery will do just as fine as Play/Akka.

Salem
  • 12,808
  • 4
  • 34
  • 54
  • You need definitely an ANB framework, because you must handle the response returned from the API also in an aysnc manner. Otherwise your application would block the thread in any form. To guarantee your application to be fully async, every component must also be async. @see http://www.reactivemanifesto.org/ – akkie Jan 12 '15 at 07:54
2

Non async frameworks usually do long-running tasks passing them to some external process (e.g. Resque/DelayedJob/sidekiq for Rails development)

just wanted to add that Mandrill API supports async parameter for sending emails. Here is what's their docs are saying:

enable a background sending mode that is optimized for bulk sending. In async mode, messages/send will immediately return a status of "queued" for every recipient. To handle rejections when sending in async mode, set up a webhook for the 'reject' event.

So in case using async set to true you'll get handle immediately after performing a call to the API without waiting for all emails to be sent.

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

(I took JSON version of the API just as example)

Taryn
  • 242,637
  • 56
  • 362
  • 405
Pavlo Sirous
  • 161
  • 3
  • 1
    Ah, sure, thanks, for a pointing me to it. But I think I can't comment on non-mine posts yet, I'm just doing first steps here :) – Pavlo Sirous Jan 11 '15 at 00:53
0

The Django community is working on this thing for now if you want you can utilise the sync_to_async() adapter . It comes with some limitations and performance penalties but the community is still working on the same .

The link below will help you to work with the sync_to_async() adapter

https://docs.djangoproject.com/en/3.2/topics/async/

Jay Jain
  • 59
  • 7