5 ms·
I have a fairly dumb question. If one were building a standard web app... say, a super simple web store that lists products, allows someone to submit products a
by Exuma 10y ago
I have a fairly dumb question. If one were building a standard web app... say, a super simple web store that lists products, allows someone to submit products and such. How would they use RPC instead of rest? Can you give some concrete examples of how it's different / better.
- bigmanwalter 10y agoIt's more natural to deal with collections and other data structures using RPC. REST works best with single items. As soon as you need to start generating reports, it can be complicated to create sane REST endpoints whereas it's trivial with RPC. REST: GET /api/item/1 GET /api/item/2 POST /api/item { name: foo, collection: 1 } POST /api/item { name: bar, collection: 1 } RPC: GET /api/items POST /api/items [{ name: foo, collection: 1 }, { name: bar, collection: 1 }]
- njharman 10y agoHow are your RPC examples not REST? RPC would involve client lib. And may or may not even use HTTP as transport. api.get_product(id=1) api.add_product(details)
- bigmanwalter 10y agoI thought we were talking about RPC over HTTP. My RPC examples don't qualify as "proper" REST where you are only supposed to GET and POST singular resources at a time. In order to post multiple, you need a collection identifier. In REST, you can't GET "items", you can get "item1" and "item2" or you can get "collection1" to which "item1" and "item2" belong. Maybe a clearer example around running a script: REST: POST /api/action { action: do_the_thing } RPC: POST /api/do_the_thing RPC is the most basic mapping of actions > endpoints whereas REST demands you organize everything into resources.
- mercer 10y agoInteresting. It sounds rather similar to me as the way the difference between functional and OO programming is often described (verbs-first vs nouns-first). Is there anything to that or am I comparing apples with non-apples?
- bigmanwalter 10y agoI think there is definitely some basis to your analogy :) I think that it also stems from most ORM's focus on updating single database rows at a time even though operations frequently span across multiple rows. As all data manipulation ultimately happens on the server, I feel it's often unnecessary to keep track of individual resources in the client.
- inf0rmer 10y agoBut that's not how you would use REST and RPC though, you seem to be confusing both paradigms. REST: GET /api/items (returns a list of items) GET /api/items/1 (returns item with id#1) POST /api/items (creates a new item, "adds" it to the list) PUT /api/items/1 (updates item with id#1, the whole resource needs to be sent) PATCH /api/items/1 (updates item with id#1, only changes in the resource need to be sent) DELETE /api/items/1 (updates item with id#1, only changes in the resource need to be sent) RPC (one possible implementation): GET /api/listItems (lists all items) POST /api/addItem (adds an item) POST /api/updateItem (updates an item, the id is in the payload) GET /api/deleteItem (deletes the item) (Verbs don't matter in RPC, I only used POST in favour of GET in the above examples because some clients and servers enforce limits on the size of GET requests.)
- bigmanwalter 10y agoRight, but RPC allows for, say, updating items 3, 4, 5, 6 in one request, whereas REST dictates that you do it over 4 separate requests. REST can also get messy if you, let's say, update all items with value > 4 as you can't PATCH /api/items/greaterthan/4 { active: false } Whereas with RPC you can easily do: POST /api/items?greaterthan=4 { active: false } In REST, you would do POST /api/item_updates/ { greatherthan: 4, active: false } It comes off as messy to me as I would prefer to keep all endpoints around manipulating a particular model within the same controller rather than having multiple controllers for each model. I find there's an impedance mismatch between what endpoints my solutions need and what REST dictates. And it requires a lot of acrobatics to map my solution onto the REST way.
- seangrogg 10y ago> REST dictates that you do it over 4 separate requests Can you point me to documentation that supports this claim? I've yet to see anything that expressly prohibits batched requests.
- bigmanwalter 10y agoI can't find a proper reference but that is my understanding after having thoroughly researched it years ago.
- daxfohl 10y agoUsers, for instance. If you think of users as a resource, then updating them is a PUT to /users/{id}. Fine, they can update their info. But you also need a way to change their password. That's a different entrypoint. Where does it go? /users/{id}/password? Is it a PUT or a POST? I mean, nothing here can't be worked around. Millions of sites do this just fine. But to me, the mental model just doesn't match up. The REST model tries to present a facade that everything is a "resource". In my experience, as apps get bigger, more and more things start not quite fitting that model. You end up having to justify to yourself why certain things go on certain endpoints and soon half your API is REST and half is some hacky REST-RPC hybrid anyway. Starting with an RPC model from the get-go, you avoid these problems. And note, REST and RPC aren't technologies. REST is a form of RPC, and you can certainly roll your own RPC protocol over REST. They're merely different ways of thinking about and modeling your application.
- dragonwriter 10y ago> If you think of users as a resource, then updating them is a PUT to /users/{id}. Fine, they can update their info. That sounds a lot more like a user profile resource than a user resource. > But you also need a way to change their password. That's a different entrypoint. Or, if you have a user resource rather than separate profile I and password resources, all partial updates could go to the same resource as PATCHes. > Where does it go? If you spend a lot of time thinking about that, you probably aren't doing REST. > Is it a PUT or a POST? Is it a replacement or a new resource? Largely, that depends on your domain model, and models under which either answer (or PATCH) make sense. As long as the definitions of your resource representations tell what operations are supported, and what they mean, for endpoints represented by the relevant link relations, it really doesn't matter all that much. > The REST model tries to present a facade that everything is a "resource". In my experience, as apps get bigger, more and more things start not quite fitting that model. I can't imagine how anything could fail to fit the model, unless you assume (as REST does not) that resources must be completely independent so that an action on one resource has no effects on the state of other resources.