router

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Oct 2, 2024 License: MIT Imports: 5 Imported by: 0

README

go-router Documentation

go-router is a lightweight, flexible, and idiomatic HTTP router for Go web applications. It leverages Go's standard net/http package and the latest routing enhancements in Go 1.22 to provide powerful routing capabilities without external dependencies.

Overview

  • Method-Based Routing: Easily define routes for GET, POST, PUT, PATCH, DELETE, OPTIONS, and HEAD methods.
  • Route Grouping: Organize routes under common base paths using groups.
  • Middleware Support: Apply middleware functions globally or per group.
  • Custom 404, 405 and 500 Handlers: Set custom handlers for NotFound (404) and MethodNotAllowed (405) responses.
  • Trailing Slash Handling: Configure automatic redirection of trailing slashes.
  • Static File Serving: Serve static files and directories seamlessly.
  • Built on Standard Library: Utilizes Go's net/http package, ensuring performance and reliability.
  • No External Dependencies: Keeps your application lightweight and maintainable.

Installation

Ensure you have Go 1.22 or later installed to leverage the latest routing enhancements.

To install go-router, run:

go get github.com/donseba/go-router

Package Contents

Types
Router

The Router struct is the core of the package, providing methods to define routes, apply middleware, and configure routing behavior. Fields

  • *mux http.ServeMux: The underlying HTTP request multiplexer.
  • basePath string: The base path for the router, used in route grouping.
  • redirectTrailingSlash bool: Determines whether to redirect trailing slashes to their non-trailing counterparts.
  • middlewares []Middleware: A slice of middleware functions applied to the router.
  • notFoundHandler http.HandlerFunc: Custom handler for 404 Not Found responses.
  • methodNotAllowedHandler http.HandlerFunc: Custom handler for 405 Method Not Allowed responses.
Middleware

type Middleware func(http.Handler) http.Handler

Represents a middleware function that wraps an http.Handler to perform actions before or after the handler executes.

Functions
New(ht *http.ServeMux) *Router

Creates a new Router instance using the provided http.ServeMux.

NewDefault() *Router

Creates a new Router instance with a default http.ServeMux.

Methods

Route Definition Methods

Define routes for specific HTTP methods.

  • (*Router) Get(pattern string, handler http.HandlerFunc)
  • (*Router) Head(pattern string, handler http.HandlerFunc)
  • (*Router) Post(pattern string, handler http.HandlerFunc)
  • (*Router) Put(pattern string, handler http.HandlerFunc)
  • (*Router) Patch(pattern string, handler http.HandlerFunc)
  • (*Router) Delete(pattern string, handler http.HandlerFunc)
  • (*Router) Options(pattern string, handler http.HandlerFunc)v
Parameters
  • pattern string: The URL pattern for the route. Patterns can include placeholders like {id}. A pattern that ends in “/” matches all paths that have it as a prefix, as always. To match the exact pattern including the trailing slash, end it with {$}, as in /exact/match/{$}.
  • handler http.HandlerFunc: The function to handle requests matching the pattern and method.
Grouping Routes

(*Router) Group(basePath string, fn func(*Router))

Organize routes under a common base path.

Parameters
  • basePath string: The base path for the group.
  • fn func(*Router): A function that receives a sub-router for defining grouped routes.
Middleware

(*Router) Use(middleware Middleware)

Apply middleware functions to the router.

Parameters
  • middleware Middleware: A middleware function to be applied.
Custom Handlers

v(*Router) NotFound(handler http.HandlerFunc)**: Set a custom handler for 404 Not Found responses.

  • (*Router) MethodNotAllowed(handler http.HandlerFunc): Set a custom handler for 405 Method Not Allowed responses.
Parameters
handler http.HandlerFunc: The function to handle the specific response.
Trailing Slash Handling

(*Router) RedirectTrailingSlash(redirect bool)

Configure automatic redirection of trailing slashes.

