50 comments

[ 4.0 ms ] story [ 115 ms ] thread
The obvious solution is probably the best: Use an asynchronous framework (like node.js or asyncio) for the REST interface and wait for the completion of the task to return a response.

That process wouldn't handle all the details of the task, but it can wait for notification of the task via other means (celery, rabbitmq, redis, whatever...).

Personally I think REST is the best paradigm for most microservices. There is one exception: Data streams are inherently stateful and some kind of websocket/message passing is a lot more useful in that case.

How about batching stuff?
Yup. Batching is why we use queuing.
I am talking about how to send batch requests over REST
Aren't your requests going to be greater than the MTU anyways? Might as well send it whenever unless the work resulting from request processing can also be processed- which sounds like an application protocol.
I just love the way that consultancies are selling micro services as though it's some big thing that will revolutionise their business. Like big data or the cloud before it.

Looking at the article it seems that you've got an event driven system at the end with some components / pieces of code handling events e.g. Update inventory, inventory updated.

It seems to me that he just re-invented the enterprise service bus.
I disagree. The last version only had a message bus. Its an inversion of communication - instead of the Gateway knowing that it has to communicate to the other services, it just publishes an event and the inventory service knows that it has to listen to events from the Gateway (or even simpler: Just listen to 'inventory-updated' message).
Why is that different from an ESB?
IMHO ESBs have logic, transform events etc.
It doesn't have to. Could just be a series of queueing.
(comment deleted)
I agree. To me he just didn't talked anything about his topic. Althouth everything in this article does make sense, but what about the REST?
(comment deleted)
I somewhat agree. Truth is, you need marketing bullshit to convince upper management that doesn't know anything about tech to adopt new ideas.
(comment deleted)
"Don't use a SOA. Use microservices!"
(comment deleted)
From the headline I thought it was going to be trying to persuade us all that SOAP is better than REST.

...Phew! Turns out it's really "Is request-response the best Microservices architecture?"

SOAP really excited me when I did some training on it a while back - then, I read about REST.

Now, REST is all over my life, and I have literally never used SOAP since that training.

This article fails to mention that while, yes, REST may be too heavy for some services, there are other good options such as ZeroMQ for the messaging layer and also other transport formats such as Google's Protocol Buffers.
We use NServiceBus for our messaging architecture. It has a lot of the negatives covered in this.
I think you mean it handles a lot of the negatives.
It is rather a bold claim that REST is synchronous by nature. Synchronous only means less complexity, but it is by far not a standard. Considering the example in the article, calls to EmailService should be asynchronous and rather return '202 Accepted' instead of blocking.
every time there's a "REST" post on HN, I hope there's a comment out there that shows that not all hope is lost. Seems like today is not the day to lose hope either. Thanks :)
I think the problems identified with the architecture are being wrongly imputed on REST.

REST is synchronous in terms of request/reply, but that doesn't mean that higher-level actions must (or even should) be restricted to that cycle, so subprocesses like the notification should never have to block the stock update. Even if the requester needs to be informed about that, the stock updating mechanism should instead create a new Resource that tracks the notifications, and send the link to it so that the client can see how it's going.

But this wouldn't be necessary, because I agree that the stock updating shouldn't have to known about the notifications - but again, REST does not require it to!

The way to architect this using REST would be for the Notification Service to track how the stock of each product is currently. Since polling each product is inefficient, the stock manager could offer a feed that lists the latest stock updates, just like blogs do with posts.

