1. 15:01 14/10/2026
1. Vấn đề thường gặp
Khi phát triển song song Web (Next.js) và Mobile (Expo), team hay copy‑paste các hàm fetch thủ công. Điều này dẫn đến:
- Sai lệch kiểu dữ liệu giữa client và server.
- Khó bảo trì khi schema GraphQL thay đổi.
- Tăng bộ lọc boilerplate trong từng component.
2. Kiến trúc đề xuất
- Sử dụng GraphQL Codegen để sinh TypeScript types và React Query hooks trực tiếp từ schema.
- Đặt toàn bộ logic gọi API trong thư mục shared/api, xuất khẩu các hook sẵn sàng dùng.
- React Query lo caching, refetch, retry, còn Codegen đảm bảo type‑safe.
3. Cài đặt GraphQL Codegen
- Cài đặt: npm i -D @graphql-codegen/cli @graphql-codegen/typescript @graphql-codegen/typescript-operations @graphql-codegen/typescript-react-query
- Tạo file codegen.yml ở root monorepo:
schema: "https://api.example.com/graphql"
documents: "packages/shared/api/**/*.graphql"
generates:
packages/shared/api/generated.ts:
plugins:
- typescript
- typescript-operations
- typescript-react-query
- Chạy script: npx graphql-codegen --config codegen.yml
4. Tích hợp React Query
- Wrap ứng dụng với QueryClientProvider ở _app.tsx (Next.js) và App.tsx (Expo).
- Import hook sinh ra: import { useLoginMutation } from '@/shared/api/generated';
- Sử dụng trong component:
const { mutate, isLoading } = useLoginMutation();
const handleSubmit = (data) => mutate(data, { onSuccess: navigateToHome });
5. Ví dụ thực tế: mutation đăng nhập
- File packages/shared/api/mutations/login.graphql:
mutation Login($email: String!, $password: String!) {
login(email: $email, password: $password) {
token
user { id name }
}
}
- Sau khi codegen, hook useLoginMutation tự có kiểu biến đầu vào và kiểu trả về chính xác.
6. Lợi ích và lưu ý
- Giảm 70% boilerplate so với fetch thủ công.
- Type safety xuyên suốt từ schema đến UI.
- Dễ dàng mở rộng: thêm query mới chỉ cần file .graphql và chạy codegen.
- Cần cấu hình cache key nhất quán giữa Web và Mobile để tránh stale data.
- Theo dõi version schema qua CI để phát hiện breaking change sớm.