⛶ bấm để phóng to
API là cách hai phần mềm nói chuyện với nhau qua mạng. Có nhiều kiểu API. Bốn kiểu hay gặp là REST, GraphQL, gRPC và WebSocket. SOAP và RPC là các kiểu cũ hơn.
Mọi kiểu giải cùng một bài toán: client cần lấy hoặc thay đổi dữ liệu trên server. Chúng khác nhau ở định dạng dữ liệu, cách gọi, và đánh đổi về tốc độ, độ linh hoạt và độ dễ cache. Topic này so sánh ba kiểu chính và chỉ ra khi nào chọn kiểu nào.
An API is how two pieces of software talk over a network. There are several API styles. The four common ones are REST, GraphQL, gRPC and WebSocket. SOAP and RPC are older styles.
Every style solves the same problem: a client needs to fetch or change data on a server. They differ in data format, how you call them, and their trade-offs in speed, flexibility and cacheability. This topic compares the three main styles and shows when to choose each.
⛶ bấm để phóng to
REST mô hình hóa mọi thứ thành tài nguyên, mỗi tài nguyên có một URL. Client thao tác tài nguyên bằng HTTP verb. GET đọc, POST tạo, PUT sửa, DELETE xóa. Dữ liệu thường ở định dạng JSON.
REST là stateless. Mỗi request mang đủ thông tin để server xử lý, server không nhớ request trước. Tính chất này giúp REST dễ scale ngang. Response của GET cũng dễ cache vì nó gắn với một URL cố định.
REST models everything as a resource, and each resource has a URL. The client acts on resources with HTTP verbs. GET reads, POST creates, PUT updates, DELETE removes. The data is usually JSON.
REST is stateless. Each request carries enough information for the server to handle it, and the server remembers no previous request. This makes REST easy to scale horizontally. A GET response is also easy to cache because it maps to a fixed URL.
⛶ bấm để phóng to
REST có một điểm yếu khi giao diện phức tạp. Mỗi endpoint trả về một hình dạng dữ liệu cố định. Nếu client chỉ cần vài field, nó vẫn nhận cả object lớn. Đây là over-fetching, lãng phí băng thông.
Chiều ngược lại là under-fetching. Một màn hình cần dữ liệu từ nhiều tài nguyên, nên client phải gọi nhiều endpoint rồi tự ghép. Trên mobile, nhiều round-trip làm chậm trải nghiệm. GraphQL ra đời để giải đúng hai vấn đề này.
REST has a weakness when the UI is complex. Each endpoint returns a fixed data shape. If the client needs only a few fields, it still receives the whole object. This is over-fetching, which wastes bandwidth.
The opposite is under-fetching. One screen needs data from several resources, so the client calls many endpoints and stitches them together. On mobile, many round-trips slow the experience. GraphQL was created to solve exactly these two problems.
⛶ bấm để phóng to
GraphQL có một endpoint duy nhất. Client gửi một query mô tả chính xác những field nó cần, kể cả dữ liệu lồng nhau từ nhiều tài nguyên. Server trả về đúng hình dạng đó, không thừa không thiếu.
Cách này giải over-fetching vì client chỉ lấy field cần. Nó giải under-fetching vì một query gộp được dữ liệu từ nhiều nguồn trong một lần gọi. Frontend nhờ vậy linh hoạt, đổi giao diện mà không cần backend thêm endpoint mới.
GraphQL has a single endpoint. The client sends a query describing exactly the fields it needs, including nested data from several resources. The server returns that exact shape, nothing more and nothing less.
This solves over-fetching because the client takes only the fields it needs. It solves under-fetching because one query gathers data from many sources in a single call. The frontend becomes flexible and can change the UI without the backend adding new endpoints.
⛶ bấm để phóng to
GraphQL trả giá ở vài chỗ. Caching khó hơn REST. Mọi query đi tới cùng một endpoint bằng POST, nên không dùng được cache HTTP theo URL như GET. Phải cache ở tầng ứng dụng.
GraphQL cũng dễ gặp N+1 query: một query lồng nhiều cấp có thể nổ ra rất nhiều truy vấn database phía sau. Cần kỹ thuật như dataloader để gom. Server cũng phức tạp hơn. Chọn GraphQL khi client đa dạng và giao diện thay đổi nhanh.
GraphQL pays a price in a few places. Caching is harder than REST. Every query hits the same endpoint over POST, so it cannot use URL-based HTTP caching the way GET does. You must cache at the application layer.
GraphQL also invites the N+1 query problem: a deeply nested query can explode into many database queries behind it. You need techniques like a dataloader to batch them. The server is also more complex. Choose GraphQL when clients are diverse and the UI changes fast.
⛶ bấm để phóng to
gRPC gọi hàm trên một service ở xa như gọi hàm cục bộ. Nó dùng Protocol Buffers để mã hóa dữ liệu thành nhị phân, nhỏ và nhanh hơn JSON nhiều. Nó chạy trên HTTP/2, nên có multiplexing và streaming.
Hai bên chia sẻ một file định nghĩa schema. Từ file đó sinh ra code client và server tự động, ở nhiều ngôn ngữ. Nhờ vậy gRPC rất nhanh và chặt chẽ về kiểu dữ liệu.
gRPC calls a function on a remote service as if it were local. It uses Protocol Buffers to encode data as binary, much smaller and faster than JSON. It runs on HTTP/2, so it gets multiplexing and streaming.
Both sides share one schema definition file. From that file, client and server code is generated automatically, in many languages. This makes gRPC very fast and strongly typed.
⛶ bấm để phóng to
gRPC tỏa sáng ở giao tiếp nội bộ giữa các microservice. Tốc độ nhị phân và streaming hợp cho lưu lượng lớn trong một hệ thống. Nó cũng tốt cho kết nối thời gian thực hai chiều.
gRPC yếu ở phía trình duyệt. Trình duyệt không gọi gRPC trực tiếp được, phải qua một lớp proxy. Dữ liệu nhị phân cũng khó đọc khi debug. Quy tắc: dùng gRPC giữa các service nội bộ, dùng REST hoặc GraphQL cho API mà client bên ngoài gọi.
gRPC shines in internal communication between microservices. Its binary speed and streaming suit heavy traffic inside one system. It is also good for two-way real-time connections.
gRPC is weak on the browser side. A browser cannot call gRPC directly and needs a proxy layer. Binary data is also hard to read when debugging. The rule: use gRPC between internal services, and use REST or GraphQL for APIs that outside clients call.
⛶ bấm để phóng to
Ba kiểu chính phục vụ ba nhu cầu khác nhau. Dùng REST cho API công khai và CRUD đơn giản, vì nó dễ hiểu và cache tốt. Dùng GraphQL khi nhiều loại client cần hình dạng dữ liệu khác nhau, hoặc giao diện đổi nhanh.
Dùng gRPC cho giao tiếp nội bộ giữa các microservice cần tốc độ cao. Dùng WebSocket khi cần kênh hai chiều thời gian thực. Không có kiểu nào tốt nhất tuyệt đối. Chọn theo client, theo nhu cầu cache, và theo việc API là nội bộ hay công khai.
The three main styles serve three different needs. Use REST for public APIs and simple CRUD, because it is easy to understand and caches well. Use GraphQL when many client types need different data shapes, or the UI changes fast.
Use gRPC for internal microservice communication that needs high speed. Use WebSocket when you need a two-way real-time channel. No style is best in the absolute. Choose by the client, by caching needs, and by whether the API is internal or public.
Topic 3 dạy cách chọn và mở rộng database: SQL vs NoSQL, ACID, index, replication, sharding, CAP.