This doesn't require a SPOF like a messaging bus, it doesn't suffer from the "service going pop" problem (since we've eliminated the dependency the inventory service had on the email system) and it's proven to work at a huge scale - the web.

> the stock manager could offer a feed

How does it differ from polling?

It doesn't, it differs from polling each product, since it provides a single resource for all of them.

An alternative would be for the Inventory system to allow the Email system to register a callback URL (aka Webhook) with it that gets called when the stock updates - allowing for push events while maintaining a decoupled architecture -, but that is only useful if the stock only gets updated sporadically, as you should still have a resource that can be polled, in case the Email system dies and then needs to check what happened when it was offline.

Polling a "show me all updates since X" endpoint is a reasonable approach that is loosely coupled and minimises the amount of transfer needed.
So you imply that the OP is defeating a straw man, right?
That polling endpoint is a message bus, just disguised as a REST endpoint.

You point about the SPOF is that you prefer distributed state inside the individual services over having events stored in the message bus? Then you're back to high coupling between the inventory manager and notifier, if the former is down the latter won't be able to send out any notifications.

If the inventory manager is down, no updates to the stock can occur, so what notifications are there to be sent? You can't eliminate coupling that arises from the semantics of the model, only obscure it by adding a layer of indirection.

The coupling that should be eliminated is the reverse, ie., the inventory being unable to update stock if the notifier is down, which the article claimed was inevitable using REST. I tried to show it isn't.

Regarding the message bus, I actually meant the broker, which is the SPOF being introduced in the proposed architecture.

It looks like ESB implementations from a decade back is being reasoned out into REST, like fitting a round peg in a square hole in many places in their diagrams
And finally reduced to TX monitor. Rinse and repeat.
IMHO, The use of incoming WebHooks handles the polling problem quite well. This makes REST over http one of the fastest and most elegant way to implement Microservices.
The only real problem I find with REST+microservices as an architecture is situations where the right framework for one of the microservices' jobs is not well-equipped for HTTP interactions.

Although it's always possible to knock something up to get the job done, a developer working in (e.g.) XSLT is not necessarily in his or her comfort zone when working with remote services, and that tends to cause delays and other headaches.

Otherwise, though, I'm all in favour of it as an architectural choice.

Discover async workflow you must.
REST is not the source of the problem being described in the article. The problem in the article is from bad application of REST.

I'm currently working at a startup that has about 15 microservices and there are a few different strategies that we use to solve the problems being described in this article:

We do use HTTP REST style requests when one service needs to fetch data from another service on the fly (usually in response to a user query), but we put in timeouts and proper error handling in case the dependent service is misbehaving. We strive for a "minimally broken" experience by allowing parts of the experience to degrade if one microservice is over capacity or broken, and have designed our response to allow us to return at least some data as long as part of the system is still working. This solves the "coupling", and "when microservices go pop" problem in the article.

REST should be considered to be the interface for anything requiring realtime feedback, but not everything does require immediate processing, or immediate feedback. So for example there is no reason why the notification service should block anything as depicted in the authors example. The notification service could accept a POST request to dispatch the notification and immediately return a 200 response after placing the notification onto a queue. Then it can process the queue in the background in a non blocking manner. At some later point in time if a delivery receipt is absolutely required there can be a callback hook into the other service.

REST makes for a very nice interface when used in an appropriate setting, but it isn't necessarily the best thing for all parts of the microservice communication. But neither is a service bus, or pipeline the best implementation for everything. The most masterfully designed backend will use REST when that is appropriate, and use a messaging/queue system when that is appropriate. Any non trivial backend will probably require both.

I might suggest that 202 is a better response in your example.
Good point! The fact that there is a 202 status code also goes to show that REST best practices allows for both synchronous and asynchronous use cases.
Oh, I 100% agree. I'm using a RESTish API right now to do things that are VERY async. There's no way you'd want to block a response while a VM was fired up and provisioned.
I don't know what the author of the article is reading, but the information I read says to use REST for your sync communication which require realtime feedback and are blocking anyway (like authentication). Then use message queue mechanisms for non-blocking/async stuff (e.g. Inventory update, packaging services, etc.). Amazon even has the services out of the box in sqs/sns but you can also use rabbitmq, zeromq, ironmq, or whatever.

Of course, above described approach is just an (opinionated) option and by no means the only, or best solution. Cockcroft defines a microservices architecture as a service-oriented architecture composed of loosely coupled elements that have bounded contexts. Loosely coupled meaning you can develop, update, and deploy separately. Bounded contexts meaning you can understand and update the microservice’s code without knowing anything about the internals of its peers. I think this is the best description as it leaves completely open how one would achieve this. In other words, as long as it works for your situation it's fine.

I liked Distributed Systems and the End of the API[0] by Chas Emerick. It discusses how HTTP (and other network-related) APIs are ill-suited for complex distributed systems and what can be done about that. The article talks mostly about CRDT and CALM, it does mention messaging queues as well.

[0] http://writings.quilt.org/2014/05/12/distributed-systems-and...

Author seems to be a simpleton to believe that REST architectures shall not have messaging/asynchronous modules. In real life no system can be built purely synchronous or asynchronous. REST apis makes it easy to build headless services that can talk to each other. That does not preclude asynchronous modules behind the facade.
This article doesn't seem to be representative of its title. If you're going to ask that question, you have to make comparisons. I would probably say no, because until most of the web supports HTTP/2.0, there's no server-push capability which makes a lot of things a pain in the ass.
(comment deleted)
Admittedly too many API's written with a RESTful interface are designed in such a way that async calls and callbacks aren't being taken advantage of, I think the only real thing REST misses out on, is what tech like RabbitMQ provide.

And I'm OK with those being separated - to me, the more choice I have around techs used provides more competition for cleaner, easier configuration of said tech.

Seems like an odd complaint. I don't see why asynchrony can't be delivered via REST-based micro-services.