RPC-Style APIs: JSON-RPC, XML-RPC, and the Road to gRPC

API Types & Design — RPC-Style APIs: JSON-RPC, XML-RPC, and the Road to gRPC
API Types & Design
Chapter 6 · RPC-Style APIs: JSON-RPC, XML-RPC, and the Road to gRPC

📞 RPC-Style APIs: JSON-RPC, XML-RPC, and the Road to gRPC

REST (Chapter 3) models an API around resources — nouns. SOAP (Chapter 5) is technically an RPC-style protocol too, just wrapped in a lot of formal ceremony. This chapter covers the lighter-weight RPC styles that skip SOAP's envelope-and-WSDL machinery while keeping its core idea — "call a specific function, with these arguments, and get a result back" — and traces how that same idea evolves into gRPC, which gets its own full course on this site.

The RPC Mental Model: Call a Function, Not a Resource

RPC stands for Remote Procedure Call. Instead of asking "give me the user resource with id 42" (REST's noun-first thinking), an RPC-style API asks "call the getUser procedure, passing 42 as an argument" — a verb-first, function-call mental model.

Resource Call vs. Method Call — Same Operation

REST (resource-oriented)

GET /users/42
The URL names a resource; the HTTP method names the action.

RPC (method-oriented)

getUser(42)
The name of the call itself IS the action — there's no separate "resource" being addressed.

JSON-RPC: A Lightweight Spec

JSON-RPC is a small, precisely defined specification (currently version 2.0) for making RPC calls using plain JSON. Every request names a method, supplies params, and includes an id used to match the eventual response back to this specific request — important once multiple calls might be in flight or batched together:

A JSON-RPC 2.0 Request/Response Pair

// Request { "jsonrpc": "2.0", "method": "subtract", "params": [42, 23], "id": 1 } // Response { "jsonrpc": "2.0", "result": 19, "id": 1 }

Notice there's just one endpoint conceptually — every call typically goes to the same URL, with the method field itself saying what to actually do. That's a real structural difference from REST, where the URL path is usually what distinguishes one operation from another.

XML-RPC: The Historical Predecessor

XML-RPC came first — dating to 1998, it's the same "call a named method with arguments" idea as JSON-RPC, just expressed in XML rather than JSON. It's notably simpler than SOAP (no WSDL, no elaborate envelope with headers), but SOAP itself was actually built as an extension of XML-RPC's original ideas. Today, JSON-RPC has largely displaced it for new development — JSON parses natively in JavaScript and most modern languages, while XML needs an extra parsing step. XML-RPC mostly survives now in older systems that predate JSON-RPC's rise.

Where JSON-RPC Actually Shows Up Today

JSON-RPC isn't just historical trivia — it's genuinely in active use. Ethereum and many other blockchain networks expose their node APIs as JSON-RPC. Closer to a web developer's daily tools: the Language Server Protocol (the protocol behind VS Code's and many editors' code intelligence — autocomplete, go-to-definition, error squiggles) is itself built on JSON-RPC 2.0, running between the editor and a separate "language server" process.

The Road to gRPC

gRPC takes this exact same "call a function" mental model and modernizes it: instead of JSON or XML, it uses Protocol Buffers — a compact, strongly-typed binary schema format that plays a similar role to SOAP's WSDL (a formal, enforceable contract) but is far lighter weight and easier to work with. Instead of HTTP/1.1, it runs on HTTP/2, which supports genuine bidirectional streaming rather than one request producing exactly one response. This chapter won't go further into gRPC's actual mechanics — Protocol Buffer schema design, the four streaming modes, code generation — that's exactly what the site's dedicated gRPC course covers in full.

XML-RPCJSON-RPCgRPC
FormatXMLJSONProtocol Buffers (binary)
TransportHTTP/1.1HTTP/1.1 (usually)HTTP/2
Formal contractNoneNone (informal convention)Yes — the .proto file itself
Status todayMostly legacyActively used (blockchain nodes, LSP)Actively growing, especially in microservices

💻 Coding Challenges

Challenge 1: Convert REST to RPC

Given the REST call GET /users/42, write the equivalent JSON-RPC 2.0 request calling a getUser method with the same effective meaning.

Goal: Practice translating between REST's resource-oriented thinking and RPC's method-oriented thinking.

→ Solution

Challenge 2: Write a JSON-RPC Request/Response Pair

Write a correct JSON-RPC 2.0 request calling an add method with the numbers 7 and 5, along with the matching response — make sure the id values line up correctly.

Goal: Practice the exact JSON-RPC 2.0 shape, including the field that ties a response back to its request.

→ Solution

Challenge 3: Choosing Within the RPC Family

Match each scenario to XML-RPC, JSON-RPC, or gRPC, and justify each choice: (a) integrating with a 15-year-old legacy system that only speaks an older RPC format, (b) a new internal microservice needing very high-throughput, low-latency binary communication with strict typing, (c) a small hobby project's simple JSON-based API between two of your own scripts.

Goal: Practice applying this chapter's comparison table to realistic, distinct scenarios.

→ Solution

⚠️ Gotcha: RPC-Style APIs Don't Get REST's Free HTTP Caching

Chapter 3 covered cacheability as one of REST's architectural constraints — a GET request to a stable resource URL can be cached by browsers, proxies, and CDNs using ordinary HTTP caching mechanisms, for free. RPC-style APIs usually break this: since every call typically goes to the same endpoint (often via POST, with the actual operation named inside the body rather than the URL), there's no unique, stable URL per operation for standard HTTP caching to key off. This isn't a flaw exactly — it's a genuine tradeoff that comes with the method-call model — but it means caching has to be built deliberately at the application layer if it's needed at all, the same caveat GraphQL's course raises about its own single-endpoint design.

🎯 What's Next

The next chapter covers Webhooks: APIs That Call You — a genuinely different direction, where instead of your code asking a server for something, the server reaches out and calls you the moment something happens.