
Show HN: WebRPC – a simple alternative to REST and SOAP - gk_brown
https://github.com/gk-brown/WebRPC
======
captn3m0
While this may be simpler than REST and cleaner than SOAP, I find REST to be
far more elegant.

>An HTTP 200 is returned on successful completion, and HTTP 500 is returned in
the case of an error (i.e. an exception). Note that exceptions are intended to
represent unexpected failures, not application-specific errors. No other HTTP
status codes are supported.

Now you are just using HTTP as your transport layer, you can very well make it
customised to your particular needs rather than defining a spec. This might
result in easier client code, but why not use Thrift if that is what you need.

~~~
gk_brown
I haven't used Thrift myself, but I just took a quick look at the docs. My
initial reaction is that Thrift seems to be a bit heavier. WebRPC doesn't
require any intermediate interface definitions and doesn't create language-
specific client proxies. Method invocations are all dynamic (although you
could easily wrap the invocation API in a statically typed adapter if you
wanted to).

WebRPC isn't meant to be a replacement for REST - just an alternative.
Sometimes it's simply more convenient to think in terms of "methods" than
"resources".

~~~
malandrew
IDLs are awesomely useful and you can build all sorts of things on that
abstraction, especially if you have a parser that produces a standard AST (I
wrote a PegJS parser that takes the Thrift IDLs and creates a plain old
javascript object AST that can be used for things like: (1) writing dynamic
serializers/deserializers for binary data (uber/thriftrw), (2) validators (not
yet written, but will both lint as well as check for backwards compatibility
when IDLs are updated); (3) bash autocompletion for an RPC api via a curl-like
command (soon to land in uber/tcurl))

At Uber, we started with Apache Thrift, but found many things about it limited
and broken with dubious code quality for some languages. Furthermore we had
more ambitious ideas like application layer sharding (uber/ringpop) and
service discovery and routing (uber/hyperbahn).

We're still using the thrift protocols (uber/thriftrw) with our rpc library
(uber/tchannel), but could have built on top of another IDL format like
protobufs (v3).

For those curious about the RPC interface, just check out:
[https://tchannel.readthedocs.org/en/latest/](https://tchannel.readthedocs.org/en/latest/)

The interface supports all sorts of things

This is all over TCP right now and designed for performance and service to
service communication, but there is nothing preventing the addition of HTTP
(via XHR or WebSockets) as a transport for allowing web apps to speak with
tchannel services. I contributed to the Apache Thrift implementation that
allows this
([https://github.com/apache/thrift/blob/master/lib/nodejs/lib/...](https://github.com/apache/thrift/blob/master/lib/nodejs/lib/thrift/web_server.js)).
The implementation for tchannel would be similar, but rely on XHR/WS in the
browser and the `http` module instead of the `net` module in NodeJS on the
server. It's trivial to write a proxy frontend that relays TJSONProtocol on
the frontend to a Thrift binary protocol like TBinaryProtocol or
TCompactProtocol.

[https://github.com/uber/hyperbahn](https://github.com/uber/hyperbahn)
[https://github.com/uber/tchannel](https://github.com/uber/tchannel)
[https://github.com/uber/ringpop-node](https://github.com/uber/ringpop-node)
[https://github.com/uber/ringpop-go](https://github.com/uber/ringpop-go)
[https://github.com/uber/idl](https://github.com/uber/idl)
[https://github.com/uber/tcurl](https://github.com/uber/tcurl)
[https://github.com/uber/tcap](https://github.com/uber/tcap)

etc.

~~~
gk_brown
That sounds cool. WebRPC isn't meant to be an "everything to everyone"
solution. It's main advantage is simplicity and low overhead. It allows you to
quickly and easily build a service tier that is consumable by multiple
clients. But if your requirements scale beyond what WebRPC provides, Thrift
sounds like a great option.

~~~
stephenr
Thrift is such a broken mess I _willingly_ opted instead to fork and update a
Java project that exposes xml over http.

Thrift must have been written by people who though SOAP was _too easy to use_
and that developer lives should be made harder.

~~~
malandrew
Completely agree that the thrift stuff is a mess, which is why we only used
the one interesting part, the IDL, for our system. These days, proto3 would be
viable, but wasn't feature rich enough at the time for our needs when we were
evaluating options.

------
leejoramo
So how does this compare to XML-RPC?

I see that it is using JSON instead of XML.

> Support currently exists for implementing web RPC services in Java, and
> consuming services in Java, Objective-C/Swift, or JavaScript.

While I may personally feel that JSON is a better format than XML, there are a
implementations of XML-RPC for almost all languages and platforms which is a
huge advantage.

~~~
gk_brown
WebRPC is a lot lighter than XML-RPC (or JSON-RPC). It's really just a thin
layer on top of HTTP. Arguments are passed in the query string (or as form
parameters, if POSTing), and the response value is returned directly as JSON.
There's no body or envelope to parse. This makes WebRPC services really easy
to consume by any client that supports HTTP and JSON (which is pretty much
most platforms). WebRPC services are also really easy to test, since you can
execute a method and get the results back simply by typing a URL in your
browser.

------
Morst
We should not use HTTP for such things. It is against HTTPs intentions. Just
use any other protocol.

~~~
gk_brown
If you are implementing a REST service, then I agree with you 100%. WebRPC is
simply a different interpretation. In WebRPC, GET means "get the result of
executing this method". POST basically means the same thing, but the arguments
are passed in the message body (just like an HTML form).

The client libraries all use POST internally - GET is primarily useful for
testing and debugging (so you can easily execute a method in the browser).

------
iambvk
Does it open a socket for every rpc?

~~~
gk_brown
Not sure. The client libraries don't work with sockets directly. The Java
client uses HTTPURLConnection, the Objective-C/Swift client uses NSURLSession,
and the JavaScript client uses XMLHttpRequest. You'd have to check the
documentation for each of those to see what they might be doing under the
hood, or what options you might have for configuring them. Same goes for the
server, which just sits on top of a servlet container. You'd have to see the
container docs to see what your options are.

