6 ms·
It's time to put REST to rest
- baq 3y agohttps://en.wikipedia.org/wiki/XML-RPC https://en.wikipedia.org/wiki/XML-RPC (1998)
- catmanjan 3y agoHaving used “REST” for 10 years or so I can confidently say I’ve never used REST
- the__alchemist 3y agoYea. I assume from the article it's an alias for an HTTP interface that usually uses JSON payloads. I use those in a few projects, both work and personal. Are they Rest? Maybe. They use Django REST framework. But I think of them and describe them as HTTP APIs.
- munk-a 3y agoWell, if we're being truthful, none of us use REST. We're all just cherry-picking the parts of it that work for our organizations... and that's absolutely fine. The programtic discoverability portion of REST always struck me as pretty poorly thought-out anyways.
- nesarkvechnep 3y agoYou use REST every day. HTML is REST. Yes, with HATEOAS.
- deleted 3y ago[deleted]
- munk-a 3y agoWell, not all of REST - the discoverability portion isn't supported by pretty much anyone (because, IMO, it's just not useful).
- the_gastropod 3y agoI think you missed the point. You 100% use it every day. You’re using it on this website right now. Your web browser shows you what actions you’re able to take against the HN api. Neat, huh?
- richbell 3y agoThe three common types of "REST" I have encountered in enterprise dev are: 1. Ancient XML/SOAP based APIs Frankenstiened to use JSON 2. Poorly implemented RPCs advertised as "JSON REST API", usually the entire thing either relies on POST requests but sometimes GET is used to make stateful changes. 3. Things that should obviously be RPC split into dozens of anemic JSON endpoints that the caller has to re-construct to get anything useful Incidently, my company's leadership got inspired by Amazon's API culture and made # of APIs a metric that teams must hit. The result is every single endpoint being deployed as a separate API, and teams blocking access to native vendor APIs so each operation can be republished as a new API. :)
- anamexis 3y agoIf I had to guess, the comments here are going to revolve around "that's not REST" and "where's the hypermedia." I think that ship has sailed. REST in practice just means following HTTP semantics.
- dimitrios1 3y agoExactly. If you ditch the bikeshedding and no true scot arguments, REST is just a loosely defined naming convention around HTTP verbs, that almost every company I have been apart of agrees on / disagrees on certain minor aspects. That being said, I am thankful that we moved to using some form of "REST" (however you define it) as it was infinitely better than WSDL/SOAP. gRPC is nice in some areas, but these days I find myself doing what the article says more often than not -- just creating business-definition specific resources that utilize GET/POST and JSON.
- yawaramin 3y agoIf you define the terms exactly the way I want, then I win the argument! It's a very useful technique.
- dimitrios1 3y agoyawaramin, my former reasonML brother, you won't remember me, but I am so happy to have you comment on my comment even if it is tongue in cheek! Hope all is well.
- yawaramin 3y agoReasonML–that brings back good memories! :-D To be honest, I was pulling your leg but I mostly do the same thing you're doing when dealing with APIs at work :-P
- recursivedoubts 3y agoboooooo this man! booooooooooo!
- 3y ago
- altdataseller 3y agoFirst put SOAP and GraphQL to rest. Then we can talk
- angilly 3y agoAs a REST enthusiast I was excited to read this and learn a new perspective but this section > The “benefits” REST is supposed to introduce Is one of the more egregious straw men I’ve seen in a while. Never once in my twenty years have I heard anyone say it’s nice because “you don’t have to read the docs” or “it works in a browser” REST helps with lots from thinking through clean data models to helping ensure consistency within an API.
- richbell 3y ago> Never once in my twenty years have I heard anyone say it’s nice because “you don’t have to read the docs” or “it works in a browser. I've seen multiple people argue these points. shrug
- recursivedoubts 3y agoThe uniform interface, which is the defining characteristic of REST according to Roy Fielding[1], is what allows clients to interact with REST-ful APIs without "reading documentation": > "A REST API should be entered with no prior knowledge beyond the initial URI (bookmark) and set of standardized media types that are appropriate for the intended audience (i.e., expected to be understood by any client that might use the API). From that point on, all application state transitions must be driven by client selection of server-provided choices that are present in the received representations or implied by the user’s manipulation of those representations. The transitions may be determined (or limited by) the client’s knowledge of media types and resource communication mechanisms, both of which may be improved on-the-fly (e.g., code-on-demand). [Failure here implies that out-of-band information is driving interaction instead of hypertext.]" - https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypertext-driven https://roy.gbiv.com/untangled/2008/rest-apis-must-be-hypert... The missing piece here is hypermedia, which is a requirement for a REST-ful API, as Fielding notes again with frustration in the same essay. [1] - https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_style.htm#sec_5_1_5 https://ics.uci.edu/~fielding/pubs/dissertation/rest_arch_st...
- deleted 3y ago[deleted]
- nightowl_games 3y agoLet's put "REST" to rest because no one can agree on what it means.
- hinkley 3y agoIf you’re designing something right now, I want to remind you of one piece of shared but uncommon wisdom: So many of your users will not make it much past the elevator pitch for your idea. They will feel willfully or even recklessly entitled to the notion that if your tool allows something, the.n it was meant to be used that way. I don’t have any quick fixes for that. I doubt they exist. There are some very clever things I have seen in the REST domain that are lumped under advanced topics that make a lot of sense but I don’t think I have ever seen in the wild. So if an idea feels important, you have to aim it at the journeyman if you expect it to be used at all, and beginner if you can figure out how without losing them.
- recursivedoubts 3y agoOK OK OK, OK OK, stay calm, Carson, stay calm... I'd like to just leave a few links on REST here for the reader's consideration: https://htmx.org/essays/how-did-rest-come-to-mean-the-opposite-of-rest/ https://htmx.org/essays/how-did-rest-come-to-mean-the-opposi... https://intercoolerjs.org/2016/01/18/rescuing-rest.html https://intercoolerjs.org/2016/01/18/rescuing-rest.html https://htmx.org/essays/two-approaches-to-decoupling/ https://htmx.org/essays/two-approaches-to-decoupling/ https://htmx.org/essays/hypermedia-apis-vs-data-apis/ https://htmx.org/essays/hypermedia-apis-vs-data-apis/ https://htmx.org/essays/hypermedia-clients/ https://htmx.org/essays/hypermedia-clients/ https://intercoolerjs.org/2016/05/08/hatoeas-is-for-humans.html https://intercoolerjs.org/2016/05/08/hatoeas-is-for-humans.h... https://htmx.org/essays/hateoas/ https://htmx.org/essays/hateoas/ In addition, I’d just like to interject for a moment. What you’re referring to as REST, is in fact, JSON/RPC, or as I’ve recently taken to calling it, REST-less. JSON is not a hypermedia unto itself, but rather a plain data format made useful by out of band information as defined by swagger documentation or similar. Many computer users work with a canonical version of REST every day, without realizing it. Through a peculiar turn of events, the version of REST which is widely used today is often called “The Web”, and many of its users are not aware that it is basically the REST-ful architecture, defined by Roy Fielding. There really is a REST, and these people are using it, but it is just a part of The Web they use. REST is the network architecture: hypermedia encodes the state of resources for hypermedia clients. JSON is an essential part of Single Page Applications, but useless by itself; it can only function in the context of a complete API specification. JSON is normally used in combination with SPA libraries: the whole system is basically RPC with JSON added, or JSON/RPC. All these so-called “REST-ful” APIs are really JSON/RPC.
- nesarkvechnep 3y agoThank you! Exactly my thoughts. I stopped using the term REST because in web development circles it’s meaningless. I use Hypermedia API.
- epcoa 3y agoThis is fair, what I think ended up happening in the 2010s is that REST was pushed similar to XML, a solution for all application problems (it wasn’t like Fielding was not pushing this view either), and realistically the useful scope of REST and Hypermedia is quite limited.
- mpweiher 3y agoThose 2 were never the claimed benefits, and the fundamental "problem" is not a problem: a LOT of data processing is making changes to records. And you can encapsulate a lot of logic behind making changes to records. And this makes most software easier to understand: "Show me your flowcharts and conceal your tables, and I shall continue to be mystified. Show me your tables, and I won't usually need your flowcharts; they'll be obvious." -- Fred Brooks
- elanning 3y agoI’ve been having a good time using REST level 0.5 https://faithlife.codes/blog/2023/09/rest-level-zero-dot-five/ https://faithlife.codes/blog/2023/09/rest-level-zero-dot-fiv...
- stock_toaster 3y agoInteresting! Level 0.5 seems to be what twirp[1], which I have used and enjoyed, would also fall under. [1]: https://github.com/twitchtv/twirp https://github.com/twitchtv/twirp
- JohnMakin 3y ago> About being able to use a RESTful API directly from a browser: browsers only use the GET and POST HTTP methods, among the ones REST associates meaning to. You cannot use a RESTful API from the browser, because the PUT, PATCH, and DELETE methods are not used by the browser, and even the POST method cannot be used without a UI. Also, even if you could, APIs are for machines, not humans. The user experience would be dreadful if you had to use a RESTful API directly from a browser, without a specific UI for it. This.. isn't true?
- munk-a 3y agoIt's kinda true if you're thinking purely about submitting requests through `<form>` elements - but even then you can bend browsers to support other verbs.
- user3939382 3y agoThere are multiple RFCs with lists of HTTP verbs and axios only supports the more limited set, which for my particular legacy project meant I couldn't use any of the creative ones.
- munk-a 3y agoThat really just sounds like an axios issue - I've built in support for custom verbs with nothing but plain-old ES5 javascript. The verb is nothing more than a string component of the HTTP request and it's pretty trivial to modify it to your liking (even outside of standard verbs!).
- stronglikedan 3y ago> without a specific UI for it None of my browsers seem to have PUT, PATCH, and DELETE baked into the standard UI (or even POST really), so maybe it is true?
- gweinberg 3y agoI just checked the MDN docs https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form https://developer.mozilla.org/en-US/docs/Web/HTML/Element/fo... The only allowed form methods are get, post, and dialog. So you can't do put, patch, or delete via a form.
- TOGoS 3y ago> I even used HATEOAS principles when building HTTP APIs I found your problem. > About being able to use any API without understanding it first That's a HATEOAS thing, as I understand it. REST just means that you have resources and verbs, and the verbs have ~relatively~ consistent meaning. If I see some GETs and PUTs and PATCHes and DELETEs I can get a pretty good idea of what's going on. It doesn't mean I understand all the details of your application logic.
- munk-a 3y agoOne point this article objects to is the (ab?)use of HTTP status codes for indicating object status (i.e. 404 Your student doesn't exist). HTTP status codes are an extremely loose and flexible standard and I think that semantically most of the "RESTful" uses here are perfectly in line with expectations. Shift your thinking for a moment to consider that instead of `/user/12` linking to a script it's actually just a flat file containing some information about the user - the 404 response when the user doesn't exist is perfectly reasonable. The requestor shouldn't really care whether the request was fulfilled by apache checking file existence or some PHP script. In fact, webservers are just another kind of dynamic responder and it's important not to mystify their internal workings.
- simonw 3y agoI agree with some of this - I've never found value in the different PUT/PATCH/etc verbs, and I think the lack of examples of good "pure" REST APIs indicates that pure REST doesn't work easily for most projects. I do think this throws away some pieces that are really valuable though: 1. URLs for concepts are a good idea 2. Distinguishing between read-only operations (which can be cached) and write operations using GET and POST verbs is useful Personally I've found myself settling on "REST-ish" JSON APIs: - Every domain concept has a URL, and a standard consistent JSON representation that's also returned by list endpoints - GET for read operations, POST for anything that performs a write - I don't like content negotiation via the Accept header, so instead if I need to support alternative representations I'll do that using file extensions, .json vs .csv for example
- nesarkvechnep 3y ago1. URLs doesn’t matter in REST because interactions are hypertext-driven. 2. The method to use is implied by the relationship of a link.
- camgunz 3y agoImplicating isn't a great way to document an API. You could easily do something you didn't intend to do, which could be no big deal or extremely costly.
- Dan42 3y agoYep, this is pretty much what I've settled on myself. GET for read, POST for write. And a url made of a slash-terminated "resource" followed by an "action" verb. user 123 + edit = "/user/123/edit" ; user 123 + default(show) = "/user/123/" ; list of users = "/user/list" ; etc. When applied to web pages, it means you can have <form action="edit"> and the "action" attribute of the form directly matches the "action" of the backend/router/API. I like that, it makes me feel warm and fuzzy. :-)
- adonese 3y agoContent negotiation is it just for taste or do you have some other reasons? I find one good use case for them when a browser can make good use case with a SSE whilst another client just needs a regular _json_ response
- monero-xmr 3y agoRest is fine, just a loose standard around using HTTP for rpc calls. Makes communicating between different servers and languages easy. The real mistake is graphql. Like microservices, so many companies get hamstrung with this. I’ve said my piece.
- kolanos 3y agoThe solution in this article looks a lot like GraphQL. Commands are mutations, queries are... well, queries.
- commandlinefan 3y agoIt drives me crazy that every RESTful API I've ever seen in the wild has been running under a full-blown Tomcat or nginx (or some equivalent) web server when only a tiny, tiny subset of the HTTP protocol is actually needed for the API being supported.
- agraddy 3y agoI went into this article strongly disagreeing but I think the alternative presented at the end are valid ways to structure an API and for those who very loosely follow REST structuring would probably consider the alternatives "REST" too. REST seems to have different definitions depending who you talk to. Some define it very strictly (as the opening of the article seems to do) and others define it very loosely (as a JSON interface with GET/POST/etc commands). For those who implement REST loosely, the suggested alternatives fit right in.
- dale_glass 3y agoA thing not being mentioned is caching. Now I'm not a web dev, I've played around way back in the CGI era and since then moved on to other things. But my impression was that part of the point of REST was making it fit in a bit better in how the protocol is supposed to behave. Early on there was a lot of stuff that did nothing but GET for everything. Done that way any layer in the middle can't make any sensible caching decisions, and even the logs are annoying to look at when you can't quickly tell apart what's retrieving data and what's changing it. So my impression was that part of the point of REST is to shoehorn an API into something that makes sense in the way HTTP is supposed to work, and you're less likely to have something go dramatically go wrong because some cheap ISP is running a transparent proxy and deciding that the GET that's supposed to save something doesn't actually need to happen, because look, this user already made a GET to the same URL 5 seconds ago. Now of course today everything uses SSL, but early on it wasn't that weird to run into some awful ISP that would do some sort of aggressive caching to save on upstream bandwidth, if not to actually try to recompress stuff in flight.
- mgaunard 3y agoThe trading example is bad, since we do talk about posting limit orders even outside of a REST context -- though it refers to it staying in the book and not matching immediately.
- ath3nd 3y agoNo, it's not. But in short, articles arguing thst the most popular api format needs to be put to rest can't be anything else but highly opinionated clickbait
- gtirloni 3y agoFreeBSD and REST should organize the Is It Dead Yet? conference.
- gtirloni 3y agoJust to clarify, my incredibly vague point is that people having been saying FreeBSD and now REST are or should be dead for so long but they never die :)
- ilovefood 3y agoThe article is good, and I get the point. However, from experience, this: > POST on /queries/enlisted-students-on-joining-date/version/1 { "date": "2023-09-22" } to retrieve all students that joined on a given date. always ends up in a complete and absolute mess, where every possible query gets it's own random name, different parameters, ending up with duplicates all over the place. Also, while it can be possible to cache these POST requests (responses), it's additional work and more friction compared to REST. I'm not convinced the tradeoff is worth it in this particular case. All in all, I don't know if the current proposal can be an alternative either but the idea of a "REST-lite" goes in the right direction and it's a great start. However this is a complete no for me: > When a requested student is nonexistent, your API can return 200 OK HTTP status code with a { "user": null, "message": "No user exists with the specified ID" } response body. If nothing is found, I want a 404! :D
- benrow 3y agoI like the convention: - 404 if resource requested by id - 200 with empty list of results if it was a 'search' type request with params (not referring directly to an id)
- tuetuopay 3y agothis is the standard we have company-wide and it works pretty well, unless you make a mistake in the uri (like picking up the wrong api version). however, all apis will return some info on their root, so it's easy to distinguish and troubleshoot
- Banditoz 3y agoWhat about 204? https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204 https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/204
- benrow 3y agoI still prefer 200 with an empty list for the 'no results' case. The same client code works, rather than having to code for 204. - If I query for an identifier which doesn't exist - Server replies 404, this should fall into my error handling as there's a data inconsistency - If I query say like ?category=automotive&price=1 and I get a 200 containing a json body in which there's an empty list of matches, then my client code can handle 0 matches as well as 1 or 10 with no special handling.
- senderista 3y agoI thought a practical benefit of REST (probably the only one I really care about) is that it makes APIs more scalable by allowing caching proxies to safely cache responses to GET requests? At least I thought that was a big part of the original pitch, but I don't see it mentioned here.
- quickthrower2 3y agoREST is a design pattern. Do you use the bridge pattern for all your Java code? Nah! Do you use an ORM for all your data access and never drop down to SQL? Nah.
- fabian2k 3y agoThere are some things that simply don't fit into the REST structure, the most common one for me is bulk operations. Operating on multiple instances of a specific resource is a common thing, and you need a non-REST endpoint to do it properly. Of course you could just iterate over the items, but then you can never have transactional behaviour (either no write happens or all of them happen). And of course it's terribly slow for larger number of items. Another annoyance is GET endpoints with complex filters like e.g. the index route for a specific resource. It's really annoying to be limited to the query params instead of a request body for that.
- alexpetros 3y agoIf the supposed benefits of REST are: > 1) It’s simple, and easy to understand. You can perform the same actions on all resources, so you don’t need to learn the details of a specific API to use it. 2) The API is usable via a browser. then the part that this article is missing is HTML. REST APIs require HTML (or equivalent), because (via the the browser) the HTML self-describes what actions can be performed on it. If you return `<a href=/profile>My Profile</a>`, then the user knows that clicking on it will take them to their profile; they're interacting with the API without knowing its details. A lot of people say "ah to hell with it REST has no meaning anymore" but since the premise of the article is to engage with the meaning of REST, well, that's kind of on them. See the @recursivedoubts essays in another comment on this post too, they're much more in-depth than my comment.
- jauntywundrkind 3y agoI was pretty annoyed expecting some awful conclusion that we had to do something entirely different, resting upon what felt like extremely shaky grounds. A one-auarter decent OpenAPI will elaborate what endpoints do, which felt like all that was missing. In the end though, the author isn't really arguing against what we have, expect they want /commands and /queries prefixes. Given the way some endpoints can be overloaded with disparate behaviors, I don't disagree that sometimes it can be confusing for all the verbal to apply to an endpoint. But POST /students/enroll seems more than fine to me, and trying to wrestle out a new norm, where URLs aren't broken down by resource type but are broken down instead by behavior-class seems absurd & a folly. > The fundamental issue with REST is that it defines operations that manipulate data structures. It’s about structure and structural changes, not behaviour. It’s imperative, rather than declarative. If it's about structure, wouldn't that be declarative? Aren't behaviors typically imperative (move this here, drive that there)?
- hn_throwaway_99 3y agoWhile I think some folks are getting caught up in the details, I thought the overall premise of this article was correct: 1. First, as other comments here are pointing out, in the industry people use "REST" to mean lots of different things. Some folks just use it to basically mean "An API over HTTP that uses JSON and HTTP methods (GET, POST, etc.)". For clarification I like to refer to that as "REST-lite". The author is talking about what I like to refer to has "true REST", which is strict about entities, verbs, etc. and the format of calls like PATCH. 2. I think the authors general points about why "true REST" is usually a bad idea have been proven out, and like most bad ideas that originated around that time period, they came about because people had a fantasy idea of how we would interact with resources on the web that wasn't born out in reality. I essentially thought his point about "being able to use any API without understanding it first" was spot on. I also think there were other good points about the supposed benefits that nobody really uses, or that aren't that much of a benefit (these days, who really cares about supporting multiple formats of an API like XML in addition to JSON?). At the end of the day, after decades in software development, I've pretty much come to the conclusion that if your API framework doesn't look like some flavor of RPC, it's bad. This is just fundamentally how most software developers think: "I want to do some operation X, so just let me make a remote procedure call that is named X". This higher-order structure is usually a mistake that's trying to get developers to conform to some ivory tower way of thinking that doesn't work.
- ilaksh 3y agoPeople will still be arguing about this in ten or twenty years when many new services use AI agents on a blockchain that automatically pick up DSLs invented a few days before by other AI agents and use them to negotiate and execute service orders on your behalf. Eventually you may get something like a high dimensional protocol used for converting and syncing neural adapters on the fly, enabling "multi-brains" to collaborate opportunistically. But even then there will _still_ be people having this exact same argument. Anyway, I feel like a lot of people actually moved on to GraphQL years ago. I think I probably need to catch up to that trend still.
- desultory 3y agoNice article and the examples are much appreciated. I've read about this concept under the terms CQS and CQRS before. 1. https://khalilstemmler.com/articles/oop-design-principles/command-query-separation/ https://khalilstemmler.com/articles/oop-design-principles/co... 2. https://martinfowler.com/bliki/CQRS.html https://martinfowler.com/bliki/CQRS.html
- Kwpolska 3y ago> So when the server receives a PATCH /schools/{school-ID}/students/234 { "lastname": "Luthor" } request, it needs to understand that a student has requested for their lastname to be changed, and it then needs to decide what to do about it. What if some fields cannot be changed? What if the value of some fields is constrained by the value of some other fields? By allowing an arbitrary PATCH operation, these concepts are hard to model and validate requests against. If there are validation issues with user-provided data in a PATCH, then the API should tell the user what they did wrong and reject the update, plain and simple. How would their solution react to bad data? How would it be different from what any implementation of PATCH does? > POST on /queries/enlisted-students-on-joining-date/version/1 { "date": "2023-09-22" } to retrieve all students that joined on a given date. So instead of a browser-accessible GET with idempotency standards, you need a POST and you need to serialize JSON just for a single field? > POST on /commands/report-student-lastname-change/version/1 { "student-id": "123", "new-lastname": "Kent" } to report a lastname change for a student. Great naming: I initially thought this would be about a report about last name changes, not a way to add new data. Should there be separate endpoints for each field of each entity? That might replace “validation” of no changes to fields that cannot be changed, but it does not replace validation of last-name-is-not-empty or national-id-number-is-valid. What if the changes are provided in a form that allows to edit all data? Do I need to send separate commands for each user-edited field? If using the bulk form (POST /commands), what if one of the commands fails — will the previous commands be rolled back, or will the DB end up with partially-edited data? > When a requested student is nonexistent, your API can return 200 OK HTTP status code with a { "user": null, "message": "No user exists with the specified ID" } response body. And now you can’t even automatically detect error conditions and have consistent handling for them, at least not with a schema like this.
- ysavir 3y agoWhat the author seems to miss is that a "resource" in the REST sense (in practical usage at least. I'll leave the official recommendation pedantry to those who care for it more strongly than I do) doesn't need to reflect a data structure. It's definitely easier to link data structures to REST commands--I imagine REST was created with them in mind--but the recommended "commands" can still be thought of as resources. Not every REST verb applies to them, true, but that's not really impactful or relevant. The point is that you can continue structuring your API in typical REST fashion, but with the addition of command-oriented RESTful paths that implement the appropriate verbs for that command. The author's own suggestion, `POST on /commands/{command-type}/version/{command-version}`, is still effectively REST as far as I'm concerned, with the identifier being a string ('command-type') instead of a number or UUID. The structure of the API hasn't changed, we just broadened our definition of a resource. Purists might disagree there, but from a day-to-day practicality perspective, nothing significant changed in our API development. The article is arguing semantics rather than actually criticizing REST as it's used in practice. That said, the author does seem to have listed a few things I disagree with: > So when the server receives a PATCH /schools/{school-ID}/students/234 { "lastname": "Luthor" } request, it needs to understand that a student has requested for their lastname to be changed, and it then needs to decide what to do about it. What if some fields cannot be changed? What if the value of some fields is constrained by the value of some other fields? By allowing an arbitrary PATCH operation, these concepts are hard to model and validate requests against. I'm not sure what difficulty they're seeing here. If some of the values can't be changed, it's a failed request, return the errors without any updates. The "arbitrary" parts feel like they derive more from their own API implementations than anything practically REST-ful. Or maybe it's in the official REST spec, which, as comments here demonstrate on repeat, holds very little ground. > This also sucks, because HTTP status codes are about the HTTP protocol, not your business semantics. The 404 Not Found status code indicates that a path doesn’t exist. If you use it to say that a student doesn’t exist, these two get mixed up. If a client invokes the wrong path by mistake, there’s no telling whether it’s due to a protocol error or to a nonexistent student. If there's no student with the ID 4, then the path `/students/4` doesn't exist. It's not saying that `/students/<id>` doesn't exist, because the path-with-variable only exists as a theoretical construct, not an actual path. So I'm not quite seeing their argument here (unless, again, they're arguing against the semantics of the official recommendation, which I've never seen implemented in a straight fashion anywhere). And if there's user error in invoking the wrong path, then that's hardly on the API design.
- deleted 3y ago[deleted]
- grishka 3y agoI'll have to add a client API to one of my projects soon and I've been thinking about this particular problem lately. The one API I worked with a lot is that of VKontakte. It's as unRESTful as they come. You send requests to URLs like api.vk.com/method/users.get. The HTTP method doesn't matter at all, how you pass parameters doesn't matter at all (can be a combination of query and form-data for all it cares), the version is just `v` parameter, the access token is also just a parameter, and errors come with 200 OK. That is kinda not well thought out. But only kinda. The one I'm contemplating is somewhere in between the two. The endpoints are still "methods", but the HTTP method does have a meaning: GET is for retrieving something, and POST is for active actions. The access token will have to be passed in Authorization header. The version will still be a `v` parameter. There will not be any IDs in the paths because of how awkward that is. The errors will set the HTTP status code. Any opinions on this?
- Humphrey 3y agoThe author has almost perfectly described the pattern behind GraphQL mutations! That is, a command on the server that represents a user action, takes input, and returns the updated data that has changed. While many people dislike the whole GraphQL stack (I love it, it solves all the problems the author has with REST), I think we can all agree with the usefullness of the pattern that mutations are built upon.
- pentaphobe 3y agoA few really appealing points and ideas here! Versioned "commands" are an improvement I'd like to see more of (it could even be useful in existing REST-lite APIs - I've used similar concepts to this in some prior work) And the key point around business logic being misrepresented is definitely worth a ponder. Notable that a lot of this sounds like a reinvention of DDD (Domain Driven Design) concepts - or at least if the author is applying DDD they make no mention of it. Which I wholeheartedly support.. Seems like two problems being conflated though: 1. Low level interactions - generally between systems. Sometimes I _want_ my API not to hold any high level business logic. It'll do basic verification of individual entity events (changes) to avoid epically stupid mistakes, but otherwise is a dumb resource used by other, more high level controllers. Often this scenario is basically a thin wrapper over storage mechanisms, or a single abstraction atop a collection of other APIs In this scenario, REST or other "non-business-aligned" options are perfectly fine - if they were any higher level then I'd be constraining the possible actions to what's implemented in a single place. But by keeping it granular, and aligned explicitly to direct interaction with specific models (in a bounded context) then those changes _should_ be isolated. 2. Intent based APIs which perform high level actions that are aligned to ubiquitous language. These would be a great fit for the proposed method in the article - and I'd posit that many of us already use some form of this in our APIs, whether through naughty blurring of what "REST" is supposed to mean, using GraphQL, or other similar alternatives. Generally these are user facing, or at least are at the boundary. Personally I'd maintain these as a separate thing (or at a separate top level route) which leverages the lower level interfaces to perform more complex, potentially multi-modal activities. --- *TLDR* what the article proposes seems useful, but (IMO) more as a good reminder to be clear about your APIs' purposes: are they an interface to a bounded context, a model, or an aggregate?
- gregors 3y agothere's a reason why REST is still the most widely used and the RPC type examples have faded. Here's the thing, domain specific language specification both in source code and at various API interaction points are a good thing. But they are a thing that takes time to figure out, and they have a tendency to change. REST is still the best starting point and I challenge anyone to say that RPC is "better". We've tried it before it wasn't better. Oh you mean we did it wrong? Well now, that's the real trick isn't it?