# Chuẩn thiết kế Restful API trong lập trình > An API is a user interface for developers. Put the necessary effort in it to ensure it’s not just functional but pleasant to use. Bài viết này sẽ nói về phương pháp thiết kế RestFul API, cũng như các lỗi thường gặp phải khi thiết kế chúng. ## Tìm hiểu về HTTP Method Các HTTP Method thường sẽ có 2 loại là ``SAFE`` và ``IDEMPOTENT``. - `SAFE`: không làm thay đổi `state` của server, tức là nó sẽ đọc và không làm thay đổi dữ liệu. Các method `SAFE` gồm: GET, HEAD, OPTIONS. Các method `UNSAFE` gồm PUT, DELETE, POST, PATCH. - `IDEMPOTENT`: các method loại này có thể thực hiện ``n + 1`` lần mà vẫn trả lại kết quả ban đầu. Vì vậy các method `SAFE` sẽ luôn `IDEMPOTENT`, còn `UNSAFE` thì chưa chắc ### Các loại HTTP Method HTTP method là các phương thức mà một máy chủ web và một trình duyệt web sử dụng để giao tiếp và thực hiện các hành động trên các tài nguyên web. Các HTTP method quan trọng nhất bao gồm: - `GET`: lấy resource từ server theo URI. - `HEAD`: cũng giống như `GET`, nhưng `response` trả về không có body, chỉ có `header`. - `POST`: gửi resource tới server thông qua các form, thường dùng cho mục đích tạo mới resource. - `PUT`: cập nhật tất cả thông tin của đối tượng với những thông tin được gửi lên. - `PATCH`: chỉ cập nhật các thông tin được thay đổi của đối tượng. - `DELETE`: xóa resource trên server. - `CONNECT`: thiết lập một kết nối tới server theo URI. - `OPTIONS`: mô tả các tùy chọn giao tiếp cho reource. - `TRACE`: thực hiện 1 bài test loop-back theo đường dẫn tới resource. ### So sánh các HTTP Method - ``GET`` với ``POST``: có một câu hỏi là: `GET có thể được dùng để đẩy dữ liệu lên hay POST có thể được dùng để lấy dữ liệu về hay không?`, câu trả lời là có. Nhưng chúng ta sẽ không làm như vậy, nó sẽ vi phạm các quy tắc về thiết kế API. `GET` sẽ không có body, cho nên khi dùng `GET` để truyền dữ liệu lên server ta sẽ thấy các parameters đều hiển thị trên URL, nó sẽ thiếu bảo mật. Còn `POST` sẽ giấu parameters trong body và được mã háo khi truyền lên, nhưng nó chỉ an toàn với phía `Client`, còn với `Server` thì khác, tức là ta có thể đứng từ `Server` và nhìn thấy nội dung được truyền lên. - ``POST``, ``PUT`` và ``PATCH``: ``PUT`` là `IDEMPOTENT` còn ``POST`` thì không, bạn sẽ nhận được lỗi khi gửi 1 request ``POST`` với cùng nội dung 2 lần, nguyên nhân có thể là trùng lặp dữ liệu, hoặc do trạng thái tài nguyên, còn với ``PUT`` thì sẽ luôn trả về kết quả giống nhau. ``PATCH`` khác với ``PUT`` ở chỗ là nó sẽ cập nhật 1 phần của resource thay vì cập nhật lại hết như ``PUT``. ## Thiết kế Restful API ### Một số nguyên tắc * Giữ nó đơn giản: Hãy thiết kế URL của 1 API một cách đơn giản, ví dụ khi ta muốn tạo API cho các sản phẩm, thì nó nên là: ``` /products // lấy tất cả sản phẩm /products/{productID} // lấy chi tiết sản phẩm theo ID ``` * Sử dụng danh từ thay vì động từ: Đây là lỗi thường hay gặp phải khi thiết kế API, ví dụ: ``` /getAllProducts // sai /products // đúng ``` * Sử dụng số nhiều: sử dụng số nhiều sẽ tránh nhầm lẫn về việc ta đang lấy một resource hay collection resource từ server, nó cũng tránh thêm những thứ bổ sung vào URL như: ``` /product/all // không cần thiết /product /products // nên dùng như này ``` * Sử dụng các tham số: nên sử dụng dạng query parameters trong các trường hợp muốn lọc dữ liệu theo các điều kiện ``` /products?name='ABC' // thay vì sử dụng getProductsByName /products?type='XYZ' // thay vì sử dụng getProductsByType ``` * Sử dụng các HTTP Method một cách hợp lý: Một số HTTP Method thường được sử dụng là: * ``GET``: lấy tài nguyên * ``POST``: thêm mới tài nguyên * ``PUT/PATCH``: cập nhật tài nguyên * ``DELETE``: xóa tài nguyên * Sử dụng HTTP codes thích hợp: các HTTP codes thường sử dụng nằm trong khoảng 200-500, bao gồm: * ``200 OK``: được sử dụng phổ biến nhất khi thực hiện gọi API thành công. * ``201 CREATED``: được sử dụng khi sử dụng POST để thêm mới tài nguyên. * ``202 ACCEPTED``: được sử dụng để xác nhận yêu cầu được gửi tới máy chủ. * ``400 BAD REQUEST``: được sử dụng khi xác thực input phía client không thành công. * ``401 UNAUTHORIZED / 403 FORBIDDEN``: được sử dụng nếu người dùng hệ thống không được phép thực hiện một hành động nào đó. * ``404 NOT FOUND``: tìm một tài nguyên không có sẵn trong hệ thống, hoặc có thể sai đường dẫn URL. * ``500 INTERNAL SERVER ERROR``: thường là server bị lỗi. * ``502 BAD GATEWAY``: được sử dụng nếu máy chủ nhận được phản hồi không hợp lệ từ máy chủ ngược tuyến. * Đánh dấu version: version của API là rất quan trọng, có nhiều cách sử dụng version như làm ngày tháng, làm tham số truy vấn, thông thường nhất là để làm tiền tố, ví dụ: ``` /v1/products /v2/products ``` * Sử dụng phân trang: việc sử dụng phân trang là bắt buộc khi tài nguyên trả về lớn. Nên sử dụng `Limit` và `Offset`, ví dụ: `/products?limit=25&offset=50`. Nhưng khi số bản ghi trả về quá lớn, tức là khi `offset` quá to, thì việc sử dụng phân trang cũng không đem lại hiệu quả thực sự. Với trường hợp này, hãy xem bài viết tối ưu tại [đây](https://hackmd.io/@hoannv/pagination). * Hỗ trợ các loại định dạng response: Hầu hết các ứng dụng hiện đại sẽ trả về phản hồi JSON trừ khi bạn có ứng dụng cũ vẫn cần nhận phản hồi XML. * Sử dụng thông báo lỗi thích hợp: nên trả về đủ nghĩa nhất có thể, bao gồm kiểu lỗi, mã lỗi, messages,... * SSL: Luôn sử dụng SSL. Đây là một trong những biện pháp bảo mật cơ bản khi thiết kế API. Cố gắng hiển thị endpoint của bạn thông qua SSL. * Một số ví dụ về `URLs and Actions — Relations`: ``` GET /tickets/12/messages — Retrieves a list of messages for ticket #12 GET /tickets/12/messages/5 — Retrieves message #5 for ticket #12 POST /tickets/12/messages — Creates a new message in ticket #12 PUT /tickets/12/messages/5 — Updates message #5 for ticket #12 PATCH /tickets/12/messages/5 — Partially updates message #5 for ticket #12 DELETE /tickets/12/messages/5 — Deletes message #5 for ticket #12 ``` ## Kết luận Trên đây là một số kiến thức cơ bản về thiết kế RESTful API, giúp bạn thiết kế chúng một cách tốt hơn, tránh những nhầm lẫn không đáng có. ## Tham khảo [RESTful API Desgign](https://betterprogramming.pub/restful-api-design-step-by-step-guide-2f2c9f9fcdbf) [Tìm hiểu Http request methods](https://viblo.asia/p/cung-tim-hieu-ve-http-request-methods-djeZ1xBoKWz) [Http methods docs](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods)