APIs (Giao diện Lập trình Ứng dụng) đang trở nên phổ biến hơn bao giờ hết. Các dịch vụ trên Internet thường sử dụng chuẩn RESTful APIs để cung cấp các tài nguyên cho đối tác của mình. Tuy nhiên, làm sao để đối tác biết về những tài nguyên mà chúng ta cung cấp? Chúng ta cần sử dụng những thông tin nào để có thể truy xuất tài nguyên đó?
Chính vì vậy, chúng ta cần một công cụ hỗ trợ việc tạo tài liệu APIs để dễ dàng cung cấp thông tin về cách sử dụng tài nguyên thông qua APIs một cách hiệu quả. Hôm nay, chúng ta sẽ tìm hiểu về một công cụ nổi tiếng dùng để viết tài liệu APIs: Swagger.
Swagger – Công cụ viết tài liệu cho RESTful APIs
Swagger là một công cụ mã nguồn mở được sử dụng để phát triển, thiết kế, xây dựng và làm tài liệu cho các hệ thống RESTful Web Service. Swagger cung cấp nhiều công cụ hỗ trợ việc tạo tài liệu, bao gồm Swagger UI, Swagger Editor, Swagger Codegen, Swagger Hub và Swagger Inspector. Trên đó, Swagger UI, Swagger Editor và Swagger Codegen là các công cụ mã nguồn mở, trong khi Swagger Hub và Swagger Inspector là các công cụ cao cấp hơn, đòi hỏi phải trả phí. Tuy nhiên, chúng ta có thể sử dụng miễn phí trong vòng 30 ngày. Vì vậy, để thuận tiện, chúng ta sẽ tìm hiểu cách viết tài liệu APIs bằng Swagger UI.
Swagger UI – Công cụ tạo trang mô tả về APIs
Swagger UI là một công cụ giúp tạo một trang HTML CSS mô tả về các APIs được cấu hình thông qua một file .yaml. Ngoài ra, công cụ này còn cho phép chúng ta thử nghiệm các API để xem kết quả.
Trong Ruby on Rails, hiện tại có gem swagger-docs và swagger-ui hỗ trợ việc viết mã Ruby để sinh ra file yaml. Tuy nhiên, hiện tại vẫn còn một số lỗi như không thể hiển thị các ví dụ hoặc lỗi về sử dụng oneOf vẫn chưa được khắc phục. Ngoài ra, các gem này yêu cầu thư viện RSpec, nên chỉ hoạt động tốt trên môi trường local. Vì vậy, chúng ta sẽ tìm hiểu cách viết trực tiếp bằng cú pháp yaml thay vì sử dụng gem.
1. Tải thư viện Swagger
Đầu tiên, chúng ta cần sao chép dự án từ GitHub và sao chép thư mục dist từ dự án đó vào dự án của chúng ta. Sau đó, chọn render file index.html trong thư mục dist. Ví dụ, trong dự án của tôi sử dụng Ruby on Rails làm backend, chúng ta sẽ sao chép vào thư mục public/swagger và thêm vào file routes.rb dòng root to: redirect(“/swagger/index.html”).
Bằng cách này, đường dẫn gốc của ứng dụng sẽ trỏ đến file index.html của Swagger.
2. Cấu trúc thư mục
Để dễ quản lý các API, chúng ta sẽ chia nhỏ file yaml thành các file và phân chia vào các thư mục tương ứng. Cấu trúc cơ bản của thư mục như sau:
- index.yaml: file config chính cho API docs, chứa các path
- paths: chứa các file định nghĩa chính của các API, chúng ta sẽ chia theo controller để dễ quản lý
- definitions: chứa mô tả về object cho API, chúng ta sẽ chia theo models
- shared: chứa các khai báo sử dụng chung như các lỗi thường gặp, thông tin về phân trang
3. Cú pháp $ref
Một điều rất hay của file .yaml là chúng ta có thể tách riêng từng phần và gọi lại chúng bằng cách sử dụng $ref. Điều này giúp chúng ta có thể tách các cấu trúc dữ liệu thành từng phần riêng biệt như cấu trúc thư mục ở trên và sau đó gọi lại chúng. Điều này giúp file .yaml của chúng ta dễ đọc, dễ hiểu và dễ nhìn.
Cú pháp để sử dụng $ref có thể tóm tắt như sau:
- Trỏ đến phần của document nằm trong cùng 1 file:
$ref: 'document.json#/myElement'
- Trỏ đến phần của document nằm trong thư mục cha:
$ref: '../document.json#/myElement'
- Trỏ đến phần của document nằm trong một thư mục bất kì:
$ref: '../another-folder/document.json#/myElement'
Tạo config cấu hình APIs của bạn
Cấu trúc cơ bản của một file .yaml trong Swagger như sau:
openapi: Phiên bản Swagger đang sử dụng, sẽ định nghĩa toàn bộ cấu trúc file .yaml
info: Thông tin của APIs, trong này sẽ chứa những phần: title, version, description, ...
title: tên Open-APIs (thường là tên sản phẩm project mình làm)
vertion: Phiên bản APIs public
description: Mô tả về APIs
security: Authentication mà APIs sử dụng để cung cấp tài nguyên
paths: Các APIs mà bạn cung cấp cho đối tác
definitions: Định nghĩa các model sử dụng bởi APIs
Ngoài ra còn rất nhiều từ khóa khác có thể tham khảo trong tài liệu của Swagger. Swagger cũng hỗ trợ viết config theo định dạng JSON, tuy nhiên chúng ta nên viết theo định dạng YAML.
Ví dụ, chúng ta sẽ tạo file index.yaml với cấu trúc như sau để cấu hình các APIs:
openapi: 3.0.1
info:
title: API V1
version: v1
paths:
/api/v1/users:
$ref: ../paths/users.yaml#index_create
/api/v1/users/{id}:
$ref: ../paths/users.yaml#show_update
servers:
- url: https://{defaultHost}
variables:
defaultHost:
default: www.example.com
Ở đây, chúng ta chia paths theo controller. Cấu trúc Restful trong Rails có 7 action, nhưng thông thường khi viết API, chỉ có 5 action phổ biến là index, create, show, update và delete. Trong đó, index và create không yêu cầu ID, trong khi các action khác đều yêu cầu ID. Vì vậy, mỗi file .yaml trong paths sẽ đại diện cho 1 resource theo controller, do đó ta cần thêm key index_create và show_update (key có thể đặt tùy ý) để phân biệt.
File paths/users.yaml:
index_create:
get:
summary: Danh sách người dùng
tags:
- users
description: Sử dụng API này để lấy danh sách người dùng
responses:
200:
description: Lấy danh sách người dùng thành công
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
example: true
data:
type: object
properties:
users:
type: array
items:
$ref: "../../definitions/user.yaml"
show_update:
put:
summary: Cập nhật người dùng
tags:
- user
description: Sử dụng API này để cập nhật người dùng
parameters:
- name: id
in: path
required: true
schema:
type: integer
requestBody:
content:
application/json:
schema:
type: object
properties:
user:
type: object
properties:
name:
type: string
required: true
example: Tên người dùng mới
responses:
200:
description: Cập nhật người dùng thành công
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
example: true
data:
type: object
properties:
user:
$ref: "../../definitions/user.yaml"
meta:
type: object
400:
description: Lỗi yêu cầu không hợp lệ
content:
application/json:
schema:
$ref: "../../definitions/common.yaml#/errors_object"
examples:
when name was blank:
value:
success: false
errors:
- resource: user
field: name
code: 1003
message: Tên không được để trống
404:
description: Không tìm thấy người dùng
content:
application/json:
schema:
$ref: "../../definitions/common.yaml#/errors_object"
examples:
when user was not found:
value:
success: false
errors:
- resource: user
field: code
message: Người dùng không tồn tại
File definitions/user.yaml:
type: object
properties:
id:
type: integer
example: 1
name:
type: string
description: Tên người dùng
example: Nhật
File definitions/commons.yaml:
errors_object:
type: object
properties:
success:
type: boolean
example: false
errors:
type: array
items:
type: object
properties:
code:
type: integer
required: true
message:
type: string
required: true
resource:
type: string
nullable: true
description: Tài nguyên gây lỗi
field:
type: string
nullable: true
description: Thuộc tính không chính xác
Chỉnh sửa file index.html trong thư mục swagger
window.onload = function() {
const ui = SwaggerUIBundle({
url: "/api/v1/index.yaml",
dom_id: '#swagger-ui',
deepLinking: true,
presets: [
SwaggerUIBundle.presets.apis,
SwaggerUIStandalonePreset
],
plugins: [
SwaggerUIBundle.plugins.DownloadUrl
],
layout: "StandaloneLayout"
})
window.ui = ui
}
Sau tất cả, hãy khởi chạy server để xem kết quả của bạn!
Như vậy, chúng ta đã tìm hiểu và viết một API document cơ bản bằng cú pháp yaml với Swagger. Ngoài ra, chúng ta còn phân chia các file yaml thành các thư mục phù hợp với cấu trúc viết API với Ruby on Rails để dễ dàng quản lý. Swagger còn rất nhiều từ khóa thú vị mà chúng ta có thể tìm hiểu và áp dụng vào dự án của mình. Và bây giờ, chúng ta có thể viết API docs mà không cần phụ thuộc vào Ruby gem nữa.