Parameters
  • redirect bool: If true, requests with trailing slashes are redirected to their non-trailing counterparts.
Serving Static Files
  • (*Router) ServeFiles(pattern string, fs http.FileSystem): Serve static files from a directory.
  • (*Router) ServeFile(pattern string, filepath string): Serve a single static file.
Parameters
  • pattern string: The URL pattern under which the files are served.
  • fs http.FileSystem: The file system to serve files from.
  • filepath string: The path to the file to be served.
HTTP Handling

(*Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

Implements the http.Handler interface, allowing the router to serve HTTP requests.

Internal Methods

handle(method, pattern string, handler http.HandlerFunc)

An internal method used to register handlers for specific HTTP methods and patterns.

Parameters
  • method string: The HTTP method (e.g., GET, POST).
  • pattern string: The URL pattern.
  • handler http.HandlerFunc: The handler function.

Configuration Variables

  • DefaultRedirectTrailingSlash bool: The default setting for trailing slash redirection (default is true).

Usage Guidelines

Defining Routes

Use the provided methods to define routes for specific HTTP methods. Patterns can include placeholders for path parameters.

r.Get("/users/{id}", userHandler)
Grouping Routes

Group related routes under a common base path using the Group method.

r.Group("/api", func(api *Router) {
   api.Get("/users", apiUsersHandler)
   api.Post("/users", apiCreateUserHandler)
})
Applying Middleware

Apply middleware functions globally or to specific route groups.


// Global middleware
r.Use(loggingMiddleware)

// Middleware for a group
r.Group("/admin", func(admin *Router) {
admin.Use(authMiddleware)
admin.Get("/dashboard", adminDashboardHandler)
})
Custom Handlers for 404 and 405 and 500 Responses

Set custom handlers to provide consistent error responses.

r.NotFound(notFoundHandler)
r.MethodNotAllowed(methodNotAllowedHandler)
r.InternalServerError(internalServerErrorHandler)
Trailing Slash Handling

Configure the router to automatically redirect trailing slashes.

r.RedirectTrailingSlash(true) // Enabled by default
Serving Static Files

Serve files from a directory or serve a single file.

// Serve files from the "./static" directory under "/static/"
fs := http.Dir("./static")
r.ServeFiles("/static/", fs)

// Serve a single file
r.ServeFile("/favicon.ico", "./static/favicon.ico")

Important Notes

  • Pattern Matching: Patterns not ending with a slash (/) are treated as exact matches, while patterns ending with a slash are treated as prefix matches.
  • Middleware Order: Middleware functions are applied in the order they are added, wrapping subsequent middleware and the final handler.
  • Custom 404 and 405 Handling: The router uses intercepting response writers to capture 404 and 405 responses from the underlying http.ServeMux and invoke custom handlers.
  • Trailing Slash Redirection: When enabled, requests with trailing slashes are redirected to the same path without the trailing slash.

Future Improvements

  • Automatic OPTIONS Handling: Provide automatic handling of OPTIONS requests.
  • Error Handling Enhancements: Provide mechanisms for handling other HTTP status codes.

Documentation

Index

Constants

View Source
const HeaderFlagDoNotIntercept = "do_not_intercept"

HeaderFlagDoNotIntercept defines a header that is (unfortunately) to be used as a flag of sorts, to denote to this routing engine to not intercept the response that is being written. It's an unfortunate artifact of an implementation detail within the standard library's net/http.ServeMux for how HTTP 404 and 405 responses can be customized, which requires writing a custom response writer and preventing the standard library from just writing it's own hard-coded response.

See:

Author : https://github.com/Rican7 ( https://github.com/golang/go/issues/65648#issuecomment-2100088200 )

Variables

View Source
var (
	DefaultRedirectTrailingSlash = true
	DefaultUseOpenapiDocs        = false
	OpenApiVersion               = "3.0.1"
)

Functions

func PrependIfMissing

func PrependIfMissing(slice []string, s string) []string

Types

type Components

type Components struct {
	Schemas         map[string]Schema         `json:"schemas,omitempty"`         // Reusable schemas
	SecuritySchemes map[string]SecurityScheme `json:"securitySchemes,omitempty"` // Security schemes
}

Components holds reusable components such as schemas and security schemes.

type DocIn

type DocIn struct {
	Object   any
	Required bool
}

type DocOut

type DocOut struct {
	ApplicationType string
	Description     string
	Object          any
}

type Docs

type Docs struct {
	Tags        []string              // Tags for the operation
	Summary     string                // Short summary of the operation
	Description string                // Operation description
	Parameters  []Parameter           // Parameters for the operation
	RequestBody *RequestBody          // Request body for the operation
	Responses   map[string]Response   // Expected responses
	Security    []map[string][]string // Security requirements

	In  map[string]DocIn
	Out map[string]DocOut
}

type Info

type Info struct {
	Title       string `json:"title" validate:"required"`   // API title
	Description string `json:"description,omitempty"`       // API description
	Version     string `json:"version" validate:"required"` // API version
}

Info represents the API metadata.

type MediaType

type MediaType struct {
	Schema *Schema `json:"schema,omitempty"` // Schema describing the type
}

MediaType represents the media type of a request or response body.

type Middleware

type Middleware func(http.Handler) http.Handler

type OpenAPI

type OpenAPI struct {
	Openapi    string                `json:"openapi" validate:"required"` // OpenAPI version (e.g., "3.0.1")
	Info       Info                  `json:"info" validate:"required"`    // API information
	Servers    []Server              `json:"servers,omitempty"`           // Server details
	Paths      map[string]PathItem   `json:"paths" validate:"required"`   // Paths and operations
	Components Components            `json:"components,omitempty"`        // Components such as schemas and security schemes
	Security   []map[string][]string `json:"security,omitempty"`          // Global security settings
	Tags       []Tag                 `json:"tags,omitempty"`              // Tags for API organization
}

OpenAPI represents the root OpenAPI document.

type Operation

type Operation struct {
	Tags        []string              `json:"tags,omitempty"`                // Tags for the operation
	Summary     string                `json:"summary,omitempty"`             // Short summary of the operation
	Description string                `json:"description,omitempty"`         // Operation description
	OperationID string                `json:"operationId,omitempty"`         // Unique operation ID
	Parameters  []Parameter           `json:"parameters,omitempty"`          // Parameters for the operation
	RequestBody *RequestBody          `json:"requestBody,omitempty"`         // Request body for the operation
	Responses   map[string]Response   `json:"responses" validate:"required"` // Expected responses
	Security    []map[string][]string `json:"security,omitempty"`            // Security requirements
}

Operation describes a single API operation on a path.

type Parameter

type Parameter struct {
	Name        string  `json:"name" validate:"required"` // Parameter name
	In          string  `json:"in" validate:"required"`   // Location (e.g., "query", "header", "path")
	Description string  `json:"description,omitempty"`    // Parameter description
	Required    bool    `json:"required,omitempty"`       // Is parameter required?
	Schema      *Schema `json:"schema,omitempty"`         // Schema defining the type
}

Parameter represents a single parameter for an operation.

type PathItem

type PathItem struct {
	Get    *Operation `json:"get,omitempty"`    // GET operation
	Post   *Operation `json:"post,omitempty"`   // POST operation
	Put    *Operation `json:"put,omitempty"`    // PUT operation
	Delete *Operation `json:"delete,omitempty"` // DELETE operation
	Patch  *Operation `json:"patch,omitempty"`  // PATCH operation
}

PathItem describes the operations available on a single path.

func (PathItem) Methods

func (p PathItem) Methods() []string

func (PathItem) SetMethod

func (p PathItem) SetMethod(method string, operation *Operation) PathItem

type RequestBody

type RequestBody struct {
	Description string               `json:"description,omitempty"` // Request body description
	Content     map[string]MediaType `json:"content"`               // Media types supported by the request
	Required    bool                 `json:"required,omitempty"`    // Is request body required?
}

RequestBody represents a request body for an operation.

type Response

type Response struct {
	Description string               `json:"description" validate:"required"` // Response description
	Content     map[string]MediaType `json:"content,omitempty"`               // Media types produced by the response
}

Response describes a single response from an API operation.

type Router

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

func New

func New(ht *http.ServeMux, title string, version string) *Router

func (*Router) AddServerEndpoint

func (r *Router) AddServerEndpoint(url string, description string)

func (*Router) Delete

func (r *Router) Delete(pattern string, handler http.HandlerFunc, doc ...Docs)

func (*Router) Get

func (r *Router) Get(pattern string, handler http.HandlerFunc, doc ...Docs)

func (*Router) Group

func (r *Router) Group(basePath string, fn func(*Router), op ...Operation)

func (*Router) Head

func (r *Router) Head(pattern string, handler http.HandlerFunc, doc ...Docs)

func (*Router) InternalServerError

func (r *Router) InternalServerError(handler http.HandlerFunc)

func (*Router) MethodNotAllowed

func (r *Router) MethodNotAllowed(handler http.HandlerFunc)

func (*Router) NotFound

func (r *Router) NotFound(handler http.HandlerFunc)

func (*Router) OpenAPI

func (r *Router) OpenAPI() *OpenAPI

OpenAPI returns the root documentation tree

func (*Router) OperationID

func (r *Router) OperationID(s string) string

func (*Router) Patch

func (r *Router) Patch(pattern string, handler http.HandlerFunc, doc ...Docs)

func (*Router) Post

func (r *Router) Post(pattern string, handler http.HandlerFunc, doc ...Docs)

func (*Router) Put

func (r *Router) Put(pattern string, handler http.HandlerFunc, doc ...Docs)

func (*Router) RedirectTrailingSlash

func (r *Router) RedirectTrailingSlash(redirect bool)

func (*Router) ServeFile

func (r *Router) ServeFile(pattern string, filepath string)

func (*Router) ServeFiles

func (r *Router) ServeFiles(pattern string, fs http.FileSystem)

func (*Router) ServeHTTP

func (r *Router) ServeHTTP(w http.ResponseWriter, req *http.Request)

func (*Router) Use

func (r *Router) Use(middleware Middleware)

func (*Router) UseOpenapiDocs

func (r *Router) UseOpenapiDocs(use bool)

type Schema

type Schema struct {
	Ref        string            `json:"$ref,omitempty"`       // Reference to a schema
	Type       string            `json:"type,omitempty"`       // Data type (e.g., "string", "object")
	Format     string            `json:"format,omitempty"`     // Data format (e.g., "uuid", "email")
	Properties map[string]Schema `json:"properties,omitempty"` // Properties of the object
	Items      *Schema           `json:"items,omitempty"`      // Schema for array items
	Required   []string          `json:"required,omitempty"`   // Required properties
}

Schema represents the structure of a request or response body.

type SecurityScheme

type SecurityScheme struct {
	Type         string `json:"type" validate:"required"` // Security scheme type (e.g., "http", "apiKey")
	Scheme       string `json:"scheme,omitempty"`         // HTTP Authorization scheme (e.g., "bearer")
	BearerFormat string `json:"bearerFormat,omitempty"`   // Bearer token format
}

SecurityScheme defines a security scheme for the API.

type Server

type Server struct {
	URL         string            `json:"url" validate:"required"` // Server URL
	Description string            `json:"description,omitempty"`   // Server description
	Variables   map[string]string `json:"variables,omitempty"`     // Variables for URL template
}

Server represents an API server.

type Tag

type Tag struct {
	Name        string `json:"name" validate:"required"` // Tag name
	Description string `json:"description,omitempty"`    // Tag description
}

Tag represents a tag for an API operation.

Directories

Path Synopsis
example
openapi command
simple command

Jump to

Keyboard shortcuts

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