Streamlining API Documentation in Go: Swagno vs. Swaggo


The Traditional Challenges of API Documentation

In the dynamic realm of software development, maintaining up-to-date documentation has always been a daunting task. Developers often find themselves engrossed in the complexities of debugging and feature development, leaving documentation as an afterthought. This traditional approach of switching contexts to update separate text-based files can lead to documentation that rapidly falls out of sync, especially in fast-paced, iterative development environments.

Swaggo: A Step Towards Integrated Documentation

The Go community has made strides in addressing this challenge with tools like Swaggo. Swaggo integrates documentation directly into the development environment, allowing developers to update documentation alongside their code. This method reduces the context switching that typically accompanies documentation tasks.

Example of Swaggo Annotations
// ShowAccount godoc
// @Summary      Show an account
// @Description  get string by ID
// @Tags         accounts
// @Accept       json
// @Produce      json
// @Param        id   path      int  true  "Account ID"
// @Success      200  {object}  model.Account
// @Failure      400  {object}  httputil.HTTPError
// @Failure      404  {object}  httputil.HTTPError
// @Failure      500  {object}  httputil.HTTPError
// @Router       /accounts/{id} [get]
func (c *Controller) ShowAccount(ctx *gin.Context) {
  id := ctx.Param("id")
  aid, err := strconv.Atoi(id)
  if err != nil {
    httputil.NewError(ctx, http.StatusBadRequest, err)
    return
  }
  account, err := model.AccountOne(aid)
  if err != nil {
    httputil.NewError(ctx, http.StatusNotFound, err)
    return
  }
  ctx.JSON(http.StatusOK, account)
}

With Swaggo, annotations are used to define API details directly in the code. This method brings some clear benefits:

  • Explicit Documentation: Annotations demarcate documentation within the code.
  • Community Familiarity: Many developers are accustomed to this style, drawing parallels to Java’s Javadoc (although some gophers may argue this is not idiomatic to go).
  • Robust Tooling: Swaggo benefits from a range of tools and established practices in the annotation-based documentation ecosystem.

However, there are some drawbacks:

  • Code Clutter: Extensive documentation requirements can make the code less readable.
  • Additional Build Steps: Commands like swag init are necessary to generate documentation, adding extra steps to the development process.
  • Managing Generated Files: Keeping documentation files in sync with the codebase adds complexity.

Swagno: A Fresh Perspective on Documentation

In response to these challenges, a new project, Swagno, offers an alternative approach to embedding documentation in Go code. Swagno emphasizes a clean and streamlined method:

  • No Annotations: Swagno’s design leads to more readable code, free from the clutter of documentation-specific annotations.
  • No Commands: The absence of extra build steps or commands like swag init streamlines the workflow.
  • No Files: Documentation embedded directly within the code offers immediate control and clarity, and avoids any potential syncing problems.
Initializing Swagno

Initializing a swagno object is as easy as the code shown below. Just pass in a swagno config.

sw := swagno.New(swagno.Config{Title: "Testing API", Version: "v1.0.0"})

Defining Endpoints and Parameters

Swagno simplifies endpoint definition using a functional options pattern, enhancing readability and ease of use. Below is an example of how you would define your endpoints.

endpoints := []*endpoint.EndPoint{
    endpoint.New(
      endpoint.GET,
      "/product/page",
      endpoint.WithTags("product"), endpoint.WithSuccessfulReturns([]response.Response{response.New(models.EmptySuccessfulResponse{}, "OK", "200")}),        endpoint.WithErrors([]response.Response{response.New(models.UnsuccessfulResponse{}, "Bad Request", "400")}),
      endpoint.WithDescription(desc),
      endpoint.WithProduce([]mime.MIME{mime.JSON, mime.XML}),
      endpoint.WithConsume([]mime.MIME{mime.JSON}),
    )
    // Other endpoints...
}

Swagno supports a wide array of parameter types, following the OpenAPI Specification (OAS), with functional options for user-friendly configuration.

Dynamically Generating Docs

The below code shows an HTTP handler set to serve the generated OAS documentation. This real-time generation ensures that the documentation is always up-to-date with the latest code changes, so you don’t have to worry about any documentation drift happening from forgetting to re-run any build commands.

sw.AddEndpoints(endpoints)
http.HandleFunc("/swagger/", swagger.SwaggerHandler(sw.MustToJson()))
http.ListenAndServe(":8080", nil)

The Swagno Advantage

  • Cleaner Code Without Annotations: Swagno’s approach avoids the use of annotations, leading to cleaner and more readable code. This helps in focusing more on the business logic without the visual clutter of documentation-specific annotations.
  • Type Safety: Swagno ensures that developers use valid options for configurations, reducing the learning curve for those new to OAS.
  • Dynamic Documentation Generation: Swagno generates up-to-date documentation in real-time, minimizing the risk of documentation drift.
  • Future Developments: The Swagno team is working on integrating with popular HTTP server libraries and adding more validation to the API to help developers with minimal OAS knowledge start writing API docs with little learning curve.

Conclusion

Swagno provides a new way to create and manage API documentation compared to traditional methods. Its approach of embedding documentation within the code aligns with modern development practices, offering a more integrated and efficient workflow. While Swaggo also provides a robust solution, Swagno caters to those who prefer an embedded documentation style without annotations. Ultimately, the choice between Swaggo and Swagno depends on individual preferences and project requirements.

Happy coding with whichever tool you choose!

Email: [email protected]
Linkedin: https://www.linkedin.com/in/eric-howard-8a4166127/

References:

  • https://github.com/swaggo/swag
  • https://github.com/go-swagno/swagno