GraphQL vs REST API: Chọn Đúng Công Nghệ Cho Dự Án
GraphQL và REST là hai approaches phổ biến nhất cho API design. Mỗi approach có điểm mạnh và điểm yếu riêng. Bài viết này sẽ so sánh chi tiết GraphQL và REST để giúp bạn chọn đúng công nghệ cho dự án của mình.
1. Giới Thiệu
REST (Representational State Transfer) đã là standard cho API design trong nhiều năm. GraphQL, được Facebook phát triển vào năm 2012 và open-sourced vào năm 2015, là một query language và runtime cho APIs. Cả hai đều có mục đích giúp clients communicate với servers, nhưng chúng có cách tiếp cận khác nhau.
2. REST API Overview
REST là architectural style sử dụng HTTP methods để perform operations trên resources. REST APIs expose multiple endpoints, mỗi endpoint returns specific data structure.
2.1 REST Characteristics:
- Multiple Endpoints: Different endpoints cho different resources
- HTTP Methods: GET, POST, PUT, DELETE, etc.
- Stateless: Each request is independent
- Cacheable: Responses can be cached
- Standard HTTP: Uses standard HTTP protocols
2.2 REST Example:
GET /api/users // Get all users
GET /api/users/123 // Get user 123
GET /api/users/123/posts // Get posts of user 123
POST /api/users // Create user
PUT /api/users/123 // Update user 123
DELETE /api/users/123 // Delete user 123
3. GraphQL Overview
GraphQL là query language cho APIs và runtime để execute those queries. GraphQL provides single endpoint và allows clients to specify exactly what data they need.
3.1 GraphQL Characteristics:
- Single Endpoint: One endpoint cho all operations
- Query Language: Clients specify exact data needed
- Strongly Typed: Type system ensures data consistency
- Introspective: API is self-documenting
- Flexible: Clients control response structure
3.2 GraphQL Example:
query {
user(id: 123) {
name
email
posts {
title
content
}
}
}
4. So Sánh Chi Tiết
4.1 Data Fetching:
REST:
- Multiple requests để get related data
- Over-fetching: Get more data than needed
- Under-fetching: Need multiple requests để get all data
- Fixed response structure
GraphQL:
- Single request để get all needed data
- No over-fetching: Get exactly what you need
- No under-fetching: Get all data in one request
- Flexible response structure
4.2 Example - Fetching User and Posts:
REST:
// Request 1: Get user
GET /api/users/123
Response: {
"id": 123,
"name": "John",
"email": "[email protected]",
"address": "...", // Over-fetching
"phone": "...", // Over-fetching
}
// Request 2: Get posts
GET /api/users/123/posts
Response: [
{
"id": 1,
"title": "Post 1",
"content": "...",
"author": "...", // Over-fetching
"tags": [...] // Over-fetching
}
]
GraphQL:
// Single request
query {
user(id: 123) {
name
email
posts {
title
content
}
}
}
Response: {
"data": {
"user": {
"name": "John",
"email": "[email protected]",
"posts": [
{
"title": "Post 1",
"content": "..."
}
]
}
}
}
4.3 Learning Curve:
REST:
- Easier to learn - uses standard HTTP
- Familiar concepts cho developers
- Wide adoption và community support
- Many tools và libraries available
GraphQL:
- Steeper learning curve - new concepts
- Need to learn GraphQL query language
- Smaller community compared to REST
- Fewer tools và libraries
4.4 Caching:
REST:
- HTTP caching works out of the box
- Can use CDN caching
- Browser caching supported
- Easy to implement caching strategies
GraphQL:
- More complex caching - single endpoint
- Cannot use standard HTTP caching easily
- Need custom caching solutions
- Client-side caching libraries needed (Apollo Client, Relay)
4.5 Error Handling:
REST:
- Uses standard HTTP status codes
- Clear error semantics
- Easy to handle errors
- Well-established error handling patterns
GraphQL:
- Always returns 200 OK (even for errors)
- Errors in response body
- Need to check errors array
- Less standardized error handling
4.6 Type System:
REST:
- No built-in type system
- Need external documentation (OpenAPI/Swagger)
- Types not enforced at runtime
- Need validation libraries
GraphQL:
- Strong type system built-in
- Self-documenting schema
- Types enforced at runtime
- Automatic validation
4.7 Versioning:
REST:
- Easy versioning với URL versioning
- Can maintain multiple versions
- Clear version separation
- Standard versioning strategies
GraphQL:
- No versioning needed - additive changes
- Deprecate fields instead of versions
- Single version of API
- Easier to evolve API
4.8 Performance:
REST:
- Can be optimized với caching
- Multiple requests can be slow
- Over-fetching wastes bandwidth
- Can use HTTP/2 multiplexing
GraphQL:
- Single request is efficient
- No over-fetching
- Can be slow với complex queries
- Need to implement query complexity limits
5. Use Cases
5.1 When to Use REST:
- Simple CRUD operations
- Well-defined, stable data structure
- Need standard HTTP caching
- Team familiar với REST
- Microservices architecture
- Public APIs với wide adoption
- Need simple error handling
5.2 When to Use GraphQL:
- Complex data relationships
- Multiple clients với different data needs
- Mobile apps với limited bandwidth
- Rapidly changing requirements
- Need to reduce over-fetching
- Real-time updates (GraphQL subscriptions)
- Frontend-heavy applications
6. GraphQL Features
6.1 Queries:
Queries are used để fetch data. Clients specify exact fields needed.
query {
users {
id
name
email
}
}
6.2 Mutations:
Mutations are used để modify data (create, update, delete).
mutation {
createUser(input: {
name: "John Doe"
email: "[email protected]"
}) {
id
name
email
}
}
6.3 Subscriptions:
Subscriptions enable real-time updates. Clients subscribe to changes và receive updates.
subscription {
userUpdated(id: 123) {
id
name
email
}
}
6.4 Fragments:
Fragments allow reusing query parts.
fragment UserFields on User {
id
name
email
}
query {
user(id: 123) {
...UserFields
}
}
7. REST Features
7.1 HTTP Methods:
- GET - Retrieve data
- POST - Create resource
- PUT - Update resource
- PATCH - Partial update
- DELETE - Delete resource
7.2 Status Codes:
- 200 OK - Success
- 201 Created - Resource created
- 404 Not Found - Resource not found
- 400 Bad Request - Invalid request
- 500 Internal Server Error - Server error
7.3 HATEOAS:
HATEOAS (Hypermedia as the Engine of Application State) allows APIs to provide links to related resources, enabling clients to discover API capabilities.
8. Implementation Examples
8.1 REST Implementation (Node.js/Express):
app.get("/api/users", (req, res) => {
const users = getUsers();
res.json(users);
});
app.get("/api/users/:id", (req, res) => {
const user = getUserById(req.params.id);
res.json(user);
});
app.post("/api/users", (req, res) => {
const user = createUser(req.body);
res.status(201).json(user);
});
8.2 GraphQL Implementation (Node.js/Apollo):
const typeDefs = gql`
type User {
id: ID!
name: String!
email: String!
posts: [Post!]!
}
type Query {
users: [User!]!
user(id: ID!): User
}
type Mutation {
createUser(input: CreateUserInput!): User!
}
`;
const resolvers = {
Query: {
users: () => getUsers(),
user: (_, { id }) => getUserById(id),
},
Mutation: {
createUser: (_, { input }) => createUser(input),
},
};
9. Hybrid Approach
Bạn không cần chọn một trong hai. Có thể use both REST và GraphQL trong same project:
- Use REST cho simple CRUD operations
- Use GraphQL cho complex queries
- Use REST cho public APIs
- Use GraphQL cho internal APIs
- Gradually migrate từ REST to GraphQL
10. Performance Considerations
10.1 REST Performance:
- HTTP caching reduces server load
- CDN caching for static resources
- Multiple requests can be slow
- Over-fetching wastes bandwidth
10.2 GraphQL Performance:
- Single request is efficient
- No over-fetching
- Complex queries can be slow
- Need query complexity analysis
- N+1 query problem
- Need DataLoader để batch requests
11. Security
11.1 REST Security:
- Standard HTTP security (HTTPS, CORS)
- API key authentication
- OAuth 2.0
- Rate limiting per endpoint
11.2 GraphQL Security:
- Query complexity limiting
- Depth limiting
- Query whitelisting
- Rate limiting per query
- Authentication và authorization
12. Tooling và Ecosystem
12.1 REST Tools:
- Postman - API testing
- Swagger/OpenAPI - Documentation
- Insomnia - API client
- Many libraries và frameworks
12.2 GraphQL Tools:
- GraphQL Playground - Query editor
- Apollo Studio - API management
- GraphiQL - Interactive explorer
- Growing ecosystem
13. Migration từ REST to GraphQL
Nếu bạn muốn migrate từ REST to GraphQL:
- Start với read operations (queries)
- Keep REST endpoints during migration
- Gradually add GraphQL endpoints
- Migrate write operations (mutations) later
- Deprecate REST endpoints gradually
- Provide migration guide cho clients
14. Best Practices
14.1 REST Best Practices:
- Use proper HTTP methods
- Return appropriate status codes
- Implement pagination
- Use consistent naming
- Version your APIs
- Document your APIs
14.2 GraphQL Best Practices:
- Design schema carefully
- Implement query complexity limits
- Use DataLoader để prevent N+1 queries
- Implement proper error handling
- Use fragments để reuse queries
- Document your schema
15. Kết Luận
REST và GraphQL đều có điểm mạnh và điểm yếu. REST là mature, widely adopted, và easy to learn. GraphQL is flexible, efficient, và powerful. Lựa chọn phụ thuộc vào:
- Project requirements
- Team expertise
- Data complexity
- Client needs
- Performance requirements
- Ecosystem support
REST is better cho simple, stable APIs với standard caching needs. GraphQL is better cho complex data relationships, multiple clients, và rapidly changing requirements. Bạn cũng có thể use both trong same project. Quan trọng nhất là chọn approach phù hợp với nhu cầu của dự án và team của bạn.