> Don't get me started with conflating http server errors with applications errors.
I've wasted so much time dealing with 404 errors that were returned by the webserver itself (not the app) because the endpoint I was hitting was wrong or had moved, and vice-versa when I was correctly hitting the app but got a 404 error back from the API and I thought that the endpoint was wrong. And, of course, similar issues for 500 errors and the app itself dying versus the app processing normally and indicating an expected failure response via a 500 error code.
To add to all that badness, a lot of JS libraries in their async API method calls have different error handlers for success and for failure response codes, so you end up having to lump together business logic (for resources not found) and retry/error-handling logic (for the server the not working correctly) into the same failure response callback handler. It'd be much cleaner if all the business logic could be handled in a single callback and all of the failure logic could be handled in another. And, of course, you only even get to this level of badness once you figure that out; you can still waste quite a bit of time before you even realize that your callback is not being called because the JS framework is interpreting the expected 404 your API endpoint is returning for non-existent things in business logic differently than you are.
I still wouldn't go back to SOAP, but I do tend to prefer HTTPS/JSON-based APIs that don't abuse verbs, HTTP error codes, and mixes of URLs/params/headers/payloads. Better to put all of that stuff inside the JSON payload where it will only be handled by the application business logic, rather than mixing it in with all of the HTTP constructs that are used for other things as well.
In theory, the latter does the same thing, but it's far more explicit, the developer knows it relies on the network and accordingly that it may fail. Developers will be more inclined to plan for errors when the possibility of such errors are more obvious.
So in most cases you'd do something like:
let foo = () => http.GET('/foo');
.
.
.
foo() //foo is statically dispatched in the source code hereIs it really a useful distinction? Let's rename our 'foo()' to 'dangerously_unreliable_with_unpredictable_latency_foo()'. Is there still a huge difference?
> accordingly that it may fail. Developers will be more inclined to plan for errors when the possibility of such errors are more obvious.
That part of your comment looks suspiciously similar to the usual argument against exception handling to me.
And to your second point... yes, all developers should check possible exceptions, just like all children should brush their teeth. However, if you have bad habits and you aren't good all the time, then at lease brush your teeth after eating sweets, and likewise, developers should please check for exceptions around network calls.
Access the RPC call as httpSerbice.getFoo() and make it return a Future/Promise, or even a special subtype of those. 100% obvious what it does.
You're going to be calling REST methods the same exact way anyway - you have to pass around the result of that restful http.get call somehow.
int start(void (*job)(void*), void (*done)(void*), void* tag);
`job` is called on a separate thread at some point (goes through a job scheduler) and once it is done, `done` is called at the "main" thread (at some synchronization point, usually during the event loop), `tag` is just passed around for context. `start` returns zero on failure.I don't see RPCs as anything different conceptually (after all the job might also fail). The only issue someone might have is when expecting a synchronous API, but even in non-networked code there are tons of asynchronous APIs.
The goal should be to inform the caller of the types of errors that may pop up. Obviously, with network or RPC calls, the caller should handle the case where the network is down. With threaded apps, the potential errors are more subtle, but the caller should definitely be aware that it's not a synchronous call. The function header you proposed is a bit clumsy due to the c semantics, but gets the general point across well enough.
The part I find most interesting about Fielding's thesis[1] is the introduction with architectural overview. He managed to map out modern Web apps perfectly - they can be REST (Web app with db/storage backend, perhaps extended with something like webdav) which is amenable to multilevel caching, smart client;movable data: json api js app, or smart client;movable code: js/Ajax - executing js delivered by server on client (subtly different from a "pure" js/json app (which is similar to an XML/xslt App).
I don't know why the hype of rest lead people to insist on conflating their architectures.
[1] http://www.ics.uci.edu/~fielding/pubs/dissertation/top.htm
Ed: not sure about "time wasted bickering over it". Bickering is always time wasted. Careful analysis of software architecture, patterns, and figuring out what you're actually trying to achieve - is time well spent.
There are fundamental trade-offs between REST and different patterns - depending on where the truth of your data recides, if you need acid or not, and where (what part of) your code executes.
You can argue that REST is easier to debug for developers, but nothing makes XML-RPC or binary protocols inherently _less_ easier to debug. It depends on the platform and library you're using.
I wholeheartedly agree with the article. Well done.
And the wide availability of those is because it's so easy to build one over obvious REST apis.
Clients are lazy and impatient, and this is a good thing because it makes the developers work hard to make it easy to connect to their API.
After moving to a REST based API there were endless meetings between co-workers of what is and isn't a good REST url. Our clients often come to us with dumb mistakes. Unlike RPC where the parameters go in a single place. With REST the parameters are spread across the verb, url, header, query param, etc..
With RPC your consumers probably need to know some coding and even maybe a specific language, a framework or a library.
So yes, for me REST is easier, and I always love to see landing pages like this one - https://freegeoip.net - where the client can test the API in a few seconds by copying an example to its browser address line. This is a simple use case, but I hope you get my meaning.
SOAP even has handy discovery tools that frameworks can consume and construct entire APIs in most popular languages.
It's just that no-one uses SOAP from a browser because XML is a royal PITA to write in JS. I would assume it's because all JS developers are too-busy writing more libraries-for and layers-over JSON.
It was the same way 15 years ago if you suggested anything other than SOAP. The more things change, the more they stay the same.
{“username”: “sam33”, “password”: “hunter42”}
Would be fine, but could include more if you were following a spec like JSON API 1.1. I really don’t have any of the problems you seem to have. But I work in a high level programming language, so maybe it’s that? Either way I find RCPs to get messy when they get bigger. Sometimes it’s the right move, but for web apps I generally prefer REST.
Subconsciously no one wants to deal with your carefully constructed REST URLs. They just want a function name and some parameters.
A good example to me is Stripe.
I've written over 10 applications that use Stripe and every single time, the first thing I did was use Stripe's official library for the languages I work out.
"Async RPC" is a more recent idea, but still gets referred to as "RPC", so the complaints about classic RPC still get raised since the term is overloaded.
The thing is, RPC is fundamentally broken due to the nature of distributed computing, and REST is not. All the time you have to spend doing things right is … the time necessary to do things right.
And REST really is very simple. The problem is the cargo-cult nature of folks who don't really understand it.