API Design

REST vs RPC: How to Choose an API Style

Compare REST and RPC API styles through resources, actions, payload design, caching, versioning, and backend team workflows.

REST and RPC are both ways to expose backend behavior over a network. The best choice depends less on fashion and more on how your domain is shaped, how clients will use the API, and how much you want HTTP semantics to be part of the contract.

Quick answer

Choose REST when your API is centered on resources such as users, orders, invoices, repositories, or tickets. Choose RPC when your API is centered on actions, commands, calculations, or workflows that do not map cleanly to a resource lifecycle.

Many real systems use both. The important part is to make the style obvious and consistent enough that client developers can predict how the next endpoint will behave.

REST thinks in resources

REST models the system as resources addressed by URLs. HTTP methods describe the operation.

GET /orders/123
POST /orders
PATCH /orders/123
DELETE /orders/123

This style works well when clients mostly create, read, update, and delete domain objects. It also aligns naturally with HTTP caching, status codes, browser tooling, logs, API gateways, and documentation tools.

A RESTful order API might expose the order as the main resource and represent lifecycle transitions as state changes:

PATCH /orders/123
{
  "status": "cancelled"
}

That can be clean when the transition is simple and the resource model is stable.

RPC thinks in actions

RPC models the API as callable procedures or commands.

POST /calculateShippingQuote
POST /approveInvoice
POST /runFraudCheck

This style works well when the domain is action-heavy and the operation does not map cleanly to a single resource. A fraud check, report export, password reset request, deployment trigger, or shipping quote may be easier to understand as a command than as a forced resource update.

RPC can also be a good fit for internal service-to-service APIs, especially when teams use gRPC, strongly typed contracts, and generated clients.

Practical tradeoffs

QuestionREST tends to fitRPC tends to fit
What is the API centered on?Resources and representationsActions and commands
How important is HTTP caching?Often importantUsually less central
How predictable should URLs be?Very predictable resource pathsPredictable method names
Are clients broad and public?Often a good public API defaultGood when commands are clearer
Are services internal and typed?Still possibleOften strong with gRPC/protobuf

REST usually gives teams more predictable URL structures and better compatibility with HTTP infrastructure. RPC can be simpler when the product is mostly commands, workflows, or computation.

The worst API style is usually a confused hybrid: resource URLs that hide complex verbs, or RPC methods that duplicate every CRUD operation without a clear naming system.

Payload design

REST responses often return resource representations:

{
  "id": "ord_123",
  "status": "paid",
  "totalCents": 4200
}

RPC responses often return operation results:

{
  "approved": true,
  "riskScore": 0.14,
  "reason": "low_risk_customer"
}

Neither shape is automatically better. What matters is whether the payload matches the mental model of the endpoint. Do not make clients reverse-engineer whether an endpoint is returning a resource, a command result, or a workflow state.

Status codes and errors

REST APIs usually lean more heavily on standard HTTP status codes such as 200, 201, 400, 404, 409, and 422. RPC-style APIs may still use HTTP status codes, but the application error code in the response body often carries more meaning.

For public HTTP APIs, do not return 200 OK for every failure just because the transport request succeeded. Client SDKs, gateways, retries, dashboards, and support tools all benefit from meaningful status codes.

Versioning

REST versioning often happens through URL paths, headers, or media types. RPC versioning often happens through method names, package names, protobuf evolution rules, or endpoint namespaces.

The same principle applies either way: avoid breaking existing clients without a migration path. API style does not remove the need for compatibility discipline.

How to choose

Choose REST when the domain has stable resources and standard lifecycle operations. Choose RPC when the domain is command-oriented, workflow-heavy, or closer to a service method than a resource representation.

A useful decision rule is this: if you can name the important thing with a noun and the HTTP method feels natural, REST may fit. If the most honest name is a verb phrase, RPC may be clearer.

Common mistakes

The first mistake is using REST vocabulary while designing pure RPC endpoints, such as POST /orders/123/cancelOrderNowAndRefund. If the operation is really a command, make that command explicit and document it well.

The second mistake is assuming RPC means no structure. RPC method names, request schemas, response schemas, error codes, and idempotency rules still need design consistency.

The third mistake is mixing styles without boundaries. It is reasonable for a public API to be mostly REST while internal services use gRPC. It is harder when one public API randomly switches styles from endpoint to endpoint.

Read REST API Design Checklist before publishing a REST contract, PUT vs PATCH in REST APIs for update semantics, and OpenAPI Explained for Backend Developers for contract documentation. Read REST API Status Codes Explained and REST API Error Handling Best Practices before finalizing public HTTP behavior. Read API Versioning Explained when planning long-lived client contracts. Use the HTTP Status Code Lookup as a quick reference while designing responses. For the full sequence, browse the API Design Learning Path.