www.bacancytechnology.com
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. mkdir goswagger cd goswagger go mod init goswagger
Install Swagger download_url=$(curl -s https://api.github.com/repos/goswagger/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:
go get github.com/gorilla/mux
Swagger: Handling swagger doc
Command:
go get github.com/goopenapi/runtime/middleware
MySQL: Handling MySQL queries
Commands:
github.com/go-sql-driver/mysql go get github.com/jmoiron/sqlx
Import Database company.sql from the Root Directory
root directory. Create main.go in the Establish database connection, routing for APIs, and Swagger documentation.
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 // 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.
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.
// 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(la ng.Get("invalid_requuest"))) return } company, errmessage := models.PostCompanySqlx(h.db, reqcompany) if errmessage != "" { json.NewEncoder(w).Encode(ErrHandler(er rmessage)) 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-formurlencoded // 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(l ang.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(l ang.Get("invalid_requuest"))) return }
company, errmessage :=
models.EditCompany(h.db, &reqcompany, id) if errmessage != "" { json.NewEncoder(w).Encode(ErrHandler(er rmessage)) 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(er rmessage)) return } successresponse := CommonSuccess{}
successresponse.Status = 1
successresponse.Message = lang.Get("delete_success") w.Header().Set("content-type", "application/json") json.NewEncoder(w).Encode(successrespon se) }
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.
// 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.
Refer to the below documentation for ReadOnly APIs that you want to share with external developers.
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.
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-swaggerexample
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.
Thank You
www.bacancytechnology.com