Agamya Samuel
Available for work

Building Scalable APIs with Go

June 15, 20242 min read

Why Go for APIs?

Go's simplicity, performance, and excellent standard library make it an ideal choice for building production-grade APIs. Unlike heavier frameworks in other languages, Go gives you fine-grained control over every aspect of your HTTP server.

Project Structure

A well-organized Go API project should separate concerns clearly:

api/
├── cmd/
│   └── server/
│       └── main.go
├── internal/
│   ├── handler/
│   ├── middleware/
│   ├── model/
│   └── repository/
├── go.mod
└── go.sum

Routing with Chi

While the standard net/http package works fine, Chi provides a lightweight, composable router:

r := chi.NewRouter()
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
 
r.Route("/api/v1", func(r chi.Router) {
    r.Get("/users", handler.ListUsers)
    r.Post("/users", handler.CreateUser)
    r.Get("/users/{id}", handler.GetUser)
})

Error Handling

Consistent error responses are critical for API consumers:

type APIError struct {
    Code    int    `json:"code"`
    Message string `json:"message"`
}
 
func writeError(w http.ResponseWriter, status int, msg string) {
    w.Header().Set("Content-Type", "application/json")
    w.WriteHeader(status)
    json.NewEncoder(w).Encode(APIError{
        Code:    status,
        Message: msg,
    })
}

Middleware Chain

Build a composable middleware chain for cross-cutting concerns:

  • Authentication — validate JWT tokens
  • Rate limiting — protect against abuse
  • CORS — handle cross-origin requests
  • Logging — request/response logging
  • Recovery — catch panics gracefully

Testing

Use Go's built-in httptest package for integration tests:

func TestGetUser(t *testing.T) {
    req := httptest.NewRequest("GET", "/api/v1/users/1", nil)
    w := httptest.NewRecorder()
    
    router.ServeHTTP(w, req)
    
    assert.Equal(t, 200, w.Code)
}

Conclusion

Go's philosophy of simplicity and explicitness leads to APIs that are easy to understand, maintain, and scale. The combination of Chi for routing, clean error handling, and composable middleware gives you a production-ready foundation.

Agamya Samuel

Agamya Samuel

Software Developer & Cloud Architect