DEV Community

ZNY
ZNY

Posted on

The Complete Guide to API Design in 2026: REST, GraphQL, and tRPC in Production

The Complete Guide to API Design in 2026: REST, GraphQL, and tRPC in Production

The API design landscape in 2026 settled into three clear patterns. REST for public APIs and microservices. GraphQL for complex data requirements. tRPC for TypeScript-to-TypeScript full-stack applications.

Each has a legitimate use case. The mistakes happen when teams choose based on hype rather than fit.

REST in 2026: Still the Default for a Reason

REST APIs remain the dominant pattern for:

  • Public and partner APIs (ease of documentation and tooling)
  • Microservices that need simple, well-defined contracts
  • Teams without TypeScript full-stack expertise

The key REST improvements in 2026:

Better Error Responses

{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Request validation failed",
    "details": [
      {
        "field": "email",
        "code": "INVALID_FORMAT",
        "message": "Must be a valid email address"
      }
    ],
    "requestId": "req_a1b2c3d4e5"
  }
}
Enter fullscreen mode Exit fullscreen mode

The requestId addition transformed our debugging. Every error now links to structured logs.

API Versioning

Still the most contentious topic. Our 2026 recommendation: URL versioning for major breaking changes only.

GET /v1/users     ← Major version, breaking changes
GET /users?since= ← Minor additions, no versioning
Enter fullscreen mode Exit fullscreen mode

Rate Limiting Headers

Standardized rate limit headers finally emerged as a convention:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1716560400
Retry-After: 3600
Enter fullscreen mode Exit fullscreen mode

GraphQL: When It's Actually the Right Choice

GraphQL shines when:

  1. Complex, nested data requirements: A dashboard that pulls users, their orders, the products in those orders, and supplier data for those products. With REST, this requires 4+ requests or a massively overfetching endpoint.

  2. Multiple client types: Mobile (needs different data than desktop) and web clients with different requirements. GraphQL's flexible queries handle this cleanly.

  3. Rapid client evolution: When your mobile and web teams work independently, GraphQL's schema contract reduces coordination overhead.

When GraphQL Is Wrong

  • Simple CRUD: If you're mostly doing Create, Read, Update, Delete on single resources, REST is simpler and has better tooling for this pattern.
  • File uploads: Still awkward in GraphQL. Use REST for this.
  • Caching: REST with HTTP caching is simpler and more efficient for publicly cacheable data.

The Schema Design Discipline

GraphQL's superpower is the type system. But it requires discipline:

type User {
  id: ID!
  email: String!
  createdAt: DateTime!

  # Explicitly define what's included, avoid N+1
  orders(first: Int, after: String): OrderConnection!
  totalOrderCount: Int! # Pre-computed, not derived
}

type OrderConnection {
  edges: [OrderEdge!]!
  pageInfo: PageInfo!
  totalCount: Int!
}
Enter fullscreen mode Exit fullscreen mode

The totalCount as a separate field (pre-computed) prevents COUNT(*) queries on every request.

tRPC: The TypeScript Revolution

tRPC became the default for TypeScript monorepos in 2025-2026. The appeal is real: end-to-end type safety without code generation.

// Server: define the procedure
const userRouter = router({
  getById: publicProcedure
    .input(z.object({ id: z.string() }))
    .query(async ({ input }) => {
      return db.user.findUnique({ where: { id: input.id } });
    }),
});

// Client: fully typed, no code generation
const user = await trpc.user.getById.query({ id: userId });
// user is typed based on the server definition
Enter fullscreen mode Exit fullscreen mode

The productivity gains are real for teams already in TypeScript. The tradeoff: you need a TypeScript monorepo, and the learning curve for Zod schemas is real.

When to Choose tRPC

Perfect for: Full-stack TypeScript teams, rapid development, internal tools, startups moving fast
Not for: Multi-language environments, public APIs, teams without TypeScript expertise

The Decision Framework

Is your team TypeScript-first with a monorepo?
  → YES → tRPC for internal services, REST for public APIs
  → NO  → Continue below

Do clients need different data shapes for the same endpoint?
  → YES → GraphQL
  → NO  → Continue below

Is this a public/partner API?
  → YES → REST (better tooling, easier to document, broader client support)
  → NO  → REST is probably fine, GraphQL if the data model is complex
Enter fullscreen mode Exit fullscreen mode

The Tooling That Matters in 2026

For REST:

  • Zod for input validation (replaced Joi and class-validator)
  • Hono or Fastify for the framework (Express is showing its age)
  • scalar or redocly for API documentation

For GraphQL:

  • GraphQL Yoga 5 (replaced Apollo Server as the default)
  • pothos or nexus for schema-first development
  • Studio for Explorer and monitoring

For tRPC:

  • tanstack-query as the client (works with tRPC natively)
  • Zod for input validation
  • Kysely for type-safe database queries

This article contains affiliate links. If you sign up through the links above, I may earn a commission at no additional cost to you.

Ready to Build Your Online Business?

Get started with Systeme.io for free — All-in-one platform for building your online business with AI tools.

Top comments (0)