7 ms·
I've always been against using true REST API to build the RPC layer of a web browser SPA on top of, for one simple reason: The REST approach is essentially: "E
by WClayFerguson 6y ago
I've always been against using true REST API to build the RPC layer of a web browser SPA on top of, for one simple reason:
The REST approach is essentially: "Everything is a noun, and you have 4 verbs"
Building a good API with everything as a noun and only 4 verbs is quite awkward in my opinion.
Lots of API calls might need to pull data from multiple different "things" (nouns) to generate the reply, and in REST you're urged to require multiple calls to accomplish that. Awkward and slow.
- lmilcin 6y agoSQL is mainly four verbs, select, insert, update and delete. Not awkward. Four verbs are enough if your intention is to implement REST. If what you are implementing is RPC I can understand why you get annoyed. REST was never intended as basis of ALL communication, but the IT world seems sometimes bent to exploit an idea well beyond its limits.
- WClayFerguson 6y agoIf your domain is built with all nouns as a core part of what it inherently already is (like a Database being built on "records" or "documents"), then a RESTful interface for it "might" be workable, with the limited CRUD verbs. However, a vast number of web developers (dare I say "most") became convinced the proper way to "think" about their architecture was "as if it were all nouns" (even when it obviously wasn't), because they thought they were having an "epiphany" about how to use REST ...when what they were really doing was conforming to software development "meme" (or trend)
- nordsieck 6y ago> However, a vast number of web developers (dare I say "most") became convinced the proper way to "think" about their architecture was "as if it were all nouns" (even when it obviously wasn't), because they thought they were having an "epiphany" about how to use REST I don't think "developers thinking their architecture was 'as if it were all nouns'" is somehow limited to REST or even web APIs. It's a fundamental part of objected oriented design philosophy. http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom-of-nouns.html http://steve-yegge.blogspot.com/2006/03/execution-in-kingdom...
- WClayFerguson 6y agoI think a conversation between a web browser (SPA RPC) and a back-end server is best thought of as an RPC. Procedure calls are verbs if you ask me. Here's my own code that is such an API: https://github.com/Clay-Ferguson/quantizr/blob/master/src/main/java/org/subnode/AppController.java https://github.com/Clay-Ferguson/quantizr/blob/master/src/ma... You can point out that 80% of those API methods are resulting in some kind of CRUD method, and I'd agree, but nonetheless trying to make it a true REST API would be super awkward and verbose, imo, because lots of those functions result in multiple CRUD ops on multiple different types of data. When I design an API, I think: "What is this operation called? What data is best to send upstream, and what do I want to get back." Then I design the API. The API is a wrapper around an abstraction layer of functionality. REST is all about removing that abstraction layer which is moronic.
- tsimionescu 6y agoThis is all a matter of definitions. For example, from a syntactic point of view, Java has three verbs for all objects: "instantiate (new)", "call method" and "access field". An object has members, and you can use those 3 verbs to interact with the members of the object. In my experience, the nice part about designing APIs in a REST-like manner is that they encourage you to think in terms of observable operations. For example, instead of "calling" a long running blocking method, you create a resource that represents the long running operation, and now you can check its status while it is running, report progress, cancel it. Basically, when designing a REST API you think about the exact same things you are saying - what is the operation called? what data does it need, and what does it return? - and then you represent this as a resource that can be created with the right input, and that will point to a result resource for the final output. For example, my usual pattern for things outside of CRUD is something like this: --> POST .../operations/renderNode {ExecuteNodeRequest goes here} <-- 202 Accepted Location: .../operations/renderNode/891 --> GET .../operations/renderNode/891 <-- 200 OK {status: IN_PROGRESS, percentage: 78, ... (includes initial ExecuteNodeRequest params)} --> GET .../operations/renderNode/891 <-- 200 OK {status: SUCCESSFUL, percentage: 100, resultURL: .../operations/renderNode/891/result, ...} And then on GET .../operations/renderNode/891/result, you have the final result. Of course, if the operation finishes quickly enough, any of the polling steps can be omitted - e.g. it can directly return 200 OK and the result URL for the initial request. If you have WebSockets support, you can also be notified via WebSockets when execution finishes, instead of polling. It may look like more ceremony, but in general, for long running operations that will be called from a browser, this kind of approach is a requirement anyway, since the number of connections with a particular origin is extremely limited. Note that I also think your API would be much more concise as a REST API, since all of the miriad "setX", "getX", "createY" methods would be reduced to a few resources with multiple fields, that you can simply GET to see all fields, or PATCH to change a single field (or even change multiple fields in a single request).
- noblethrasher 6y agoYou can have as many verbs as you want, but they all need to be valid at every state of the application (i.e at every hypermedia target), because you still want a uniform interface. Responding with a standard error code is okay for verbs that are not supported at a particular state, but it's the uniform interface constraint that forces you to keep the set of verbs small. Also, HTTP has nine verbs: GET, POST, PUT, DELETE, HEAD, CONNECT, OPTIONS, PATCH, and TRACE.
- WClayFerguson 6y agoYou can read most any good book on software development and API design, and OOP, and how to create good abstraction layers, and how to name functions, and pass parameters etc. Here's the thing: None of those concepts in those books are trumped once you happen to be communicating over HTTP/HTTPS. None of those books tell you to come up with 9 verbs, and make everything a noun operated on by those 9. That's silly. HTTP layer has a place in the tech stack. Let it do what it does. Your API RPC layer is a separate abstraction layer, that also needs to exist. Trying to merge RPC down into the HTTP layer is silly and is cramming a square peg into a round hole, just because the round hole already existed.
- noblethrasher 6y agoHTTP is one particular implementation of REST that happens to have nine verbs. Another implementation might only have two or three. But no RESTful architecture will have much more than nine. Why? Because your application is going to have thousands of nominal states, and each one is going to need to support all of the verbs because of the uniform interface constraint. Why a uniform interface? A lot to say about this, but basically, the set of verbs is an abstraction of the state machine that is your application. If you have a million states and a million verbs, then you have no abstraction. If you have ten states and a hundred verbs then you have too much abstraction (i.e. you ran afoul of YAGNI). A good degree abstraction is somewhere in between, but if you care about scale (which is the raison d'être for REST), then the size of set of verbs is going to have a logarithmic relation to the size of the set of nominal states.
- mattmcknight 6y agoThis used to be bother me a fair bit, but I learned to noun a lot of the verbs I wanted to use. You don't sell, you create a sale. You don't move, make a movement.
- WClayFerguson 6y agoRight. So you bought into it, sounds like. Almost every other software developer did too. They all think they had an epiphany. They didn't. As for me, for 30 years I've known software function calls are inherently verbs and I'm not gonna let a trending "meme" (like REST) convince me otherwise. haha. I mean it's not so much the "nouning" of verbs that's the problem, but it's the loss of the ability to use verbs that I find so appalling. I mean if I need to run some reports it had better be called "runReports()" not some janky update of a state of some 'report' object to change it to 'running' state. So silly. REST is so jank. I mean what if "runReports()" needs to start N number of independent reports and return the status of startup of each one. With REST you always end up fighting things like that which are totally trivially easy without the REST nonsense.
- mattmcknight 6y agoI didn't really have an epiphany or buy in, I just figured out a way to think about it so I wasn't worrying about verbs all of the time. Purity in all things is a problem, REST included. One thing that kind of gets you is that HTTP itself is not the best transport for all of these things. If we are talking about something that has to run over HTTP, we might do something like create a run of reports (maybe a POST to reports/run). That could return a list of report_ids that were created and their associated status, with an run_id associated with the collect run. There's no fighting! However, if you want that data streaming back to you, this is where you might think you want something more like WebSockets. For some use cases, this can be more efficient than having the client polling to see if the result of a long running process is ready. It all depends. Anyway, not advocating for anything here, just pointing out that I had the same worry about supporting a rich vocabulary of verbs, but then kind of realized it didn't matter because all verbs you want can be nouns. If you are using HTTP though, the REST verbs match up pretty nicely with how the protocol works, so it avoids inventing another abstraction to sit on top of it.
- ivan_gammel 6y agoTrue REST API is hypermedia API and it is actually great for SPAs. It is more convenient than hardwired RPC, simplifies frontend architecture and offers much better approach to security (client does not care about security model implemented on server).
- vyrotek 6y agoAgreed! A SPA using an RPC API usually makes the most sense. I've wasted so much time over my career trying to jam functional concepts into REST resources for little gain. I really like the idea of each app getting it's own specialized backend. Have you heard of the BFF pattern? https://philcalcado.com/2019/07/12/some_thoughts_graphql_bff.html https://philcalcado.com/2019/07/12/some_thoughts_graphql_bff...
- WClayFerguson 6y agoI just read that entire article. Thanks for posting that. I like everything it's saying, and it points out some of the major drawbacks of REST. I've never used GraphQL yet but I know I do like it. Most of what I've done has been a mix of OSFA and BFF. RPC API design is more art than science, but definitely everything about REST is wrongheaded, inside out, upside down, and ass backwards. lol.