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
| Strategy | Example | Pros | Cons |
|---|---|---|---|
| URL Path | /api/v1/products | Explicit, easy to route | URL changes |
| Headers | Accept: application/vnd.api.v2+json | Clean URLs | Hidden |
| Query Param | /api/products?version=2 | Simple | Messy |
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
| Criteria | REST | GraphQL | gRPC |
|---|---|---|---|
| Primary use | External API, CRUD | Frontend queries | Service-to-service |
| Performance | Good | Good | Excellent |
| Caching | HTTP native | Complex (persisted queries) | Manual |
| Learning curve | Low | Medium | High |
| Frontend friendly | Yes | Very | No (need proxy) |
| Streaming | SSE/WebSocket | Subscriptions | Native |
| Tooling | Excellent | Good | Growing |
| Browser support | Native | Native | Needs 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