[HN Gopher] Ask HN: Why isn't JSON-RPC more widely adopted?
       ___________________________________________________________________
        
       Ask HN: Why isn't JSON-RPC more widely adopted?
        
       JSON-RPC / OpenRPC seems like a great option for APIs. Why isn't it
       adopted more widely?  Many of the APIs of projects I've worked with
       look like essentially like RPC style calls. The URLs are structured
       as action/method names to do specific things. I like many of the
       benefits to an RPC approach compared to REST, GraphQL, or gRPC-Web.
       Unfortunately, the client code generation with popular options
       feels clunky when you want to use them in an RPC style. It seems
       like JSON-RPC would be better.  https://open-rpc.org
       https://www.jsonrpc.org
        
       Author : vyrotek
       Score  : 31 points
       Date   : 2023-01-01 22:34 UTC (1 days ago)
        
       | vbezhenar wrote:
       | Fashion. Lots of modern development practices is fashion-driven.
       | JSON-RPC sounds too old.
        
       | brap wrote:
       | >It is transport agnostic in that the concepts can be used within
       | the same process, over sockets, over http, websockets, or in many
       | various message passing environments.
       | 
       | I think tRPC sort of implements a transport layer for (a superset
       | of) this, no?
        
       | michaelsalim wrote:
       | Honestly, I think most projects just use a mix of whatever the
       | author likes most (Except for frameworks where it's
       | predetermined). Most would say they use REST but if you look
       | closer they actually aren't. I'm also on the opinion that it
       | doesn't really matter as long as it's documented well.
       | 
       | I've never used JSON-RPC but from the little I've read, the part
       | it is useful for is exactly the part people often customize.
        
       | user3939382 wrote:
       | Or this https://jsonapi.org/
        
       | roywashere wrote:
       | I previously worked on an embedded device with a JSON/RPC over
       | WebSockets API. I needed to use the API from a web browser
       | context.
       | 
       | There is not so much tooling for JSON/RPC in general. But it is
       | very simple. I wrote my own client library wrapper that did the
       | connection handling and request/response mapping. You'll probably
       | want to do something like that to be able to handle requests that
       | take a long time, that need to be retried, to re-open closed
       | websockets for some reason or such. But if you have that, it's
       | OK.
       | 
       | I was not aware of the open-rpc 'schema' stuff, that looks very
       | interesting, simple and useful
        
       | chubot wrote:
       | Read about the important of idempotence in distributed systems
       | 
       | HTTP GET is idempotent, which seems trivial, but it's worth more
       | than people think. With JSON-RPC you can't safely retry any RPC,
       | and that matters at scale! (If the transport is HTTP, I'm pretty
       | sure all JSON-RPC are POSTs. JSON-RPC can be good for local
       | communication like language servers, where you don't really care
       | about retrying or caching)
       | 
       | FWIW Google had/has a very RPC-like model, and when I left many
       | years ago there, I remember they came around to giving explicit
       | guidance to use a REST-like model (which you can do in an RPC
       | system). That is, where you have more nouns than verbs, and you
       | GET nouns.
        
         | dastbe wrote:
         | i think the benefit of client expectations around verbs isn't
         | the be-all-end-all. i can still write a non-idempotent fairly
         | easily.
         | 
         | writing resource oriented apis does benefit quite a bit, as it
         | often forces you into good api patterns around idempotency.
         | many aws apis and almost all new ones follow this pattern and
         | they are much betterto integrate with because of it.
        
       | benatkin wrote:
       | Lack of tooling, plus gRPC being faster and safer than JSON-RPC
       | while being as convenient as JSON-RPC except for requiring
       | tooling. Also it brands itself as an alternative to REST while
       | gRPC is branded more as being complementary to REST. Disliking
       | REST is a huge hangup for me.
        
       | tptacek wrote:
       | Perhaps, by the time they decide on a formal RPC standard, people
       | conclude they might as well use a compact optimized RPC standard,
       | like gRPC. REST-ish JSON APIs work fine and are universally
       | familiar. What's the big advantage of encoding whole requests
       | into JSON blobs, rather than just URL routing? If I'm going to do
       | that, why wouldn't I just use GraphQL, and get the graph
       | traversal part for free?
        
         | dastbe wrote:
         | there is something nice about being able to just write some
         | json and curl an endpoint. getting to this point with grpc is
         | effort.
        
           | jiggawatts wrote:
           | This to me always feels like someone saying it's nice to be
           | able to just pour crude into a couple of buckets and
           | transport them around in the back of a truck when the goal is
           | to build an oil refinery.
           | 
           | This kind of "make the trivial part easy", "get started
           | quick", "need no tooling" approach _feels_ fast... at first,
           | but then very quickly runs into nigh insurmountable problems.
           | 
           | A great analogy I heard was: "If your plan is to go to the
           | moon, you won't get there by making a fast bus."
        
       | vyrotek wrote:
       | [dead]
        
       | erdaniels wrote:
       | For my current job, I speced out what was needed for an RPC
       | solution. I ended up basically coming up with what JSON-RPC
       | provides but was missing a few things.
       | 
       | 1. Binary support for non-web clients 2. Robust code generation
       | 3. First-class cancellation/deadline concepts 4. More guidance
       | around a standard HTTP transport; kind of related to 2 5. Simple
       | schema/type definitions to assist in code generation and API
       | ecosystems
       | 
       | Ultimately, we went with gRPC and it has been pretty nice. The
       | code generation is mostly good and where it isn't, we can make
       | our own wrapping code. There have definitely been some downsides
       | and gotchas when it comes to the servers, specifically around
       | client streaming and bi-di requests. Also, grpc-web is really not
       | great and is the biggest downside so far. Overall though, it
       | feels worth it for our use case. Protobuf has been great.
        
       | joshxyz wrote:
       | For me, tradeoffs.
       | 
       | Methods can be expressed in http method, and resource can be
       | expressed in url. Response status can be expressed in http
       | statuses.
       | 
       | Some people prefer that for lower payload size. Others prefer
       | byte encoded payloads like msgpack instead of json. In trading
       | platform api's i've noticed that.
       | 
       | Also, using url based resources lets you route these requests at
       | the network proxy level (caddy haproxy nginx envoy traefik etc).
        
         | hinkley wrote:
         | > Response status can be expressed in http statuses.
         | 
         | This also simplifies circuit breaker work. The more error
         | states you can interpret at the HTTP protocol layer the simpler
         | it is to implement resiliency behavior. If you have to keep
         | parsing responses looking for errors then you have to
         | instrument every single call site separately - and distinctly.
         | The more variation the harder it is to validate that they work
         | properly.
        
       | crazygringo wrote:
       | Most API's don't need to receive deeply hierarchical data.
       | Function calls almost always take just a handful of values, and
       | if you need the occasional array, that's quite easy to manage
       | with duplicated keys ("...&filter=price<300&filter=color:red") or
       | numbered suffixes ("...&filter5=price<300&filter6=color:red") or
       | delimiters ("...&filter=price<300,color:red") as preferred.
       | 
       | While if you do need something deeply hierarchical, there's a
       | good chance it might be something massive and so you'll probably
       | just pass a URL to it as a document, rather than embed it as
       | parameters.
       | 
       | So why use JSON for input if you don't need it? It's just using
       | the simplest tools for the job. Since any web request already
       | parses GET/POST parameters, why would you add JSON into the mix
       | when the parameters can usually already handle what you're doing?
       | 
       | (But if you did have an API where input _was_ necessarily deeply
       | flexibly hierarchical, JSON RPC could very well be the perfect
       | tool for the job. Also, compare with API output which often _is_
       | very deeply hierarchical, which is why JSON is so popular on the
       | output side.)
        
       | morelisp wrote:
       | > Many of the APIs of projects I've worked with look like
       | essentially like RPC style calls.
       | 
       | There are two correct responses to this:
       | 
       | - Use a decent RPC framework to hide HTTP's semantics (which are
       | not appropriate for RPC) and to get generally better but still
       | widely-accessible tooling; I use gRPC but at this point there are
       | a dozen good-enough ones (JSON-RPC not being among them).
       | 
       | - Design a REST, or at least REST-ish, API. Map your URLs to
       | entities not actions or methods. Make each entity have a
       | canonical URL. Use content negotiation. And so on. It's more work
       | but you're also available to a lot more real HTTP clients.
       | 
       | There is also a wrong answer:
       | 
       | - Continue trying to do RPC over HTTP semantics with an
       | inefficient format and assume that having a standards document
       | per se solves literally any problem.
        
       | bullen wrote:
       | I would say not many data structures requires hierarchy, which
       | kinda is the point of JSON or XML before that.
       | 
       | Those structures that do, are often persistent; so the right
       | trade-off might be to make your protocols more lightweight (I use
       | |;, separation of just text) and then use JSON for your database
       | objects (fits well with my |;, separators).
       | 
       | Here are two examples of "packets":
       | 
       | Movement: "move|<session>|<x>,<y>,<z>|<x>,<y>,<z>,<w>|walk"
       | (where x,y,z,w are floats)
       | 
       | Storage: "save|<session>|{"name": "torch", "amount": 3}"
       | 
       | You can read more here:
       | http://fuse.rupy.se/doc/game_networking_json_vs_custom_binar...
        
       | djha-skin wrote:
       | Parsing makes it hard.
       | 
       | Consider http based rpc. I parse the first line. It tells me the
       | location and the method. Followed by a bunch of key value pair
       | headers where both the key and the value were strings. So far so
       | good, I could write all of the above in C or Go pretty easily.
       | Finally comes the body. I can unmarshall this in go or parse this
       | in C easily because I can I know what to expect in the body by
       | the time I get there. This is because I already know the method
       | and location.
       | 
       | Contrast this with json RPC. I have to partially parse the entire
       | object before I know what function is being called. Only then can
       | I fully parse the arguments because I don't know what type they
       | are (or in other words, which struct the arguments correspond to)
       | until I know what function is being called and what version of
       | RPC is being used etc.
       | 
       | Super annoying. And HTTP is just sitting there waiting to be
       | used.
       | 
       | HTTP allows for incremental parsing. I can parse the first few
       | lines separately from the body. It makes it really nice.
       | 
       | Having everything in a single json object doesn't allow for
       | incremental parsing because the standard says I can't guarantee
       | order of key value pairs when an object is concerned.
        
       ___________________________________________________________________
       (page generated 2023-01-02 23:00 UTC)