send(payload).then(reply => ...) send(payload).then(reply => ...)But client and server use it to maintain a record of events.
JSON-RPC is request-response only; the server cannot send unsolicited messages. gRPC supports bidirectional streaming, but I understand that setting it up is more complex than WebSockets.
I will concede that horizontal scaling of RPC is easier because there's no connection overhead.
Ultimately, it really depends on what you're trying to build. I also don't underestimate the cultural aspect; fair or not, JSON-RPC feels very "enterprise microservices" to me. If you think in schemas, RPC might be a good fit.
That solves none of the issues outlined in the post or the comments.
At its core, JSON-RPC boils down to "use `id` and `method` and work the rest out", which is acceptably minimal but does leave you with a lot of other issues to deal with.
What people seem to be often missing for some reason is that those two map naturally to existing semantics of the programming language they're already using.
What it means in practice is that you are exposing and consuming functions (ie. on classes) – just like you do in ordinary libraries.
In js/ts context it usually means async functions on classes annotated with decorators (to register method as rpc and perform runtime assertions) that are event emitters – all concepts already familiar to developers.
To summarize you have system that is easy to inspect, reason about and easy to use - almost like any other package in your dependency.
Introducing backward compatible/incompatible changes also becomes straight forward for everybody ie. following semver on api surface just like in any ordinary package you depend on.
Those straight forward facts are often missed and largely underappriciated.
ps. in our systems we're introducing two deviations – error code can also be strings, not just numbers (trivial); and we support async generators (emitting individual objects for array results) – which helps with head of line blocking issues for large resultsets (still compatible with jsonrpc at protocol level, although it would be nice if they supported it upstream as dedicated semantic in jsonrpc 2.1 or something). They could also specify registering and unregistering notification listeners at the spec level so everybody is using the same scheme.
The terminology is not ideal, I grant, but a JSON-RPC "notification" (a request with no id) is just a request where the client cannot, and does not, expect any response, not even a confirmation that the request was received and understood by the server. It's like UDP versus TCP.
> emitting individual objects for array results
This is interesting! How does this change the protocol? I assume it's more than just returning multiple responses for the same request?
Our implementation emits notifications for entries and rpc returns done payload (which is largely irrelevant just the fact of completion is relevant).
As I said it would be nice if they’d support generator functions at the protocol level.
Honestly, I'm a little surprised and more than a bit depressed how we effectively reinvent the OSI stack so often...