Bắt đầu
Việc xây dựng một API không được hoàn thành nếu không có tài liệu có ý nghĩa về các API của chúng tôi cũng như khả năng kiểm tra các điểm cuối của nó, người dùng thậm chí sẽ không cố gắng sử dụng nó. Giải pháp cho điều đó là viết tài liệu. Tuy nhiên, viết nó có thể mất nhiều thời gian. May mắn thay, có một công cụ có sẵn để giúp chúng tôi và đó là Swagger.
Vênh vang trong cờ vây
Hãy bắt đầu với các thư viện cần thiết để tạo tài liệu Swagger. Có nhiều gói chúng ta có thể sử dụng nhưng hai lựa chọn phổ biến là go-swagger và swag . go-swageer dường như là một lựa chọn phổ biến giữa hai người, nhưng cấu hình và đường cong học tập hơi phức tạp nên trong bài này chúng ta sẽ đi với swag .
swag cho phép sử dụng tạo tài liệu vênh vang từ nhận xét tài liệu ( godoc ) và nó rất đơn giản để sử dụng. Tất cả những gì chúng ta cần làm là ghi lại chức năng xử lý của chúng ta khi chúng ta viết mã và sử dụng công cụ dòng lệnh thì chúng ta sẽ làm tốt. Tôi chỉ cho bạn cách tạo tài liệu vênh vang bằng cách xây dựng ứng dụng Todo. Dự án ví dụ có thể được tìm thấy trong kho github của tôi, hãy chắc chắn kiểm tra xem.
Bootstraping
Để bắt đầu, trước tiên chúng ta cần cài đặt công cụ dòng lệnh mà chúng ta cần bằng cách chạy
1 2 | $ go get -u github.com/swaggo/swag/cmd/swag |
Sau đó cd
vào một dự án gốc và sau đó chạy swag init
. Lệnh này sẽ hy vọng rằng có một tệp có tên main.go
trong thư mục hiện tại, nhưng trong ví dụ của chúng tôi, mục nhập là cmd/server/main.go
vì vậy chúng ta cần truyền cờ -g
như thế này
1 2 | $ swag init -g cmd/server/main.go |
Điều này sẽ tạo ra một thư mục docs
mới trong dự án gốc. Trước khi chúng tôi mô tả các điểm cuối API riêng lẻ, trước tiên chúng tôi cần viết mô tả chung cho toàn bộ dự án của chúng tôi. Phần chú thích này nằm trong gói chính của bạn, ngay trước chức năng chính
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <span class="token keyword">package</span> main <span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token boolean">_</span> <span class="token string">"github.com/PrinceNorin/todo-go/docs"</span> <span class="token string">"github.com/PrinceNorin/todo-go/handler"</span> echo <span class="token string">"github.com/labstack/echo/v4"</span> echoSwagger <span class="token string">"github.com/swaggo/echo-swagger"</span> <span class="token punctuation">)</span> <span class="token comment">// @title Todo Application</span> <span class="token comment">// @description This is a todo list management application</span> <span class="token comment">// @version 1.0</span> <span class="token comment">// @host localhost:8081</span> <span class="token comment">// @BasePath /api/v1</span> <span class="token keyword">func</span> <span class="token function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> e <span class="token operator">:=</span> echo <span class="token punctuation">.</span> <span class="token function">New</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> e <span class="token punctuation">.</span> HTTPErrorHandler <span class="token operator">=</span> handler <span class="token punctuation">.</span> ErrorHandler v1 <span class="token operator">:=</span> e <span class="token punctuation">.</span> <span class="token function">Group</span> <span class="token punctuation">(</span> <span class="token string">"/api/v1"</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> todo <span class="token operator">:=</span> handler <span class="token punctuation">.</span> <span class="token function">NewHandler</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> v1 <span class="token punctuation">.</span> <span class="token function">GET</span> <span class="token punctuation">(</span> <span class="token string">"/todos"</span> <span class="token punctuation">,</span> todo <span class="token punctuation">.</span> FindTodos <span class="token punctuation">)</span> v1 <span class="token punctuation">.</span> <span class="token function">POST</span> <span class="token punctuation">(</span> <span class="token string">"/todos"</span> <span class="token punctuation">,</span> todo <span class="token punctuation">.</span> CreateTodo <span class="token punctuation">)</span> v1 <span class="token punctuation">.</span> <span class="token function">GET</span> <span class="token punctuation">(</span> <span class="token string">"/todos/:id"</span> <span class="token punctuation">,</span> todo <span class="token punctuation">.</span> GetTodo <span class="token punctuation">)</span> v1 <span class="token punctuation">.</span> <span class="token function">PUT</span> <span class="token punctuation">(</span> <span class="token string">"/todos/:id"</span> <span class="token punctuation">,</span> todo <span class="token punctuation">.</span> UpdateTodo <span class="token punctuation">)</span> v1 <span class="token punctuation">.</span> <span class="token function">DELETE</span> <span class="token punctuation">(</span> <span class="token string">"/todos/:id"</span> <span class="token punctuation">,</span> todo <span class="token punctuation">.</span> DeleteTodo <span class="token punctuation">)</span> <span class="token punctuation">}</span> e <span class="token punctuation">.</span> <span class="token function">GET</span> <span class="token punctuation">(</span> <span class="token string">"/swagger/*"</span> <span class="token punctuation">,</span> echoSwagger <span class="token punctuation">.</span> WrapHandler <span class="token punctuation">)</span> e <span class="token punctuation">.</span> Logger <span class="token punctuation">.</span> <span class="token function">Fatal</span> <span class="token punctuation">(</span> e <span class="token punctuation">.</span> <span class="token function">Start</span> <span class="token punctuation">(</span> <span class="token string">":8081"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Điều này sẽ xác định Thông tin API chung, bao gồm những thứ như tên, phiên bản, URL cơ sở, v.v. Có một vài trường nữa mà bạn có thể bao gồm và chúng được liệt kê trong trang github swag .
Ngoài các chú thích, chúng tôi cũng cần nhập các thư viện cần thiết bao gồm nhập trống gói tài liệu mà chúng tôi đã tạo. Một điều nữa chúng ta cần làm là thực sự gắn kết Swagger UI ở một số điểm cuối, ở đây chúng ta sử dụng /swagger/*
. Ở đây tôi sử dụng echo nhưng bạn có thể sử dụng swag với khá nhiều khung công tác bạn muốn.
Hoạt động
Để có được danh sách hoạt động hiển thị trong UI của chúng ta, chúng ta cần chú thích và xử lý chức năng. Các chú thích này đứng trước mỗi hàm xử lý mà chúng ta gắn kết như là điểm cuối API của chúng tôi và trong trường hợp này là todo.FindTodos , todo.CreateTodo , todo.GetTodo , todo.UpdateTodo , todo.DeleteTodo . Nó trông như thế nào
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <span class="token comment">// CreateTodo godoc</span> <span class="token comment">// @Summary Create a todo</span> <span class="token comment">// @Description Create a new todo item</span> <span class="token comment">// @Tags todos</span> <span class="token comment">// @Accept json</span> <span class="token comment">// @Produce json</span> <span class="token comment">// @Param todo body types.Todo true "New Todo"</span> <span class="token comment">// @Success 201 {object} types.Todo</span> <span class="token comment">// @Failure 400 {object} HTTPError</span> <span class="token comment">// @Router /todos [post]</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> h <span class="token operator">*</span> Handler <span class="token punctuation">)</span> <span class="token function">CreateTodo</span> <span class="token punctuation">(</span> c echo <span class="token punctuation">.</span> Context <span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> h <span class="token punctuation">.</span> <span class="token function">withLockContext</span> <span class="token punctuation">(</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> todo types <span class="token punctuation">.</span> Todo <span class="token keyword">if</span> err <span class="token operator">:=</span> c <span class="token punctuation">.</span> <span class="token function">Bind</span> <span class="token punctuation">(</span> <span class="token operator">&</span> todo <span class="token punctuation">)</span> <span class="token punctuation">;</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> errBadRequest <span class="token punctuation">}</span> <span class="token keyword">if</span> todo <span class="token punctuation">.</span> Name <span class="token operator">==</span> <span class="token string">""</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> errBadRequest <span class="token punctuation">}</span> h <span class="token punctuation">.</span> lastID <span class="token operator">++</span> todo <span class="token punctuation">.</span> ID <span class="token operator">=</span> h <span class="token punctuation">.</span> lastID h <span class="token punctuation">.</span> todos <span class="token punctuation">[</span> todo <span class="token punctuation">.</span> ID <span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token operator">&</span> todo <span class="token keyword">return</span> c <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> http <span class="token punctuation">.</span> StatusCreated <span class="token punctuation">,</span> <span class="token operator">&</span> todo <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Gần như tất cả những điều này là tự giải thích, vì vậy tôi sẽ bỏ qua một vài trong số chúng và chỉ chỉ ra một trong những điều quan trọng.
-
@Param
: mô tả tải trọng yêu cầu của chúng tôi, nó phải ở dạng{name} {type} {dataType} {required} {comment}
phân tách bằng dấu cách, do đó, trong trường hợp này, nó được dịch sang tên param todo trong thân yêu cầu với trường như được định nghĩa trong type.Todo struct, nó là bắt buộc và với mô tả New Todo. -
@Success
: phải ở dạng{status} {returnType} {dataType} {comment}
và trong trường hợp của chúng tôi, nó sẽ trả về 200 mã trạng thái với type.Todo làm đối tượng phản hồi khi cuộc gọi api thành công. -
@Failure
: giống như@Success
nhưng đối với trường hợp khi cuộc gọi api không thành công. -
@Router
: ở dạng{path} [method]
.
Và đây là tất cả những gì chúng ta cần để mô tả một điểm cuối duy nhất bây giờ tất cả những gì còn lại để cập nhật tài liệu của chúng tôi với những thay đổi mới này bằng cách gọi lại swag init -g cmd/server/main.go
Nếu mọi thứ đều ổn thì chúng ta có thể khởi động máy chủ của mình bằng cách go run github.com/PrinceNorin/cmd/server
sau đó điều hướng đến http://localhost:8081/swagger/index.html
sau đó bạn sẽ thấy một cái gì đó như thế này