REST with JSON or XML, or gRPC? Choosing an API Style for Your Application

REST, JSON, XML, and gRPC are often compared as if they were the same kind of thing. They are not. What each one is good at, real payload size measurements, where XML is still required in Indonesia, and a simple way to decide which to use for public APIs, partner integrations, and internal services.

Published 10 min read
Source code on a monitor in a dark code editor

When a team starts designing an API, the question is often phrased as "REST, JSON, XML, or gRPC?" That mixes two different decisions. REST and gRPC are ways of structuring the conversation between two systems. JSON, XML, and Protocol Buffers are formats for the data inside that conversation. REST is usually paired with JSON, sometimes with XML, and gRPC almost always with Protocol Buffers. Separating the two questions makes the choice much easier, and in most projects the answer turns out to be a combination rather than a single winner.

Two Separate Decisions

REST is an architectural style built on plain HTTP. Data is exposed as resources with URLs, such as /orders/10482, and clients act on them with HTTP methods: GET to read, POST to create, PUT or PATCH to change, DELETE to remove. The server answers with standard status codes like 200, 201, 404, or 422. Nothing in REST dictates the data format, which is why the same API can return JSON to one client and XML to another.

gRPC, originally developed at Google, is a remote procedure call framework. Instead of resources, you define services with methods, such as OrderService.GetOrder, in a .proto file. From that file, tools generate client and server code in Go, Java, Kotlin, Python, C#, Node.js, Dart, and other languages. It runs over HTTP/2 and encodes messages in Protocol Buffers, a compact binary format. Calling a remote service feels like calling a local function.

REST with JSON: The Default for a Good Reason

Most APIs on the internet today, from payment gateways to marketplaces and shipping services, are REST with JSON. Every programming language can read JSON, every browser understands it natively, and a developer can test an endpoint with curl or Postman and read the response without any extra tools. HTTP caching, CDNs, API gateways, and logging tools all work with it out of the box.

The weakness of JSON is that it has no built-in contract. Nothing stops a server from sending a price as a string one day and a number the next. Teams solve this by writing an OpenAPI specification and validating requests and responses against it, which also gives you documentation and generated client libraries. A few details are worth agreeing on early:

  • Large integer IDs should be sent as strings. JavaScript can only represent integers exactly up to 9,007,199,254,740,991, so a 64-bit ID from a database can silently change when a browser parses it.
  • Money should be sent as an integer in the smallest unit, or as a decimal string, never as a floating-point number.
  • Dates should use ISO 8601 with a time zone offset, for example 2026-10-30T09:15:00+07:00, so a server in Singapore and a client in Jakarta agree on what time it is.
  • Errors should follow one consistent shape across every endpoint. RFC 9457, Problem Details for HTTP APIs, is a ready-made standard for this.

XML: Rarely Chosen, Often Required

Few teams pick XML for a new API today, but many still have to work with it, because the other side demands it. Older enterprise and banking systems expose SOAP web services, which are XML by definition. Financial messaging is moving to ISO 20022, an XML-based standard that Bank Indonesia adopted for BI-FAST. Many ERP systems and older desktop applications also exchange data as XML files, so an integration with them often means reading and writing XML whether you like it or not.

XML does have real strengths. An XSD schema can validate a document strictly before it is processed, namespaces allow several standards to be combined in one document, and XML digital signatures can sign part of a document. The price is verbosity, more complex parsing, and a well-known security risk: XML External Entity (XXE) attacks, where a crafted document makes the parser read local files or call internal URLs. Any service that accepts XML from outside should disable external entities and DTD processing in its parser.

A practical pattern is to keep your own system on JSON and isolate XML in an adapter at the edge: one module that converts between your internal data and the XML format the partner or government system expects, with its own tests against their official schema.

gRPC: Built for Service-to-Service Traffic

gRPC shines where a team controls both ends of the connection, typically between microservices inside one platform. The .proto file is a strict contract: if the order service changes a field type, the code that calls it fails to compile instead of failing in production. Protocol Buffers are designed to evolve, too. New fields can be added without breaking old clients, as long as existing field numbers are never reused.

  • Four call types: a single request and response, a stream from the server, a stream from the client, and streams in both directions. Streaming is useful for live location tracking, progress updates, or sending large data sets in chunks.
  • Deadlines are built in. A client says how long it is willing to wait, and the deadline travels along the chain of calls, so a slow downstream service does not hold every caller hostage.
  • One HTTP/2 connection carries many calls at once, which cuts connection overhead between services that talk to each other constantly.
  • Generated clients mean nobody writes HTTP calls and JSON parsing by hand, and every language uses the same contract.

