Skip to content

quentinalbertone/httpx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

HTTPX

httpx is a small helper library to work with Go's standard net/http package. The package is designed to be simple yet powerful, providing just the essential features needed for building HTTP APIs without the complexity of larger frameworks.

The main asset of httpx is its error-returning handlers and middleware pattern. Instead of handling errors within each handler, errors are returned and managed centrally by a single errorHandler function. This dramatically reduces boilerplate error handling code in your handlers.

The router and handler groups can be used standalone with the standard http.ListenAndServe or with the provided httpx.ListenAndServe function which includes graceful shutdown support.

Key Features:

  • Error-returning handlers/middlewares: returns errors instead of handling them inline
  • Centralized error handling: All errors managed by a single errorHandler function
  • Route grouping: Organize routes with prefixes and shared middleware
  • Middleware chain: Composable middleware with Next() pattern
  • Graceful shutdown: Optional ListenAndServe with built-in signal handling

Basic Usage

import "https://github.com/quentinalbertone/httpx"

func main() {
    router := httpx.NewRouter(nil, nil)
    router.GET("/hello", func(w http.ResponseWriter, r *http.Request) error {
        return httpx.JSON(w, http.StatusOK, map[string]string{"message": "Hello, World!"})
    })
    http.ListenAndServe(":8080", router)
}

With Middleware

func AuthMiddleware(w http.ResponseWriter, r *http.Request) error {
    // Check authentication
    if !isAuthenticated(r) {
        return httpx.JSON(w, http.StatusUnauthorized, map[string]string{"error": "unauthorized"})
    }
    return httpx.Next(w, r) // Continue to next handler
}

func main() {
	router := httpx.NewRouter(nil, nil)
	router.GET("/protected", AuthMiddleware, func(w http.ResponseWriter, r *http.Request) error {
		return httpx.JSON(w, http.StatusOK, map[string]string{"data": "secret"})
	})
}

Route Groups

func main() {
    router := httpx.NewRouter(nil, nil)
    api := router.Group("/api")
    {
        v1 := api.Group("/v1")

        v1.GET("/users", GetUsers)
        v1.POST("/users", CreateUser)
        v1.PUT("/users/{id}", UpdateUser)
    }
}

Error Handling

func MyErrorHandler(fn httpx.HandlerFunc) http.HandlerFunc {
    return func(w http.ResponseWriter, r *http.Request) {
        if err := fn(w, r); err != nil {
            // Custom error handling logic
            var status int
            var msg string
            switch {
            case errors.Is(err, customerr.ValidationErr):
                status = http.StatusBadRequest
                msg = err.Error()
            case errors.Is(err, customerr.NotFoundErr):
                status = http.StatusNotFound
                msg = err.Error()
            case errors.Is(err, ierrors.NotImplementedErr):
                status = http.StatusNotImplemented
                msg = "not implemented"
            case errors.Is(err, ierrors.UnauthorizedErr):
                status = http.StatusUnauthorized
                msg = "not authorized"
            default:
                status = http.StatusInternalServerError
                err = errors.New("internal server error")
            }
            httpx.JSON(w, http.StatusInternalServerError, map[string]string{"error": err.Error()})
        }
    }
}

func main() {
    router := httpx.NewRouter(nil, MyErrorHandler)
}

Using with Standard Library

func main() {
    router := httpx.NewRouter(nil, nil)
    router.GET("/api/data", GetDataHandler)
    http.ListenAndServe(":8080", router)
}

Using with Graceful Shutdown

func main() {
    router := httpx.NewRouter(nil, nil)
    router.GET("/api/data", GetDataHandler)

    serverConf := func(server *http.Server) {
        server.Addr = ":8080"
        server.ReadTimeout = 5 * time.Second
        server.WriteTimeout = 10 * time.Second
    }

    ctx := context.Background()
    if err := httpx.ListenAndServe(ctx, router, serverConf); err != nil {
        log.Fatal(err)
    }
}

The package is designed to be minimal and focused: it's a small helper that makes working with Go's net/http package more convenient by centralizing error handling and providing useful routing utilities.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages