5 ms·
Anybody here who used this pattern in practice and found out it is not as good as this article portrays it?
by wilgertvelinga 8y ago
Anybody here who used this pattern in practice and found out it is not as good as this article portrays it?
- politelemon 8y agoThese patterns are geospecific. They are only known to work within the vicinity of the town of Theory. You may find several deviations and compromises that occur outside this region, though the intention is often to emulate a loose collection of (sometimes) consensus based best practices.
- icebraining 8y agoThey work just fine for millions of services; they're called "websites". When you click on a link/button that starts a long running task, you often get redirected to a status page which refreshes (polling), and which has a link to cancel.
- skinnyarms 8y agoIt sounds pretty sensible to me, I filed it away for next time I need to do something like this.
- gravypod 8y agoThis layout is similar to something I've done in production. In my use case we don't support stopping of jobs and I return job completion status in aggregate. I also avoid confusion in status codes and implementation by separating my resources for requests of a resource and the resource itself into different endpoints. POST /<resource>-requests { ... } GET /<resouce>-requests [ { "id": <id>, "status": "complete", ... "url": "/<resource>/<id>" } It all comes down to your queue processing system and making sure it's sensibly configured. For long running jobs (1+hr) the stack we use at work (Laravel/Lumen) come very poorly configured.
- twodave 8y agoBottom line is if you’re doing this via REST and not using web sockets (which is fine, of course!) then you’re going to end up in a polling situation. That’s the important thing to think about. I had a bulk export job that ran similar to this, minus a lot of the frills. On the initial POST you get back a token that would allow you to poll the job status. Until you went to download the (often several GB) payload, all requests were extremely fast. At most we would insert a single record into a DB and queue a tiny object onto the message bus. In the status poll it was a simple key lookup. In my experience nobody seriously tries to figure out how to use your API by calling it, they’ll prefer to look at your code examples and documentation. Nobody is going to build a generic-enough REST client to make all the HATEOAS crap matter for their workflow. In my view it’s a waste of time, but maybe others have found it measurably useful?
- geezerjay 8y ago> Bottom line is if you’re doing this via REST and not using web sockets Websockets is not a viable solution for this problem because long-running processes are long-running, and it would make no sense to keep a connection up for minutes/hours just to poll the process status.
- twodave 8y agoSure, good point. I’d argue this isn’t exactly black and white but you won’t find me defending web sockets for many applications at all anyway.
- scarface74 8y agoI have. I used it when creating a long running report. While polling, the end point would also return a status update - the percentage complete and where it was in the process.
- Lazare 8y agoI'm using it, it works fine. Two things to keep in mind though: First, the post recommends that "once resource is created, API should respond with 303 See Other status code on all the subsequent requests to the queued task." That's a great idea, but NOT if you're, say, polling from a web browser via AJAX hoping to get some snippet of data to display to the end user. Browsers take 3xx codes seriously, so they will transparently follow the redirect. This is probably not what you had in mind, so you'll end up needing to use a 2xx code. And that brings us to the second point: This post is basically "here's how to do something pretty basic in a RESTful and semantic way". That's fine! But as above, sometimes that's not feasible, and even when it is feasible, you could also just...you know...not be RESTful. REST isn't magic, and it's not a synonym for "an HTTP based API". And sometimes all you need is an HTTP API. Yes, using a 202 Created response with a Location header for where to poll is clever and (I think) elegant. But it's functionally identical to a 200 Okay response with the URL in the body. Similarly, a link to the cancellation method when you poll is cool; you'll feel smug showing that off during code review. But...no client is magically going to work with this (or any other) scheme; you're going to have to hand code all the logic, come up with a schema for conveying job status, etc. If you enjoy the challenge of making the logic as RESTful as possible while you're doing that, then sure, this describes a good way to be pretty RESTful. But don't feel like you're missing out on much if you decide not to do all that. There's no actual benefit from using HTTP response codes in a super semantic way. :) In short: It's as good as the article portrays it, but keep in mind the problem being solved is "handing a long-running job RESTfully". Handling a long-running job via an HTTP API is a different (simpler) problem.
- time0ut 8y agoI've been doing it in production at a rate of a few million individual asynchronous transactions per day for five years now. It adds a lot of complexity to the client that this article doesn't touch on. The client has to maintain state or you have to provide a means for it to reconstruct it's state. Clients can misbehave in ways that weren't as likely with simple synchronous creates. Where ever we can, we favor things like websockets and webhooks to push state back to the client. Unfortunately, that isn't always possible and doing something like this article describes is the best option.