The trade-offs show up outside the data centre. Browsers cannot call gRPC services directly; a web frontend needs gRPC-Web through a proxy such as Envoy, or a compatible protocol such as Connect. Messages are binary, so debugging needs tools like grpcurl instead of a browser or plain curl. And because HTTP/2 keeps connections open for a long time, a load balancer that only balances connections, not individual requests, can send all traffic to one server. Check that your load balancer, ingress, or proxy supports gRPC properly before committing to it.

How Much Smaller Is Protobuf, Really?

Size is the argument most often made for gRPC, so we measured it. We encoded the same order, once with three line items and once with a hundred, as compact JSON, as XML, and as Protocol Buffers with protoc, and then compressed each with gzip, which is what happens to most HTTP responses in production.

PayloadJSONXMLProtobuf
Order with 3 items, raw345 bytes528 bytes166 bytes
Order with 3 items, gzip257 bytes314 bytes192 bytes
Order with 100 items, raw7,385 bytes10,575 bytes3,545 bytes
Order with 100 items, gzip1,123 bytes1,241 bytes1,127 bytes

Uncompressed, Protobuf is about half the size of JSON and a third of XML. Once compression is applied, most of that difference disappears, and for the larger order JSON and Protobuf end up practically the same. The real gains of Protobuf are elsewhere: less CPU spent encoding and decoding, which matters for services handling thousands of calls per second, and a contract enforced by the compiler. For a typical web or mobile API with compression enabled, bandwidth alone rarely justifies moving away from JSON.

Side by Side

REST + JSONREST or SOAP + XMLgRPC + Protobuf
ContractOptional, through OpenAPIStrict, through XSD or WSDLMandatory, through .proto files
Called from a browserYes, nativelyYes, but awkwardOnly through gRPC-Web or Connect
Human readableYesYes, but verboseNo, binary
StreamingLimited, via SSE or WebSocketNoBuilt in, both directions
Code generationAvailable from OpenAPIAvailable from WSDLStandard part of the workflow
Typical usePublic APIs, web and mobile apps, partner integrationsBanking, government, and legacy enterprise systemsInternal microservices and high-volume service calls

Which One to Use

  • An API used by a web frontend, a mobile app, or outside developers: REST with JSON and an OpenAPI specification. It is the easiest for others to adopt and the easiest to debug.
  • An integration where the other side defines the format, such as a bank, a government system, or an older ERP: use what they require, usually XML, and keep it in a separate adapter.
  • Many internal services written in different languages, with heavy traffic or a need for streaming: gRPC between those services.
  • A platform with both: gRPC inside, and a REST and JSON gateway at the edge for browsers and partners. Tools such as grpc-gateway or Envoy can translate between the two from the same .proto definitions.

Whichever you choose, the habits that keep an API healthy are the same: write the contract first and keep it in version control, version breaking changes instead of slipping them in, set timeouts on every call, make payment and order endpoints idempotent so a retry does not charge a customer twice, and log enough to trace a request across services. If you are planning an API or an integration and would like a second opinion on the design, our team builds and maintains these systems for clients every day.

Key takeaways

  • REST and gRPC are ways to structure an API; JSON, XML, and Protocol Buffers are data formats. Decide them separately.
  • REST with JSON is the right default for public APIs, web frontends, mobile apps, and partner integrations.
  • XML is still required by SOAP services, ISO 20022 banking messages such as BI-FAST, and many older ERP systems. Isolate it in an adapter and disable external entities in the parser.
  • gRPC suits internal service-to-service traffic, streaming, and multi-language teams, but needs gRPC-Web or Connect for browsers and a load balancer that understands HTTP/2.
  • In our measurement Protobuf was half the size of JSON uncompressed, but almost the same after gzip. Its main advantages are CPU efficiency and a strict contract.
Share this article

Related articles

More articles on software development, AI, cloud, and infrastructure.

Close-up of network cables plugged into a rack switchBackend Development

9 min read

Business System Integration with APIs: Marketplaces, Stock, and Accounting

How to connect marketplaces, stock, and Accurate or Jurnal without staff re-typing data: integration patterns, webhooks versus polling, idempotency, master data and SKU mapping, retries and error queues, daily reconciliation, security, and when n8n or Make is enough.

Let’s talk

Looking for a software development partner?

Tell us about your project, what you need to build, and the challenges you are facing. We can discuss the technical approach, scope, timeline, and estimated cost.

Start a conversation