What is a swagger?
Swagger is a simple but powerful API expression tool. It has the largest ECOSYSTEM of API tools on earth, with thousands of developers, using almost every modern programming language, all supporting and using Swagger. With Swagger generating apis, we get interactive documentation, SDKS that automatically generate code, and DISCOVERY features for apis.
What does a Swagger document look like?
A simple Example of a Swagger document:
swagger: "2.0"
info:
version: 1.0. 0
title: Simple API
description: A simple API to learn how to write OpenAPI Specification
schemes:
- https
host: simple.api
basePath: /openapi101
paths: {}
Copy the code
Assuming you already know how to write a Swagger document, of course, if you don’t, check out the documentation on the swagger website to learn how to do it, and there’s a set of Swagger From Getting Started to Mastering.
Background of this paper
The reason for writing this article is because the company requires the API documentation to be in Swagger format and the project is written in Golang. How can a lazy programmer bear to write such complicated Swagger documentation? Is there a one-click generation tool? Google it, and it’s called the Go-Swagger project. One of the many features of The Go-Swagger is Generate a spec from source, which suits my needs.
How to add Swagger comments to a project and generate API documentation with one click
Two tools need to be installed before you can begin:
- Swagger-editor: For Writing Swagger documentation, UI presentation, generating code, etc…
- Go-swagger: For one-click GENERATION of API documentation
Install swagger – editor, here I use the docker run, other installation, please see the official document:
docker pull swaggerapi/swagger-editor
docker run --rm -p 80:8080 swaggerapi/swagger-editor
Copy the code
Install the Go-Swagger, I use BREW installation, other installation, please see the official documentation
brew tap go-swagger/go-swagger
brew install go-swagger
Copy the code
Ok, now we finally get down to business: Start coding!!
Start writing comments
1. Suppose you have a user.server that provides some REST API for adding, deleting, modifying and querying user data.
For example, here is a getOneUser interface that queries user information:
package service
import (
"encoding/json"
"fmt"
"net/http"
"strconv"
"user.server/models"
"github.com/Sirupsen/logrus"
)
type GetUserParam struct {
Id int `json:"id"`
}
func GetOneUser(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
decoder := json.NewDecoder(r.Body)
var param GetUserParam
err := decoder.Decode(¶m)
iferr ! =nil {
WriteResponse(w, ErrorResponseCode, "request param is invalid, please check!".nil)
return
}
// get user from db
user, err := models.GetOne(strconv.Itoa(param.Id))
iferr ! =nil {
logrus.Warn(err)
WriteResponse(w, ErrorResponseCode, "failed".nil)
return
}
WriteResponse(w, SuccessResponseCode, "success", user)
}
Copy the code
According to the Swagger Documentation specification, a Swagger document starts with the swagger version and info. To use the go-Swagger, just declare the package with the following comment:
// Package classification User API. // // The purpose of this service is to provide an application // that is using Plain Go code to define an API // // Host: localhost // Version: 0.0.1 // // Swagger: Meta Package serviceCopy the code
/swagger.json: Swagger generate spec -o./swagger.json
This command finds the main.go entry file, then iterates through all the source files, parses and generates a swagger.json file
{
"swagger": "2.0"."info": {
"description": "The purpose of this service is to provide an application\nthat is using plain go code to define an API"."title": "User API."."version": "0.0.1"
},
"host": "localhost"."paths": {}}Copy the code
2. The basic information is there, then there is the route, the request, the response, etc.
// swagger:parameters getSingleUser
type GetUserParam struct {
// an id of user info
//
// Required: true
// in: path
Id int `json:"id"`
}
func GetOneUser(w http.ResponseWriter, r *http.Request) {
// swagger:route GET /users/{id} users getSingleUser
//
// get a user by userID
//
// This will show a user info
//
// Responses:
// 200: UserResponse
decoder := json.NewDecoder(r.Body)
var param GetUserParam
err := decoder.Decode(¶m)
iferr ! =nil {
WriteResponse(w, ErrorResponseCode, "request param is invalid, please check!".nil)
return
}
// get user from db
user, err := models.GetOne(strconv.Itoa(param.Id))
iferr ! =nil {
logrus.Warn(err)
WriteResponse(w, ErrorResponseCode, "failed".nil)
return
}
WriteResponse(w, SuccessResponseCode, "success", user)
}
Copy the code
You can see that the GetUserParam structure has added a swagger: Parameters getSingleUser comment above it. This is the input comment for declaring the interface. Several lines of comments inside the structure indicate that the id parameter is required and that the query parameter ID is in the URL path. Swagger :params
In the GetOneUser function:
swagger:route
Specifies the HTTP method and route to be used, as well as the tag and operation ID. For details, see swagger:routeResponses
Specifies the code and type of the return value
Then declare the response:
// User Info
//
// swagger:response UserResponse
type UserWapper struct {
// in: body
Body ResponseMessage
}
type ResponseMessage struct {
Code int `json:"code"`
Message string `json:"message"`
Data interface{} `json:"data"`
}
Copy the code
Use swagger:response syntax to declare the return value, and the next two lines are a description of the return value. For details on usage, see; swagger:response
Then go to LocalHost in your browser and view the Swagger-Editor interface. Click File->Impoprt File in the toolbar to upload the swagger.json File you just generated.
A simple API documentation is generated
3. How’s it going? Is it simple? But it feels like it’s not right. Well, the comments are in the code, it’s ugly, and it’s not easy to maintain. Think go-Swagger works by scanning all the GO files in the directory and parsing the comment information. So is it possible to write API comments in a single file, unified management, lest scattered in various source files.
Create a new doc.go file, and there is another interface called UpdateUser, so we declare the API comments for this interface in the doc.go file. Let’s look at the UpdateUser interface code:
func UpdateUser(w http.ResponseWriter, r *http.Request) {
defer r.Body.Close()
// decode body data into user struct
decoder := json.NewDecoder(r.Body)
user := models.User{}
err := decoder.Decode(&user)
iferr ! =nil {
WriteResponse(w, ErrorResponseCode, "user data is invalid, please check!".nil)
return
}
// check if user exists
data, err := models.GetUserById(user.Id)
iferr ! =nil {
logrus.Warn(err)
WriteResponse(w, ErrorResponseCode, "query user failed".nil)
return
}
if data.Id == 0 {
WriteResponse(w, ErrorResponseCode, "user not exists, no need to update".nil)
return
}
// update
_, err = models.Update(user)
iferr ! =nil {
WriteResponse(w, ErrorResponseCode, "update user data failed, please try again!".nil)
return
}
WriteResponse(w, SuccessResponseCode, "update user data success!".nil)}Copy the code
Then write the following declaration in the doc. Go file:
package service
import "user.server/models"
// swagger:parameters UpdateUserResponseWrapper
type UpdateUserRequest struct {
// in: body
Body models.User
}
// Update User Info
//
// swagger:response UpdateUserResponseWrapper
type UpdateUserResponseWrapper struct {
// in: body
Body ResponseMessage
}
// swagger:route POST /users users UpdateUserResponseWrapper
//
// Update User
//
// This will update user info
//
// Responses:
// 200: UpdateUserResponseWrapper
Copy the code
Swagger generate spec -o./swagger.json to generate a JSON file, you can see the result:
Write a few lines of comments with reference to the documentation, and then a command generates the API documentation. Good news for lazy programmers
All sample code for this article is hosted here at the original address
Reference:
- Swagger official Doc
- Swagger from beginner to master
- Go to swagger document
- Go-swagger’s Github home page