In this article, we explore the powerful tool 'go-swagger', and how it can be used to generate Swagger documentation files directly from Go code. Swagger, also known as OpenAPI, is a widely-accepted standard for designing, building, and documenting REST APIs, providing interactive documentation, client SDK generation, and API discoverability. Why do you need Swagger docs? As a beginner software engineer, understanding and implementing efficient documentation practices is critical. Documenting your commercial code helps your colleagues better understand the design and function of your codebase, making it easier to maintain and expand upon. However, manually writing API documentation can be time-consuming and error-prone. That's where tools like go-swagger come in. This open-source project can generate Swagger specification documentation automatically from your Go code. This means you'll be able to focus on developing your code, while also maintaining clear, accurate, and up-to-date API documentation with minimal effort. The generation of a Swagger specification from the source code of a Go program is done by two things: using utility, which is called from the command line; go-swagger API wrappers in Go-code, i.e., some preparation needs to be done before in the code so that the generation utility will generate what you expect to see; Install go-swagger go get -u github.com/go-swagger/go-swagger/cmd/swagger Prepare some code We need to create a directory at the external level of the project, in which we create a single file inside. In fact, you can put the directory anywhere, as long as the package is called , and the name of the file does not matter. I will give here an example of the content of the file, so that it will be clear enough for understanding: docs docs.go docs docs.go // Package classification Hellow Hachernoon // // Documentation for my go project // // Schemes: http // BasePath: / // Version: 1.0.0 // Host: // // Consumes: // - application/json // - multipart/form-data // // Produces: // - application/json // // Security: // - basic // // SecurityDefinitions: // basic: // type: basic // // swagger:meta package docs A couple of comments: do not set the and sections at all if there is no authorization on the server; Security SecurityDefinitions specifies a list of content types that are used in your requests. In most cases, a single is sufficient, but don't forget to include or something else if you're using other content types in requests. The same with . Consumes application/json multipart/form-data Produces Importing In your looks like this: docs main.go import _ "path/to/docs" Don’t forget to import it, otherwise, you will catch the joy of the fact that empty documentation will be generated without errors. Route wrapper Write all the binding in the same package, it can be in one file, it can be in several, or even in , it doesn't matter. Perhaps, you can write wrappers right where your handlers are, but I haven’t tried it, so I won’t argue with it, but in this case, you need to start importing these wrappers in the package. docs docs.go docs For example, let's create a file. Let's describe a wrapper for one route in it: docs/routes.go /payloads // swagger:route GET /payload payloads GetPayload // Get payload with given ID. // responses: // 200: GetPayloadRes200 // swagger:parameters GetPayload type GetPayloadReq struct { core.GetPayloadReq } // swagger:response GetPayloadRes200 type GetPayloadRes200 struct { // in:body Body core.GetPayloadRes } Our points: such a block must be written for each route; GET specifies the request method (GET, POST, …); - a route URL; /payload - a section name (for grouping in Swagger UI); payloads - request identifier, the name can be anything. It just must be unique for each route, and it is used below for linking with the request parameter description block; GetPayload - request description for Swagger UI; Get payload with given ID. After responses: all possible variants of the request-response are described. In this case, it is specified that the only response can be 200: . The status (200) and the name of the Go-type corresponding to the description of this response ( ) are indicated. It is important to note that it is not necessary to describe literally all possible responses, such as 500 Internal Server Error, for example, since this is already clear that it can always happen. It is logical to describe those responses that are separately registered in the request handler, such as 200, 400, 404; GetPayloadRes200 GetPayloadRes200 says that the type, written after this comment, determines the format of the request input with the ID. It describes both Body-parameters and Query-parameters, in general, all input is there; // swagger:parameters GetPayload GetPayload - type name with input parameters, can be any, no restrictions, but probably should be public; GetPayloadReq - just embedding a type with a real description of the input parameters into a given type used to generate documentation. The idea is simple. You write your own route handlers, they have input parameters for which you described the structure, which, of course, is stored somewhere else, convenient for you. In this structure, for generation, we simply refer to this structure with input parameters, so that we do not have to go into this docs package every time we change the input parameters. And this is very cool: when adding, changing, or deleting parameters, both input, and output, nothing needs to be edited in at all! But note that new types of query responses will still require edits in this package; core.GetPayloadReq docs says that the type, written after this comment, determines the format of the requested output. The status code is described above, so the name does not have to follow any rules. Call it whatever you want, but in order not to get confused and to make everything as generic as possible, I recommend naming such things according to some pattern, for example, the name of the request + Req, + ResXXX, etc.; // swagger:response GetPayloadRes200 GetPayloadRes200 see the POST request section below. core.GetPayloadRes GET request parameters This type of request is characterized by the following details: When describing input parameters, embed the type with the description of the parameters, i.e., not , just ; Body core.GetPayload core.GetPayload Each parameter must be a Query parameter, i.e. these are the parameters we are talking about. Well, the parameters that are inside the URL. If we discard the parameters inside the URL, then the description of the GET request parameters should look like this: /payload?id=..., type GetPayloadReq struct { // in:query PayloadID string `query:"PayloadID"` } It is important here, firstly, to write (once for the entire list of Query parameters), and secondly, to specify the query: tag for each field. The structure of the output parameters follows the same rules as the input parameters for a POST request, since the output is always Body. // in:query "paramName" POST request parameters This type of request is characterized by the following details: When describing input parameters, you should not use embedding, but specify the Body field: // swagger:parameters NewPayload type NewPayloadReq struct { // in:body Body core.NewPayloadReq } It is important here, firstly, to write , and secondly, to put the name of the field; // in:body Body No comments are needed in the parameter type itself but specify the JSON tag for each input field, if you, of course, use JSON in requests. For form data, do not use a tag, use a comment before the parameter. For details such as the description of the parameter for uploading a file to the server, see the documentation or ask your colleagues. json:"paramName" // in: formData The structure of the output parameters follows the same rules. Generate Swagger doc cd /path/to/your/project SWAGGER_GENERATE_EXTENSION=false swagger generate spec -o /path/to/swagger.yaml It is important that your project has file at the top level, because the go-swagger utility relies on when the generation starts. main.go is an optional setting that removes the following default behavior: Go type descriptions in swagger model descriptions. In other words, by default, the utility saves information about what Go-types are behind each field of each model and stores this in special attributes that . In my opinion, it is absolutely unnecessary information for users of the Swagger specification. SWAGGER_GENERATE_EXTENSION Swagger UI