Chuyển đến nội dung chính

Lesson 5: API Design Masterclass — REST, GraphQL & gRPC

Detailed comparison of REST vs GraphQL vs gRPC: use cases, performance, trade-offs. RESTful API best practices, GraphQL schema design, gRPC with Protocol Buffers. API versioning strategies and backward compatibility.

🏗️ Architecture — Lesson 5 Lesson 5: API Design Masterclass — REST, GraphQL & gRPC

Microservices & Micro Frontend system design — From basics to Production

Part 2: Designing Microservices Backend

xdev.asia

Introduction

APIs are contracts between services and between backend and frontend. Choosing the right API style and good design determines the success or failure of a microservices architecture. This article deep-dive the 3 most popular API styles and instructions on choosing the right one for each use case.


1. REST API — The Default Choice

1.1 RESTful Best Practices

Resource-based URLs:

GET    /api/v1/products              → List products
GET    /api/v1/products/{id}         → Get product
POST   /api/v1/products              → Create product
PUT    /api/v1/products/{id}         → Update product
PATCH  /api/v1/products/{id}         → Partial update
DELETE /api/v1/products/{id}         → Delete product
GET    /api/v1/products/{id}/reviews → Nested resource

Pagination (cursor-based):

{
  "data": [...],
  "pagination": {
    "next_cursor": "eyJpZCI6MTAwfQ==",
    "has_more": true,
    "total": 1500
  }
}

Standard Error Response:

{
  "error": {
    "code": "PRODUCT_NOT_FOUND",
    "message": "Product with id '123' not found",
    "details": []
  }
}

1.2 API Versioning Strategies

StrategyExampleProsCons
URL Path/api/v1/productsExplicit, easy to routeURL changes
HeadersAccept: application/vnd.api.v2+jsonClean URLsHidden
Query Param/api/products?version=2SimpleMessy

Recommended: URL Path versioning — simple, clear, easy to route at API Gateway.

1.3 When to use REST

  • Public API for third-party
  • Simple CRUD operations
  • Critical caching (HTTP native caching)
  • Familiar team, mature tooling

2. GraphQL — Flexible Queries

2.1 Why GraphQL for Micro Frontend?

Each Micro Frontend needs different data from the same service:

# Product MFE (cần đầy đủ thông tin)
query ProductDetail {
  product(id: "123") {
    id, name, description, price
    images { url, alt }
    reviews { rating, comment, user { name } }
    relatedProducts { id, name, price }
  }
}

# Cart MFE (chỉ cần tên + giá)
query CartItem {
  product(id: "123") {
    id, name, price, thumbnail
  }
}

→ GraphQL addresses over-fetching (REST returns too many) and under-fetching (REST needs to call many endpoints).

2.2 Schema Design Best Practices

type Product {
  id: ID!
  name: String!
  slug: String!
  price: Money!
  images: [Image!]!
  category: Category!
  reviews(first: Int, after: String): ReviewConnection!
}

type Money {
  amount: Float!
  currency: Currency!
}

type ReviewConnection {
  edges: [ReviewEdge!]!
  pageInfo: PageInfo!
}

2.3 When to use GraphQL

  • Frontend needs flexibility in data fetching
  • Multiple frontend clients need different data
  • BFF layer or API Gateway aggregation
  • Complex, nested data relationships

3. gRPC — High Performance Internal

3.1 Protocol Buffers

// product.proto
syntax = "proto3";

service ProductService {
  rpc GetProduct(GetProductRequest) returns (Product);
  rpc ListProducts(ListProductsRequest) returns (stream Product);
  rpc CreateProduct(CreateProductRequest) returns (Product);
}

message Product {
  string id = 1;
  string name = 2;
  double price = 3;
  repeated string image_urls = 4;
}

message GetProductRequest {
  string id = 1;
}

3.2 gRPC Advantages

  • ~10x faster than JSON serialization (binary format)
  • HTTP/2: multiplexing, header compression
  • Strong typing: generated code, compile-time checks
  • Bi-directional streaming: real-time data flows

3.3 When to use gRPC

  • Service-to-service communication (internal only)
  • High throughput, low latency requirements
  • Streaming data (real-time updates, logs)
  • Polyglot: code generation for Go, Java, Python, Node.js

4. Decision Matrix

CriteriaRESTGraphQLgRPC
Primary useExternal API, CRUDFrontend queriesService-to-service
PerformanceGoodGoodExcellent
CachingHTTP nativeComplex (persisted queries)Manual
Learning curveLowMediumHigh
Frontend friendlyYesVeryNo (need proxy)
StreamingSSE/WebSocketSubscriptionsNative
ToolingExcellentGoodGrowing
Browser supportNativeNativeNeeds gRPC-Web

4.1 Recommendations for E-Commerce Platform

Client → Shell/MFE:     GraphQL (flexible, typed)
MFE → BFF/Gateway:      REST hoặc GraphQL
Gateway → Services:      REST (simple CRUD) + gRPC (high-perf)
Service → Service:       gRPC (internal) + Events (async)

Summary

  • REST: default choice for external API and simple CRUD
  • GraphQL: great for Micro Frontend — reduces over/under-fetching
  • gRPC: king of service-to-service — fast, typed, streaming
  • In practice: use a combination of all 3 for the correct use case

Next article: Lesson 6: Inter-service Communication — Sync, Async & Event-Driven