{"post":{"slug":"rest-vs-rpc-2026","title":"REST vs RPC in 2026: which API style should you use?","excerpt":"REST, gRPC, tRPC, and JSON-RPC each have a place in 2026. This guide cuts through the philosophy and gives you the practical decision framework.","category":"code","date":"April 7, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">R</span>EST has dominated API design for fifteen years, but 2026 is the year most teams have at least two API styles in production: REST for public surfaces and something faster (gRPC or tRPC) for internal services. The right choice depends on who calls the API, what language they use, and what matters most — standardization, performance, or developer experience.\n\n## What changed in 2026\n\n- **tRPC v12** stabilised with first-class support for React Server Components and Next.js App Router, making it the default for new TypeScript full-stack projects.\n- **gRPC-Web** improved enough that browser clients can call gRPC services without a proxy — though tRPC still wins for browser DX.\n- **Connect (by Buf)** gained significant adoption as a gRPC-compatible protocol that works over plain HTTP/1.1 and HTTP/2, solving the browser gRPC problem cleanly.\n- **OpenAPI 3.1** and tooling like Zod-to-OpenAPI mean REST can regain type safety with less friction than before.\n\n## Core concepts\n\n**REST** (Representational State Transfer) models the API around resources. Operations are HTTP verbs on noun URLs: `GET /users/42`, `POST /orders`, `DELETE /sessions/abc`.\n\n**RPC** (Remote Procedure Call) models the API around actions. Operations are function calls: `getUser(42)`, `createOrder({...})`, `deleteSession(\"abc\")`.\n\nNeither is strictly superior — REST wins when resources are the right mental model; RPC wins when actions are.\n\n## Comparison table\n\n| Dimension | REST | gRPC | tRPC | JSON-RPC |\n| --- | --- | --- | --- | --- |\n| Transport | HTTP/1.1 or HTTP/2 | HTTP/2 | HTTP/1.1 or HTTP/2 | HTTP, WS |\n| Encoding | JSON (text) | Protobuf (binary) | JSON | JSON |\n| Type safety | Via OpenAPI codegen | .proto files | Native TypeScript | Manual |\n| Browser support | Native | gRPC-Web / Connect | Native | Native |\n| Streaming | SSE / WS | Bidirectional | Subscriptions (WS) | No |\n| Payload size | Larger | ~5× smaller | Larger | Larger |\n| Best for | Public APIs | Internal microservices | TS full-stack | Command APIs |\n\n## REST: when it is the right choice\n\n```\nGET    /orders?status=pending        → list\nPOST   /orders                       → create\nGET    /orders/42                    → read\nPATCH  /orders/42                    → update\nDELETE /orders/42                    → delete\n```\n\nREST maps naturally to CRUD resources. HTTP caching (ETags, Cache-Control) is automatic. Every HTTP client, load balancer, and CDN understands it. For public APIs, REST is almost always correct.\n\n## gRPC: when it is the right choice\n\n```proto\n// orders.proto\nservice OrderService {\n  rpc CreateOrder (CreateOrderRequest) returns (Order);\n  rpc StreamOrders (StreamRequest) returns (stream Order);\n}\n```\n\ngRPC shines when services call other services at high frequency. Protobuf binary encoding is ~5× smaller than JSON equivalents and ~3× faster to serialize/deserialize. Bidirectional streaming is first-class. The cost: no browser support without Connect/gRPC-Web, and .proto files add a build step.\n\n## tRPC: when it is the right choice\n\n```ts\n// server: define a router\nconst router = t.router({\n  getUser: t.procedure\n    .input(z.object({ id: z.string() }))\n    .query(({ input }) => db.user.findUnique({ where: { id: input.id } })),\n});\n\n// client: fully typed, no codegen\nconst user = await trpc.getUser.query({ id: \"42\" });\n//     ^? User | null  — inferred from server type\n```\n\ntRPC eliminates the schema-first step entirely. The server types flow directly to the client. No OpenAPI, no .proto, no codegen. The tradeoff: TypeScript only. If you have non-TS consumers, publish a REST or OpenAPI interface too.\n\n## How to pick\n\n1. **Public API consumed by anyone** → REST + OpenAPI spec.\n2. **Internal service-to-service at high volume** → gRPC (or Connect for HTTP/1.1 compat).\n3. **TypeScript monorepo, full-stack** → tRPC. Best DX, lowest boilerplate.\n4. **Simple command API (games, blockchain, protocol)** → JSON-RPC.\n5. **Mixed consumers (browser + server)** → REST for browser routes, gRPC internally.\n6. **You already have REST and need streaming** → Add Server-Sent Events before migrating to gRPC.\n\n## Common mistakes\n\n**Forcing every action into a REST resource.** Not everything is a noun. `POST /orders/42/cancel` is fine REST; `POST /cancelOrder` is fine RPC. Pick the model that matches the domain, not a purity ideal.\n\n**gRPC without Connect in browser-facing services.** Plain gRPC-Web requires an Envoy proxy. Use Connect protocol (Buf) instead — it speaks HTTP/1.1 and HTTP/2 natively.\n\n**tRPC without input validation.** Always use Zod (or Valibot) schemas on every procedure. Unvalidated inputs are a security risk even when TypeScript types are correct.\n\n**Versioning REST APIs in the URL (`/v1/`, `/v2/`)** when field additions would have sufficed. Version only on breaking changes; additive changes are backwards compatible.\n\n**gRPC `Any` types.** They defeat the purpose of Protobuf typing and are as unsafe as untyped JSON. Define concrete message types instead.\n\n## What to skip\n\n- **GraphQL for simple CRUD.** It is powerful but adds complexity (N+1 problem, schema stitching, persisted queries) that most apps do not need.\n- **SOAP.** It is still alive in enterprise, but no new system should choose it in 2026.\n- **Rolling a custom binary protocol.** Use Protobuf or MessagePack. Custom wire formats have no tooling.\n\n## FAQ\n\n**Can REST and gRPC coexist?**\nYes — this is the common production pattern. Expose REST for external consumers; use gRPC internally. A gateway (Kong, Traefik, Envoy) translates between them.\n\n**Is tRPC production-ready?**\nYes. tRPC v11/v12 is used in production by many large TypeScript shops. The main constraint is TypeScript-only consumers.\n\n**Does REST support streaming?**\nNot natively in the request body. Use Server-Sent Events (one-way server push) or WebSockets (bidirectional). gRPC has cleaner streaming semantics.\n\n**What is the performance difference between REST and gRPC?**\nAt the wire level, Protobuf is ~3–5× smaller and faster to parse than equivalent JSON. In practice, DB query time dominates — so the difference matters mainly at very high RPS (>10k/s) or on mobile with constrained bandwidth.\n\n## Where to go next\n\n- [Webhooks vs polling in 2026](/blog/webhooks-vs-polling-2026)\n- [How to build a REST API in Node in 2026](/blog/how-to-build-a-rest-api-in-node-2026)\n- [How to build an API in Python in 2026](/blog/how-to-build-an-api-in-python-2026)","hue":313,"metaTitle":"REST vs RPC 2026: gRPC, tRPC, and Which to Pick","metaDescription":"2026 guide comparing REST, gRPC, tRPC, and JSON-RPC. Performance, DX, tooling, and the decision framework for choosing the right API style.","keywords":["rest vs rpc 2026","grpc vs rest 2026","trpc vs rest","rest api vs grpc performance","rpc api design 2026","json-rpc vs rest","api design best practices 2026","trpc typescript 2026","grpc microservices 2026","rest api vs graphql vs grpc"],"tldr":["**REST is the default for public APIs** — ubiquitous tooling, browser-native, caching built in.","**gRPC wins for internal microservices** — binary encoding, ~5× lower payload size, streaming support.","**tRPC is the best DX for TypeScript full-stack** — end-to-end type safety with zero schema files.","**JSON-RPC is niche but useful** for simple command-style APIs (Ethereum, LSP, JSON:API variants).","**Skip:** designing a REST API and fighting to map every action to a resource — some things are just commands."],"readTime":"4 min read","wordCount":987},"related":[{"slug":"rest-vs-graphql-2026","title":"REST vs GraphQL in 2026: which API style should you build?","excerpt":"REST is still the default for most APIs, but GraphQL has found its genuine niche. This 2026 guide gives you the honest trade-offs and a concrete decision framework.","category":"code","date":"April 7, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":307},{"slug":"rest-vs-graphql-vs-grpc-2026","title":"REST vs GraphQL vs gRPC 2026: Which API Style Wins","excerpt":"REST, GraphQL, and gRPC solve different problems for different callers, and picking the wrong one shows up as friction years later. Here is a direct, three-way comparison for 2026 and a simple way to decide.","category":"code","date":"August 8, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":320},{"slug":"how-to-build-a-rest-api-2026","title":"How to build a REST API in 2026: the complete guide","excerpt":"REST APIs are still the backbone of most web backends in 2026. This guide covers design, implementation, validation, auth, and deployment correctly.","category":"code","date":"April 14, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":322}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"rest-vs-graphql-2026","title":"REST vs GraphQL in 2026: which API style should you build?","excerpt":"REST is still the default for most APIs, but GraphQL has found its genuine niche. This 2026 guide gives you the honest trade-offs and a concrete decision framework.","category":"code","date":"April 7, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":307},"older":{"slug":"saving-vs-investing-2026","title":"Saving vs investing in 2026: when to do each and how to balance both","excerpt":"Saving and investing are not competing strategies — they serve different jobs. Knowing when to save and when to invest is the foundation of smart money management.","category":"finance","date":"April 7, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":274}}