Why not REST?

455 views
Skip to first unread message

sean...@gmail.com

unread,
Nov 24, 2014, 12:35:15 PM11/24/14
to capn...@googlegroups.com
I'm confused and I'm hoping you guys can correct my thinking. 

We're building out the backend for an application and want to use microservices. We gravitate towards using REST APIs for them, but we also want to enforce the contract between them. 

I'm very interested in enforcing the contracts between services staticly. Both this project and protobuf support only RPC. Why is no one talking about static typing between REST APIs? Have you all found RPC to be a better fit for your applications?

Anyone know of an alternative project that does basically this but for REST apis? Or how should I be thinking about this?

Thank you so much!

Kenton Varda

unread,
Nov 24, 2014, 4:01:22 PM11/24/14
to sean...@gmail.com, capnproto
Hi Sean,

This is a matter of opinion and you can certainly find a lot of smart people on both sides.

The reason I don't like REST, at a philosophical level, is because I feel it constrains what can be expressed. APIs are built out of nouns (objects) and verbs (methods on those objects). In pure REST, you only get four verbs: "create" (post), "read" (get), "update" (put), "delete", aka CRUD. Any other action you might want to do -- say, "increment play count" -- typically needs to be implemented via read-modify-write.

But this read-modify-write loses information about exactly what the user was trying to do. Inevitably, the server is forced to reverse-engineer these actions by diffing the resource before and after the change. There's a bunch of reasons why a server needs to know specific actions, not just before-and-after:
- Authorization: The user might be authorized to increment the play count, but not decrement it, or may be authorized to modify some fields but not others.
- Audit logging: If you want to keep a log of actions, you probably want them to be semantic actions like "incremented play count", not "overwrote the resource with new content".
- Concurrency: If two users modify the resource at the same time, you want to be able to merge those changes. Merging streams of semantic actions is typically trivial -- just accept one action at a time and execute them in order. But merging two PUTs is hard; if you just perform them in order, the first one gets obliterated by the second.
- Public vs. private: Often the format you expose in your API is not the true underlying format of your storage, and may not be an exact representation. You may even have intentionally private information. You don't want a PUT to obliterate the private bits. Relatedly, you want to be able to evolve your storage format without old clients constantly deleting the new data whenever they do a read-modify-write.
- Non-storage behavior: APIs which aren't just glorified interfaces to a database have trouble with REST. For example, imagine an API for a game where the client controls a character moving around in a 3D world. How the heck are you going to represent that with REST? I'm sure you could think of something, but it's going to be weird.

In our programming languages, we define classes with methods. Those methods are not limited to getters and setters -- in fact, good interfaces often avoid getters and setters altogether, preferring higher-level methods representing semantic operations. We have decades of experience saying that this is the right thing. What makes the web different?

Cap'n Proto aims to extend the same object-oriented model we're used to in our programming languages to distributed systems (while accounting for network issues and providing tools to work with them, rather than trying to hide them as CORBA did). You can always define an interface limited to CRUD verbs if that's what you really want, but Cap'n Proto doesn't think you should be limited to that.

With all that said, you can of course use Cap'n Proto serialization in a regular RESTful API.

-Kenton

--
You received this message because you are subscribed to the Google Groups "Cap'n Proto" group.
To unsubscribe from this group and stop receiving emails from it, send an email to capnproto+...@googlegroups.com.
Visit this group at http://groups.google.com/group/capnproto.

Tony Arcieri

unread,
Nov 24, 2014, 4:09:19 PM11/24/14
to Kenton Varda, sean...@gmail.com, capnproto
On Monday, November 24, 2014, Kenton Varda <ken...@sandstorm.io> wrote:
The reason I don't like REST, at a philosophical level, is because I feel it constrains what can be expressed. APIs are built out of nouns (objects) and verbs (methods on those objects). In pure REST, you only get four verbs: "create" (post), "read" (get), "update" (put), "delete", aka CRUD. Any other action you might want to do -- say, "increment play count" -- typically needs to be implemented via read-modify-write.

+1. The advantage of Cap'n Proto's capability-based model (and objcap/RPC systems in general) is it provides a more natural mapping to OOP models in distributed systems, and a security model that naturally falls out of how the RPC protocol operates.

Code Climate had a good blog post on this recently, although it doesn't cover Cap'n Proto's capability-based bits:




--
Tony Arcieri

Bram de Jong

unread,
Nov 24, 2014, 4:09:45 PM11/24/14
to capn...@googlegroups.com
We're doing REST with proto buffers. And for me this is also what I would use capnp for. There are things in favor or rest and there are those in favor of RPC...

Like Kenton says, nothing stops you from using capnp as format in rest.

Bram
Reply all
Reply to author
Forward
0 new messages