5 ms·
> It's perfectly RESTful; ... Yeah, so this is where just what the meaning of REST is comes in. There's no representation of the "transaction" resource that y
by cryptonector 8y ago
> It's perfectly RESTful; ...
Yeah, so this is where just what the meaning of REST is comes in. There's no representation of the "transaction" resource that you can GET, therefore they are not like the other resources (the ones you can HEAD/GET). You can only POST representations of transactions that internally contain ad-hoc encodings of CRUD operations on multiple other resources. This really feels like it should have been a first-class operation in HTTP rather than constructed in an ad-hoc way as needed.
- niftich 8y agoIf you design in this model, 'GET transaction-uri' should get, y'know, the payload of the transaction, or a status resource, or whichever you asked for based on proactive or reactive content negotiation, or whichever the server wishes to make available. It's just such a mental departure from the last 20 years of 'do-the-verb-to-the-noun' object oriented design that it's not often done.
- cryptonector 8y agoSure, but it's still not like a resource, and you still have to write code to implement it. You could never have a user-agent construct a transaction because the construction is completely ad-hoc and will differ by application. It's just not generic.
- dragonwriter 8y ago> Sure, but it's still not like a resource It is exactly a resource. > and you still have to write code to implement it. Well, someone, somewhere has to, just like any other resource. > You could never have a user-agent construct a transaction because the construction is completely ad-hoc and will differ by application. This is not true in any sense where the same is not true of lots of resources. > It's just not generic. While REST may favor using suitable generic representations where available, being generic isn't a requirement of REST. REST is DRY, not “Don’t write code for anything.”
- weberc2 8y agoIt seems like the GP is arguing that REST is insufficiently generic and you’re responding with “That’s not true, because REST isn’t generic”. Why is it desirable to write the same boilerplate code for every resource and now (presumably) every combination of resources that are operated on by every kind of transaction? Or are you making a different argument?
- niftich 8y agoIt's not clear what 'generic' means here, or in the parent, or anywhere in this thread. But in my view, this post [1] is saying that payloads that define a complex transformation or atomic manipulation of multiple independently-accessible resources require an extremely intelligent user-agent to construct case-by-case, because there's no widely-accepted terminology to describe arbitrary transformations of arbitrary data, or to introspect raw, semantically non-marked-up data ahead of time and figure out what needs to be done. In other words, to construct a resource you could POST to '/bank-transfer' that removes x amount from account y and adds it to account z requires the client to know about what these things mean. But the point of this post [2] is that that's precisely true, and it shouldn't be surprising, because this is exactly how every resource works. The disconnect between the expectations in this post [1] and this post [2] stems from the fact that most of these CRUD-over-HTTP APIs are actually implemented as thin middleware that parses info from the URI and hands it to database to retrieve. Resulting data items are then serialized using simple conventions as some commonly-used, non-hypermedia structural format, like JSON (no links, no rels), and served as 'application/json', devoid of any programmatic semantic meaning. A human reads this, and uses a combination of common sense, natural language skills, documentation, and trial-and-error to extract meaning from such a payload (e.g. "customerId" probably matches our customer number). For both retrieval and the inverse of this as storage, this is simple, and works: fields are matched by name, and the values are taken at face value. To the author of this post [1], this probably feels 'generic'. It takes low effort to implement on the server, it can be templated to work on any resource it can find in the database, and assuming an intelligent (i.e. human) client, these resources are practically self-describing! But to the author of the other post [2], this approach seems like a hardcoding of a particular behavior into client based on the the structure of a resource (e.g. a Customer resource), which doesn't seem meaningfully different from the same burden that would be required to implement a resource that describes a domain verb rather than a domain noun (e.g. a Bank Transfer resource). [1] https://news.ycombinator.com/item?id=18488976 https://news.ycombinator.com/item?id=18488976 [2] https://news.ycombinator.com/item?id=18489402 https://news.ycombinator.com/item?id=18489402
- saltcured 8y agoAssuming you accept things like links and forms, you can get a user-agent to collect input and ad-hoc "job" descriptions from the user and fill in the required structure in your specific application model. It's no more exotic than building up a shopping cart and submitting an order. Once you reify the process, you can add asynchronous monitoring and lifecycle controls as REST operations on these resources. Don't mistake a custom resource model with server-side processing with a requirement for a custom user-agent. All of the above could be done with pure, form-driven interactions or augmented with client-side processing to provide a slightly nicer UX. Of course, that doesn't mean you will have a generic web service that can perform all different transactions.
- jmull 8y agoI'm not sure what you're thinking of. What I've see is where a transaction resource is expressed as a collection of modified documents. E.g., in pseudo JSON: [ doc1, doc2, doc3 ] Usually each doc consists of some metadata (at least the doc URI, probably a revision number of the base document, maybe more depending) and the modified document content. (actually, it might be better like this: { "uri1": doc1, "uri2": doc2, "uri3": doc3 }) I'm not sure what your objection is, but this seems pretty generic to me. So the client GETs documents. It modifies some, puts them in a collection to form the transaction and POSTs them back to the store.
- deleted 8y ago[deleted]
- dragonwriter 8y ago> There's no representation of the "transaction" resource that you can GET Except in the most trivial cases, it's probably essential that there be such a representation and that you 201 the transaction with a URL for the resulting resource. The nature of aggregate transactions is that you probably don't want to do a 200 and done, especially if you are supporting arbitrary combinations of CRUD actions as you suggest. > You can only POST representations of transactions that internally contain ad-hoc encodings of CRUD operations on multiple other resources. “Ad hoc”? No more than any other resource representation. Not that I think most applications that need a transaction resource of some kind need an arbitrary combination of lower level actions; most need well defined classes of domain transactions that are each more constrained.
- jerf 8y agoThe reason you can't POST a transaction [1] is primarily that due to ~25 years of Web inertia that has hardwired people's brains into thinking that the request lifecycle is that a request comes in, you deal with it, you emit your response, and then you drop all state on the floor. For a good chunk of those 25 years nothing else was possible due to memory constraints, but today things are bit more fluid, yet the old ideas persist, often still unexamined [2]. I could build you a transactional API in Erlang, Haskell, or Go fairly easily, where it is easy and not necessarily unidiomatic to have a thread persist for a long period of time. It would do the obvious thing: You POST to get a transaction ID, the thread starts a DB transaction [3]. You do your various other POSTs, passing the transaction ID. When you're done, you POST to the transaction itself the commit request and get the response back. If you take too long, the coordinating thread will automatically roll back. It's not terribly different from other REST-based workflows that exist in the world; a REST interface [4] is not particularly required to not have workflows in it. There are various technical issues, some of which I footnoted even, but it's conceptually perfectly possible. There isn't a representation of any sort of resource until a developer creates it. There's no particular reason why a transaction can't be such a resource, any more than any number of other very abstract resources that exist in the world. [1]: Properly speaking, not a GET because it changes the state of the world. [2]: Unexamined != wrong, by the way. Some of the old issues still obtain. Some, however, do not. Dropping all state is still often a great idea, but there's a lot of APIs and code bent around a repeated cycle of "drop all state -> immediately reconstruct it all in the next request" that wastes a lot of developer and computer time for something that is not always necessary anymore if you're not scaling to the moon. Scaling code is great, but don't pay the price for 10^8 when you're never going to pass 10^3. [3]: Possibly it could build up a list of desired changes you want, or a number of other ways around holding open DB transactions for long periods of time, but let's go ahead and do it the hard way for demonstration purposes. [4]: At least, the modern colloquial sense of the term. I'm not particularly concerned about the details of The Thesis, which I consider a nice piece of work, but not something particularly binding on the rest of world, and not necessarily that much more interesting than an extended blog post since I do not believe it to have been based on anything like extensive real world experience or anything else that would give it more heft than any other thesis.
- 8y ago