As a developer, it is vital to document and arrange all APIs, but you also know that not every developer like the documentation aspect. To do so, we’ll need certain tools that make it simple to create API documentation.
What is Swagger?
Swagger is an open-source suite of tools for creating REST-based APIs. It speeds up the process of building APIs by setting standards and providing the tools needed to write and organize scalable APIs. Swagger makes it so easy to create, manage, and publish API documentation. Swagger is an open-source professional toolset that enables individuals, teams, and corporations to effortlessly develop and describe APIs at scale.
Here are some of the advantages of using Swagger in your next project:
- Allowing you to rapidly and easily write, maintain, and publish API documentation
- Creating visually appealing interactive documentation that allows you to validate and test API endpoints directly from your browser without the use of third-party applications.
- Developers and non-developers alike will find it simple to understand.
- The ability to directly produce API client libraries (SDKs) for numerous languages and frameworks from an OpenAPI specification.
In this tutorial you will learn how to use annotation and Swag to produce Swagger documentation for Go web APIs directly from the source code.
How to generate Golang API documentation with Swagger
Step 1: Make a Project Directory: Configuring your development environment Create a new Go project in your text editor or IDE then go ahead and load your go.mod file. You may choose any name for your package. If you don’t know how to do that, you can use the text below
mkdir goswagger
cd goswagger
go mod init goswagger
Step 2: Installing Swagger
download_url=$(curl -s https://api.github.com/repos/go-swagger/go-swagger/releases/latest | \
jq -r '.assets[] | select(.name | contains("'"$(uname | tr '[:upper:]' '[:lower:]')"'_amd64")) | .browser_download_url')
curl -o /usr/local/bin/swagger -L'#' "$download_url"
chmod +x /usr/local/bin/swagger
Step 3: Download Dependencies Next, we will download the required dependencies
For this tutorial purpose, we will make use of
Mux: Handling http requests and routing
Command:
go get github.com/gorilla/mux
Swagger: Handling swagger doc
Command:
go get github.com/go-openapi/runtime/middleware
MySQL: Handling MySQL queries
Commands: Shape Copy Text
github.com/go-sql-driver/mysql
go get github.com/jmoiron/sqlx
Step 4: Import Database company.sql from the Root Directory Create main.go in the root directory. Establish database connection, routing for APIs, and Swagger documentation.
Shape Copy Text
r := mux.NewRouter()
dbsqlx := config.ConnectDBSqlx()
hsqlx := controllers.NewBaseHandlerSqlx(dbsqlx)
company := r.PathPrefix("/admin/company").Subrouter()
company.HandleFunc("/", hsqlx.PostCompanySqlx).Methods("POST")
company.HandleFunc("/", hsqlx.GetCompaniesSqlx).Methods("GET")
company.HandleFunc("/{id}", hsqlx.EditCompany).Methods("PUT")
company.HandleFunc("/{id}", hsqlx.DeleteCompany).Methods("DELETE")
Step 5: Write Documentation using Go Swagger Now, let’s see how to document using Swagger. It will consist of basic configurations, models, and API routes.
Basic Configuration
// Comapany Api:
// version: 0.0.1
// title: Comapany Api
// Schemes: http, https
// Host: localhost:5000
// BasePath: /
// Produces:
// - application/json
//
// securityDefinitions:
// apiKey:
// type: apiKey
// in: header
// name: authorization
// swagger:meta
package controllers
We can define security using the API key, which can be checked for each API.
Step5: Create a Model You can create models for our APIs’ requests and answers. Below are some structural examples with swagger comments. Every field can have a name, type, schema, required, and description.
type ReqAddCompany struct {
// Name of the company
// in: string
Name string `json:"name"validate:"required,min=2,max=100,alpha_space"`
// Status of the company
// in: int64
Status int64 `json:"status" validate:"required"`
}
// swagger:parameters admin addCompany
type ReqCompanyBody struct {
// - name: body
// in: body
// description: name and status
// schema:
// type: object
// "$ref": "#/definitions/ReqAddCompany"
// required: true
Body ReqAddCompany `json:"body"`
}
// swagger:model Company
type Company struct {
// Id of the company
// in: int64
Id int64 `json:"id"`
// Name of the company
// in: string
Name string `json:"name"`
// Status of the company
// in: int64
Status int64 `json:"status"`
}
// swagger:model CommonError
type CommonError struct {
// Status of the error
// in: int64
Status int64 `json:"status"`
// Message of the error
// in: string
Message string `json:"message"`
}
Step 6: Set Up your API Routes Every route can have swagger comments. You can specify the request and response models, the route name, the request method, the description, and, if necessary with the API key.
[Text Wrapping Break] HYPERLINK "javascript:void(0);"
// swagger:route GET /admin/company/ admin listCompany
// Get companies list
//
// security:
// - apiKey: []
// responses:
// 401: CommonError
// 200: GetCompanies
func (h *BaseHandlerSqlx) GetCompaniesSqlx(w http.ResponseWriter, r *http.Request) {
response := GetCompanies{}
companies := models.GetCompaniesSqlx(h.db)
response.Status = 1
response.Message = lang.Get("success")
response.Data = companies
w.Header().Set("content-type", "application/json")
json.NewEncoder(w).Encode(response)
}
// swagger:route POST /admin/company/ admin addCompany
// Create a new company
//
// security:
// - apiKey: []
// responses:
// 401: CommonError
// 200: GetCompany
func (h *BaseHandlerSqlx) PostCompanySqlx(w http.ResponseWriter, r *http.Request) {
w.Header().Set("content-type", "application/json")
response := GetCompany{}
decoder := json.NewDecoder(r.Body)
var reqcompany *models.ReqCompany
err := decoder.Decode(&reqcompany)
fmt.Println(err)
if err != nil {
json.NewEncoder(w).Encode(ErrHandler(lang.Get("invalid_requuest")))
return
}
company, errmessage := models.PostCompanySqlx(h.db, reqcompany)
if errmessage != "" {
json.NewEncoder(w).Encode(ErrHandler(errmessage))
return
}
response.Status = 1
response.Message = lang.Get("insert_success")
response.Data = company
json.NewEncoder(w).Encode(response)
}
// swagger:route PUT /admin/company/{id} admin editCompany
// Edit a company
//
// consumes:
// - application/x-www-form-urlencoded
// security:
// - apiKey: []
// responses:
// 401: CommonError
// 200: GetCompany
func (h *BaseHandlerSqlx) EditCompany(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
w.Header().Set("content-type", "application/json")
vars := mux.Vars(r)
response := GetCompany{}
id, err := strconv.ParseInt(vars["id"], 10, 64)
if err != nil {
json.NewEncoder(w).Encode(ErrHandler(lang.Get("invalid_requuest")))
return
}
var reqcompany models.ReqCompany
reqcompany.Status, err = strconv.ParseInt(r.FormValue("status"), 10, 64)
reqcompany.Name = r.FormValue("name")
if err != nil {
json.NewEncoder(w).Encode(ErrHandler(lang.Get("invalid_requuest")))
return
}
company, errmessage := models.EditCompany(h.db, &reqcompany, id)
if errmessage != "" {
json.NewEncoder(w).Encode(ErrHandler(errmessage))
return
}
response.Status = 1
response.Message = lang.Get("update_success")
response.Data = company
json.NewEncoder(w).Encode(response)
}
// swagger:route DELETE /admin/company/{id} admin deleteCompany
// Delete company
//
// security:
// - apiKey: []
// responses:
// 401: CommonError
// 200: CommonSuccess
// Create handles Delete get company
func (h *BaseHandlerSqlx) DeleteCompany(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
errmessage := models.DeleteCompany(h.db, vars["id"])
if errmessage != "" {
json.NewEncoder(w).Encode(ErrHandler(errmessage))
return
}
successresponse := CommonSuccess{}
successresponse.Status = 1
successresponse.Message = lang.Get("delete_success")
w.Header().Set("content-type", "application/json")
json.NewEncoder(w).Encode(successresponse)
}
// documentation for developers
opts := middleware.SwaggerUIOpts{SpecURL: "/swagger.yaml"}
sh := middleware.SwaggerUI(opts, nil)
r.Handle("/docs", sh)
// documentation for share
// opts1 := middleware.RedocOpts{SpecURL: "/swagger.yaml"}
// sh1 := middleware.Redoc(opts1, nil)
// r.Handle("/docs", sh1)
After we’ve finished with the API, we can use the command below in the root directory to generate swagger yaml or JSON files from swagger comments.
./swagger.yaml -scan-models swagger produce spec
It will create a file called swagger.yaml in the root directory. The same method can be used to generate a JSON file.
We may add routes for documentation in the main using this file.
Go ahead and file.
Generate Clients using Swagger Documentation
Swagger, as indicated earlier, isn’t just for API documentation; we can also use it to construct clients. Consider the following AngularJS client creation example.
Example: Client Generation for AngularJS.
npm install ng-swagger-gen --save-dev
sudo node_modules/.bin/ng-swagger-gen -i ../swagger.yamal -o backend/src/app
It will generate services files for all of the APIs that will be referenced in the Swagger document. Clients for other frameworks and technologies can also be generated in the same way.
Finally, creating a Golang documentation with swagger is not as hard as it is seem. Following the above listed processes would help you achieve that. Alternatively you can visit Github repository: go-swagger-example for complete documentation.