Skip to content

Go Web APIs — Building Production REST APIs with Go, Validation, and Documentation

DodaTech Updated 2026-06-28 1 min read

In this tutorial, you will learn about Go Web APIs. We cover key concepts, practical examples, and best practices to help you master this topic.

Go web APIs use Gin/Echo for routing, go-playground/validator for validation, and swaggo/swag for OpenAPI documentation generation.

What You'll Learn

  • API request validation
  • Error handling patterns
  • API documentation
  • Versioning strategies

Why It Matters

Production APIs need validation, docs, and versioning. Docker registry API uses validation. DodaZIP API validates file uploads.

Real-World Use

Public REST APIs, internal Microservices, partner integrations, mobile backends.

Request Validation

type CreateUserRequest struct {
    Name  string `json:"name"  binding:"required,min=2,max=100"`
    Email string `json:"email" binding:"required,email"`
    Age   int    `json:"age"   binding:"gte=0,lte=150"`
}

func createUser(c *gin.Context) {
    var req CreateUserRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        c.JSON(400, gin.H{"errors": parseValidationErrors(err)})
        return
    }
    c.JSON(201, req)
}

func parseValidationErrors(err error) []string {
    var errors []string
    for _, e := range err.(validator.ValidationErrors) {
        errors = append(errors, fmt.Sprintf(
            "%s is %s", e.Field(), e.Tag(),
        ))
    }
    return errors
}

Error Handling

type APIError struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
    Detail  string `json:"detail,omitempty"`
}

func handleError(c *gin.Context, status int, msg string) {
    c.JSON(status, APIError{
        Code:    status,
        Message: msg,
    })
}

// Usage
if err != nil {
    handleError(c, 500, "Internal server error")
    return
}

API Documentation

// @Summary Create a new user
// @Description Creates a user with name, email, and age
// @Tags users
// @Accept json
// @Produce json
// @Param user body CreateUserRequest true "User data"
// @Success 201 {object} User
// @Failure 400 {object} APIError
// @Router /users [post]
func createUser(c *gin.Context) { /* ... */ }
swag init
# Generates docs, swagger.json, swagger.yaml

Versioning

v1 := r.Group("/api/v1")
{
    v1.GET("/users", v1ListUsers)
    v1.POST("/users", v1CreateUser)
}

v2 := r.Group("/api/v2")
{
    v2.GET("/users", v2ListUsers)
    v2.POST("/users", v2CreateUser)
}
Topic Description Link
Go Web Frameworks Gin, Echo, Fiber {{< ref "40-web-frameworks" >}}
Go Middleware HTTP middleware {{< ref "41-middleware" >}}
Go Testing HTTP Testing APIs {{< ref "42-testing-http" >}}

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro

Home Browse Go