Being a developer, you might understand how important it is to document and organize all the APIs, and you also know not every developer likes this documentation part. For that, we need some tools that can be easily used to prepare API documentation. Well, the very first tool that strikes is Swagger.

What is Swagger?

Swagger is a set of open-source tools for writing REST-based APIs. It simplifies the process of writing APIs by notches, specifying the standards & providing the tools required to write and organize scalable APIs.

Why use Swagger?

As mentioned before, when we have to follow methodology, documentations are a ‘must.’ With swagger, we can create API documentation by just adding comments in code.

Now the question might strike Is Swagger just for API documentation? No, it’s not.

With Swagger, we can generate clients for any technologies like Node, AngularJS, PHP, and many more. Thus, it is good for naming conventions, maintaining best practices, and common structure for our application. Also, it does save coding time on the client side.

Now, let’s see what we will do in this tutorial.

Tutorial Goal: Golang API Documentation using Go Swagger.

In this tutorial, we will make a demo application and prepare API documentation using go-swagger. Watch the video below to have a look at what we are going to build in this tutorial.

Go Swagger Example: How to Create Golang API Documentation

Without further ado, let’s get started with the coding part. Here are the step-by-step instructions to create Golang API documentation.

Create Project Directory

Use the below commands to create a project directory.

Copy Text
mkdir goswagger
cd goswagger
go mod init goswagger

Install Swagger

Copy Text
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

Downloading Dependencies

Next, we will download the required dependencies
For this demo, we will use:

  • Mux: Handling http requests and routing

Command:

Copy Text
 go get github.com/gorilla/mux
  • Swagger: Handling swagger doc

Command:

Copy Text
go get github.com/go-openapi/runtime/middleware
  • MySQL: Handling MySQL queries

Commands:

Copy Text
github.com/go-sql-driver/mysql
go get github.com/jmoiron/sqlx

Import Database company.sql from the Root Directory

Create main.go in the root directory. Establish database connection, routing for APIs, and Swagger documentation.

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")

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

Copy Text
//  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

For security definition, we can use the API key, which can be verified for every API.

Models

Create models for requests and responses for our APIs. Below are some examples of structure with swagger comments. We can add name, type, schema, required, and description for every field.

Copy Text
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"`
}

API Routes

We can add swagger comments for every route. In which we can specify request and response models, route name, the request method, description, and API key if required.

Copy Text
// 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)
}

After done with api, we can generate swagger yaml or JSON files from swagger comments using the below command in the root directory.

swagger generate spec -o ./swagger.yaml –scan-models
It will generate a swagger.yaml file in the root directory. We can also create a JSON file the same way.

Using this file, we can add routes for documentation in the main.go file.

Copy Text
   // 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)

Once you are done with the steps, documentation for developers will look something like the below images.

documentation for developers will look

Refer to the below documentation for Read-Only APIs that you want to share with external developers.

documentation for Read-Only APIs

Generate Clients using Swagger Documentation

As mentioned above in the beginning, Swagger isn’t just for API documentation; we can also generate clients using Swagger. Let’s see the below example for client generation for AngularJS.

Example: Client Generation for AngularJS.

Copy Text
npm install ng-swagger-gen --save-dev
sudo node_modules/.bin/ng-swagger-gen -i ../swagger.yaml -o backend/src/app

It will create services files for all the APIs that are to be included in the Swagger document. In the same way, you can generate clients for other frameworks and technologies.

So, this was about creating Golang API Documentation using go-swagger. For complete documentation, please feel free to visit the github repository: go-swagger-example

Conclusion

I hope the Go Swagger tutorial was helpful to you and has cleared your doubts regarding Swagger Documentation for Golang APIs. If you are a Golang enthusiast, please visit the Golang Tutorials page for more such tutorials and start learning more each day! Feel free to drop comments and connect in case you have any questions.

Sometimes many requirements demand skilled, knowledgeable, and dedicated developers for their Golang projects. For such requirements, it is advisable to contact and hire proficient developers. Are you looking for such developers for your projects too? If yes, then why waste time? Contact Bacancy immediately to hire Golang developers with fundamental and advanced Golang knowledge.

Golang Tutorials

Connect Now

Get In Touch

[email protected]

Your Success Is Guaranteed !

We accelerate the release of digital product and guaranteed their success

We Use Slack, Jira & GitHub for Accurate Deployment and Effective Communication.

How Can We Help You?