Paging
Use page & per_page query parameter, return x-total-count header
( Ngoài việc dùng page & per_page
, chúng ta cũng có thể sử dụng offset & limit
với ý nghĩa tương tự )
Để phân trang cho kết quả của bạn sử dụng page
& per_page
trong query parameter, ví dụ api cần trả về các item từ 50 đến 100 thì, câu lệnh sẽ là
GET /item?page=2&per_page=50
Một số lưu ý phân trang
1. Trả về tổng số items thông qua X-Total-Count
header
2. Nếu muốn cung cấp link to previous and next page
thì có thể sử dụng Link HTTP header.
3. Trong code mà bạn cài đặt nên set maximum limit, ví dụ 1000 chẳng hạn, để tránh những vấn đề tại server
Ngoài ra còn nhiều cách khác để phân trang chẳng hạn như dùng Range header. Khi nghĩ về end user của bạn, tức client: sẽ dễ dàng phân trang bằng thông số page
và per_page
của GET request, hoặc định nghĩa một range header.
Sorting
Using sort parameter with value has prefix is minus (-) sign for desc and no sign for asc
Cách đơn giản nhất để sort là sử dụng sort query params, cho phép bạn định nghĩa thông qua minus (-) sign, For example:
GET /items?sort=-created_at # desc
GET /items?sort=created_at # asc
(Đây là cách đơn giản nhất, nhưng vẫn cò một số style khác như sort[desc]=created_at
,sort:desc=created_at
or sort=created_at.desc
)
Filtering
Use a unique query parameter for each of your fields
ex:
GET /items?first_name=huong
GET /items?title=developer
Searching
For fulltext search, should be using q params
Nếu muốn tìm kiếm một giá trị mà phạm vi full-text search, cách đơn giản nhất là dùng q
params
Ex: Bạn muốn tìm kiếm mọi thứ liên quan đến "Huong Ngo"
GET /users?q="Huong Ngo"
Retrieving specific fields
Using fields parameter and slit value by ','
API nên chỉ cho phép user của bạn chỉ nhận vào một số fields nhất định thay vì toàn bộ object, khi đó ta nên dùng từ khóa là fields
và sử dụng dấy chấm phấy ',' để tách các giá trị
Ex:
GET /users?fields=email,scrore,alias_name
Advanced filtering
Using LHS brackets with an operator
for intuitive orLucene or ElasticSearch syntax
for flexible issue
Phương thức filtering được nhắc đến ở trên, sử dụng query parameter, làm việc khá ổn nhưng chỉ với các filter là exact match ( chính xác hoàn toàn ). Nhưng nếu bạn cần những filter dạng như:
- 10 <= price <= 100
- status IS NOT past
- user is manager or director
Có nhiều cách để thực hiện:
1. Using LHS brackets with an operator: price[lte]=200 status[ne]=past
2. Using RHS colon with an operator: price=lte:200 status=ne:past
3. Using Lucene syntax or ElasticSearch Simple Query strings directly: q=price:<200 q=-status:past
Nhìn bảng so sánh dưới đây để có thêm thông tin:
Điểm mạnh | Hạn chế | |
---|---|---|
LSH Brackets with an operator |
- Người sử dụng (front-end dev) dễ dàng sử dụng - Tương đối đơn giản để parse ở phía server-side - Trông khá trực quan |
- Không thể thực hiện OR cho combined filters |
RHS colon with an operator |
- Dễ dàng parser tại server side - Người sử dụng (front-end dev) dễ dàng sử dụng |
- Không thể thực hiện OR cho combined filters - Ít trực quan hơn LSH Brackets with an operator |
Lucene or ElasticSearch syntax |
- Là phương pháp linh hoạt nhất trong các phương pháp trên Gần như không cần parse phía server (có thể đẩy trực tiếp cho elasticsearch ) |
- Cú pháp không trực quan như các phương pháp trên, cần phải học để sử dụng nhưng không quá khó |
Nếu bạn cần một giải pháp filter linh hoạt nhất có thể dành cho front-end của bạn, cho phép nó query trực tiếp vào DB thông qua API, thì sử dụng trực tiếp Lucene or ElasticSearch syntax
sẽ hợp lý hơn ngay cả khi nó đòi hỏi người sử dụng phải học để dùng nó.
Tuy nhiên, trong hầu hết các trường hợp phổ biến, thì việc sử dụng LSH Brackets with an operator
là giải pháp được recomend nhất nếu API của bạn có dùng filter nâng cao
Ref:
https://www.gvj-web.com/blog/paging-sorting-filtering-restful-api
https://www.moesif.com/blog/technical/api-design/REST-API-Design-Filtering-Sorting-and-Pagination