In other language paradigms, I haven't faced this issue. Swagger is _just_ documentation, and a nice front-end on top. The Java annotations definitely make it easy to generate, though, I'll give it that.
In other language paradigms, I haven't faced this issue. Swagger is _just_ documentation, and a nice front-end on top. The Java annotations definitely make it easy to generate, though, I'll give it that.
I've never really liked the REST paradigm, so I'd be pleased to see it die.
My biggest complaint with Thrift: they still make you do some convoluted hacks to get a two-way ("streaming") connection in the RPC, and when this is discussed, they usually kibosh it pretty quickly by saying it's an unsupported case and that you can find some hacks online, but they don't want to talk about it any further.
This may not have been a big problem for them before gRPC was released for protobufs, but it's definitely something that's worthy of attention and response now. I know lots of people who are going with protobufs instead because of this.
The other thing is that while Thrift boasts a lot of language compatibility, several of these are buggy.
Don't hold your breath. Fielding's thesis is already 17 years old, so one would expect its philosophy to endure by the Lindy Effect if for no other reason.
There are lots of things in tech that we just stop doing one day. They get replaced by a different hot new thing. I'm sure REST will not go extinct for a very long time, but it definitely could go cold, just like its popular predecessors.
But the architectural principle called REST will be around forever because it's essentially the same thing as functional programming.
That REST is cache friendly corresponds exactly to the way that pure functions are memo-ising friendly.
Hmm way to paint Java developers as old dinosaurs...
> and thus try to create clients with Swagger when they should be using gRPC or Thrift.
They're trying to create clients with Swagger because they've made a REST API (yes you can do that in Java!). If you're using gRPC or Thrift, you're not making a REST API.
Personally, I've always found REST troublesome and overhyped. There's always a few incidents where you spend hours trying to figure out why something isn't working before realizing you had the wrong method on the request. There's no reason the thing you actually want to do to a resource should be tucked away in some header that's not always easy to access or see, it's just asking for trouble.
def handle_thing(thing):
r = urllib.request.Request(url='example.com',
data={'stuff': 1})
return urllib.request.urlopen(r)
Just one example.I know the tooling has improved somewhat since REST has become extremely common, so this is less of an issue now than it used to be (for example, most people use the Python requests module now, which makes it harder to use the wrong method (though many other HTTP libs still have the older urllib-style design)), but it's still annoying in principle. Combine with the fact that people tend to have different ideas about what the HTTP verbs and response codes mean, and it's pretty yucky.
Compare with Thrift, where you define an interface, list the possible exceptions, and generate stubs that auto-handle all of this communication exchange for you. All you have to do is make sure that you're calling the correct function, which should be pretty obvious.
This differs from setting the correct method in the HTTP headers in a couple of ways: first, HTTP clients usually assume a default method of GET. With a different protocol, there is no default "method", your action has to be defined somewhere. There will be no assumption (unless you code something implicit like this on top).
Second, a more conventional method has increased code locality, meaning the code that affects the operation is likely to be in the same source file/area. You'll normally be calling an ordinary function name like SaveThing inside the application logic flow, and it will be easier to debug, easier to realize the problem, etc.; the operation to perform is not tucked away in some other contraption that affects the headers.
Is it possible to design REST codebases so that such errors are hard to cause? Sure. But why do it the REST way and make it harder on yourself?
It should be just as easy to see what function you're asking the API to perform on a resource as it is to see what you're sending it. The operation I want to perform is an intrinsic part of what I'm doing. There's no reason to separate it and make it hard. I'd even prefer url-based actions, like example.com/string_save, because then at least the resource and operation are defined in the same spot.
A simple JSON envelope that has an "operation" key separate from a "data" key would make this easy, but then it's not in your header anymore, so it's not "real REST".
The difference is that the processes behind REST speak with HTTP. You're still doing a "remote procedure call"; you're asking for a remote process to execute some function on your behalf and return the result. RPCs facilitate the same exact thing. How is this a "fundamental" difference?
[I'm speaking here of the practical difference, not some difference that was originally hypothesized in the dissertation.]
Thrift contains both an RPC and an IDL, but they don't necessarily have to be used together. Protobufs is just an IDL; gRPC is the RPC, which was released just a year or two ago.
You would layer Thrift and REST by putting a REST API over the top of an interface defined in the Thrift IDL. You could also run the Thrift RPC for Thrift-compatible clients.
Say you have a user profile, which has a Gravatar associated. Sure you can have a getUserProfile() procedure that fetches the user information, but what about the image? You can write a getUserAvatar() procedure that proxies it, but that's wasteful.
In a RESTful system, you have a Resource Identifier (URL) that you can indicate as an hypermedia reference (link), with which the client can use a standard data fetching verb (GET) to retrieve it directly from the other server.
Of course, in a practical setting the getUserProfile() procedure would return the URL, but that's just an admission of the limitations of RPC vis-a-vis REST.
On the other hand, REST itself has its own problems and limitations, and is certainly not adequate for every use case, as Fielding's dissertation mentions at length.
I haven't read the dissertation so I can't really comment on the hypothetical REST (though it is on my reading list now, and not that it really stops anyone else), I can only comment on what, in the real world, passes for a "REST API".
"REST" principles certainly sound nice on paper, but for the most part, it's clear that they're completely implausible to realize in a wide-scale, meaningful way. After over a decade of pro-REST propaganda, people still can't even tell if their interface is "RESTful" or not.
The parts of "REST" that have worked are the two simple basics of HTTP: GETting a resource to read it, or POSTing a resource to write it. Nothing else has really stuck or can be expected to have a uniform meaning (and even POST's behavior will vary, with some doing an upsert-style operation and some accepting it only for new writes and using PUT and/or PATCH for edits). 200 OK means it worked most of the time, but sometimes people will return a plaintext error with it. 404 might mean that the resource is not found, or it might mean that the route is not found/no longer valid (or that it was called with invalid or improperly encoded parameters). There are a bunch of esoteric codes that are used to mean a lot of different things, always depending on who the implementer is.
So the "uniform interface" is just that everyone is using HTTP, to mean all sorts of different things. In practical terms, it doesn't really amount to much, except a lot of blathering over whether something conforms with a theoretical ideal that everyone has already demonstrated they're unwilling to conform to.
The term "REST," like so many others, now "means" something totally different than what the inventor of the term intended.
[1]: http://roy.gbiv.com/untangled/2008/rest-apis-must-be-hyperte...
"RESTful APIs" have mostly been a failure, I fully agree with you on that. The difference is that I think it's a cultural problem; when people like Licklider sensibly thought about a future wherein computers would learn to talk to each other (of which REST is a first step), as static protocols obviously didn't scale, we proved him wrong by sheer brute force. Watching something like Bret Victor's The Future of Programming, it's hard to miss the giant indictment of our whole profession.
That said, since I know the term is hopelessly lost, I don't push for REST either. Our service uses XML/JSON-RPC.