Selecting an API architecture is one of the most critical decisions when building modern web applications, mobile backends, and microservices. The choice dictates network payload sizes, client developer ergonomics, caching efficiency, and server CPU overhead.

In this architectural guide, we compare the three dominant API technologies—REST, GraphQL, and gRPC—analyzing transport protocols (HTTP/1.1 vs HTTP/2 multiplexing), payload serialization (JSON vs Protocol Buffers), schema enforcement, and real-world throughput benchmarks.

1. Protocol Architecture Overview

Feature REST GraphQL gRPC
Transport Layer HTTP/1.1 & HTTP/2 HTTP/1.1 & HTTP/2 (Single /graphql POST) HTTP/2 Exclusive (Multiplexed Streams)
Payload Format JSON, XML (Human readable text) JSON (Human readable text) Protocol Buffers (Compact Binary Bytecode)
Schema Enforcement Optional (OpenAPI / Swagger specs) Strict GraphQL Type System Schema Strict .proto File Contracts
Streaming Support Server-Sent Events (SSE) / WebSockets GraphQL Subscriptions (WebSockets) Native Bidirectional HTTP/2 Streaming
Best Use Case Public Web APIs & Simple CRUD Complex Mobile / Frontend Dashboards High-Throughput Inter-Microservice RPC

2. gRPC & Protocol Buffers (Protobuf) Serialization

Unlike REST and GraphQL which parse text-based JSON strings using CPU-intensive string parsers, gRPC serializes data into binary bytecode using Protocol Buffers.

A Protobuf payload replaces string keys (e.g. "user_first_name") with small 1-byte integer field tags (e.g. tag = 1). This reduces payload sizes by 70-80% and speeds up CPU serialization/deserialization by 5x-10x.

Sample Protobuf Schema Definition (`user.proto`)

syntax = "proto3"; package user.v1; // Service definition representing gRPC RPC methods service UserService { rpc GetUserProfile (GetUserRequest) returns (UserProfileResponse); rpc StreamUserAnalytics (UserAnalyticsRequest) returns (stream AnalyticsChunk); } message GetUserRequest { string user_id = 1; } message UserProfileResponse { string user_id = 1; string display_name = 2; string email = 3; int64 created_at_timestamp = 4; repeated string roles = 5; }

3. Solving Over-Fetching and Under-Fetching with GraphQL

In REST APIs, fetching a user profile with their 5 recent orders requires either:

  • Over-Fetching: Endpoint GET /users/123 returns 40 unused fields.
  • Under-Fetching / N+1 Calls: Calling GET /users/123 followed by GET /users/123/orders in 5 separate HTTP round-trips.

GraphQL allows the client frontend to declare the *exact* fields required in a single request:

# Client GraphQL Query query GetDashboardData { user(id: "usr_992") { displayName email orders(limit: 5) { id totalAmount status } } }

4. Architectural Decision Framework

  • Use REST: When building public-facing web APIs, static file endpoints, or when third-party developers require standard HTTP caching (Etag / Cache-Control headers).
  • Use GraphQL: When building rich React / iOS mobile frontends with complex nested relational data where client developer flexibility is paramount.
  • Use gRPC: For backend internal microservice communication, real-time video/telemetry streaming, or high-frequency low-latency distributed systems.

5. Frequently Asked Questions (FAQ)

Q1: Can browsers call gRPC endpoints directly?

Browsers require gRPC-Web proxy translation because native browser JavaScript APIs do not expose low-level HTTP/2 frame control needed for raw gRPC streams.