routegroup

package module
v0.1.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 22, 2024 License: MIT Imports: 1 Imported by: 22

README

routegroup Build Status Go Report Card Coverage Status godoc

routegroup is a tiny Go package providing a lightweight wrapper for efficient route grouping and middleware integration with the standard http.ServeMux.

Features

  • Simple and intuitive API for route grouping and route mounting.
  • Easy middleware integration for individual routes or groups of routes.
  • Seamless integration with Go's standard http.ServeMux.

Why One More Router?

Despite what the section title might suggest, routegroup is not another router. With Go's 1.22 release, the standard library's routing enhancements have made it possible to implement sophisticated routing logic without the need for external libraries. These enhancements provide the foundation for building fully functional HTTP servers directly with the tools Go offers.

However, while the standard http.ServeMux has become more powerful, it still lacks some conveniences, particularly in route grouping and middleware management. This is where routegroup steps in. Rather than reinventing the wheel, routegroup aims to supplement the existing routing capabilities by providing a minimalist abstraction layer for efficiently grouping routes and applying middleware to these groups.

Install and update

go get -u github.com/go-pkgz/routegroup

Usage

Creating a New Route Group

To start, create a new route group without a base path:

func main() {
    mux := http.NewServeMux()
    group := routegroup.New(mux)
}

Adding Routes with Middleware

Add routes to your group, optionally with middleware:

    group.Use(loggingMiddleware, corsMiddleware)
    group.Handle("/hello", helloHandler)
    group.Handle("/bye", byeHandler)

Creating a Nested Route Group

For routes under a specific path prefix:

    apiGroup := routegroup.Mount(mux, "/api")
    apiGroup.Use(loggingMiddleware, corsMiddleware)
    apiGroup.Handle("/v1", apiV1Handler)
    apiGroup.Handle("/v2", apiV2Handler)

Complete Example

Here's a complete example demonstrating route grouping and middleware usage:

package main

import (
	"fmt"
	"net/http"
	
	"github.com/go-pkgz/routegroup"
)

func main() {
	mux := http.NewServeMux()
	apiGroup := routegroup.WithBasePath(mux, "/api")

	// add middleware
	apiGroup.Use(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			fmt.Println("Request received")
			next.ServeHTTP(w, r)
		})
	})

	// Route handling
	apiGroup.Handle("GET /hello", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("Hello, API!"))
	})

	http.ListenAndServe(":8080", mux)
}

Applying Middleware to Specific Routes

You can also apply middleware to specific routes:

    apiGroup.With(corsMiddleware, helloHandler).Handle("GET /hello", helloHandler)

Alternative Usage with Set

You can also use the Set method to add routes and middleware:

    mux := http.NewServeMux()
	group := routegroup.New(mux)
	group.Set(b func(*routegroup.Bundle) {
		b.Use(loggingMiddleware, corsMiddleware)
		b.Handle("GET /hello", helloHandler)
		b.Handle("GET /bye", byeHandler)
    })
    http.ListenAndServe(":8080", mux)

Contributing

Contributions to routegroup are welcome! Please submit a pull request or open an issue for any bugs or feature requests.

License

routegroup is available under the MIT license. See the LICENSE file for more info.

Documentation

Overview

Package routegroup provides a way to group routes and applies middleware to them. Works with the standard library's http.ServeMux.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Bundle

type Bundle struct {
	// contains filtered or unexported fields
}

Bundle represents a group of routes with associated middleware.

func Mount

func Mount(mux *http.ServeMux, basePath string) *Bundle

Mount creates a new group with a specified base path.

Example
package main

import (
	"net/http"

	"github.com/go-pkgz/routegroup"
)

func main() {
	mux := http.NewServeMux()
	group := routegroup.Mount(mux, "/api")

	// apply middleware to the group
	group.Use(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Header().Add("X-Test-Middleware", "true")
			next.ServeHTTP(w, r)
		})
	})

	// add test handlers
	group.Handle("GET /test", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
	})
	group.Handle("POST /test2", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
	})

	// start the server
	if err := http.ListenAndServe(":8080", mux); err != nil {
		panic(err)
	}
}

func New

func New(mux *http.ServeMux) *Bundle

New creates a new Group.

Example
package main

import (
	"net/http"

	"github.com/go-pkgz/routegroup"
)

func main() {
	mux := http.NewServeMux()
	group := routegroup.New(mux)

	// apply middleware to the group
	group.Use(func(next http.Handler) http.Handler {
		return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
			w.Header().Add("X-Test-Middleware", "true")
			next.ServeHTTP(w, r)
		})
	})

	// add test handlers
	group.Handle("GET /test", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
	})
	group.Handle("POST /test2", func(w http.ResponseWriter, _ *http.Request) {
		w.WriteHeader(http.StatusOK)
	})

	// start the server
	if err := http.ListenAndServe(":8080", mux); err != nil {
		panic(err)
	}
}

func (*Bundle) Handle

func (b *Bundle) Handle(path string, handler http.HandlerFunc)

Handle adds a new route to the Group's mux, applying all middlewares to the handler.

func (*Bundle) Set

func (b *Bundle) Set(configureFn func(*Bundle))

Set allows for configuring the Group.

Example
package main

import (
	"net/http"

	"github.com/go-pkgz/routegroup"
)

func main() {
	mux := http.NewServeMux()
	group := routegroup.New(mux)

	// configure the group using Set
	group.Set(func(g *routegroup.Bundle) {
		// apply middleware to the group
		g.Use(func(next http.Handler) http.Handler {
			return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				w.Header().Add("X-Test-Middleware", "true")
				next.ServeHTTP(w, r)
			})
		})
		// add test handlers
		g.Handle("GET /test", func(w http.ResponseWriter, _ *http.Request) {
			w.WriteHeader(http.StatusOK)
		})
		g.Handle("POST /test2", func(w http.ResponseWriter, _ *http.Request) {
			w.WriteHeader(http.StatusOK)
		})
	})

	// start the server
	if err := http.ListenAndServe(":8080", mux); err != nil {
		panic(err)
	}
}

func (*Bundle) Use

func (b *Bundle) Use(middleware func(http.Handler) http.Handler, more ...func(http.Handler) http.Handler)

Use adds middleware(s) to the Group.

func (*Bundle) With

func (b *Bundle) With(middleware func(http.Handler) http.Handler, more ...func(http.Handler) http.Handler) *Bundle

With adds new middleware(s) to the Group and returns a new Group with the updated middleware stack.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL