router

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Feb 10, 2025 License: MIT Imports: 30 Imported by: 3

README

go-router

A lightweight, generic HTTP router interface for Go that enables framework-agnostic HTTP handling with built-in adapters. This package provides an abstraction for routing, making it easy to switch between different HTTP router implementations.

Installation

go get github.com/goliatone/go-router

Overview

go-router provides a common interface for HTTP routing that can be implemented by different HTTP frameworks. Currently includes a Fiber and HTTPRouter with plans to support more frameworks.

Usage

Basic Example with Fiber
package main

import (
    "github.com/goliatone/go-router"
    "github.com/gofiber/fiber/v2"
)

func main() {
    // Create new Fiber adapter
    app := router.NewFiberAdapter()

    // Add middleware
    app.Router().Use(func(c router.Context) error {
        c.SetHeader("Content-Type", "application/json")
        return c.Next()
    })

    // Add routes
    app.Router().Get("/hello", func(c router.Context) error {
        return c.JSON(200, map[string]string{"message": "Hello World!"})
    })

    // Start server
    app.Serve(":3000")
}
Route Groups
api := app.Router().Group("/api")
{
    api.Post("/users", createUser(store)).Name("user.create")
    api.Get("/users", listUsers(store)).Name("user.list")
    api.Get("/users/:id", getUser(store)).Name("user.get")
    api.Put("/users/:id", updateUser(store)).Name("user.update")
    api.Delete("/users/:id", deleteUser(store)).Name("user.delete")
}
Builder
api := app.Router().Group("/api")

builder := router.NewRouteBuilder(api)

users := builder.Group("/users")
{
    users.NewRoute().
        POST().
        Path("/").
        Description("Create a new user").
        Tags("User").
        Handler(createUser(store)).
        Name("user.create")

    users.NewRoute().
        GET().
        Path("/").
        Description("List all users").
        Tags("User").
        Handler(listUsers(store)).
        Name("user.list")

    users.NewRoute().
        GET().
        Path("/:id").
        Description("Get user by ID").
        Tags("User").
        Handler(getUser(store)).
        Name("user.get")

    users.NewRoute().
        PUT().
        Path("/:id").
        Description("Update user by ID").
        Tags("User").
        Handler(updateUser(store)).
        Name("user.update")

    users.NewRoute().
        DELETE().
        Path("/:id").
        Description("Delete user by ID").
        Tags("User").
        Handler(deleteUser(store)).
        Name("user.delete")

    users.BuildAll()
}

API Reference

Server Interface
type Server[T any] interface {
    Router() Router[T]
    WrapHandler(HandlerFunc) any
    WrappedRouter() T
    Serve(address string) error
    Shutdown(ctx context.Context) error
}
Router Interface
type Router[T any] interface {
    Handle(method HTTPMethod, path string, handler ...HandlerFunc) RouteInfo
    Group(prefix string) Router[T]
    Use(args ...any) Router[T]
    Get(path string, handler HandlerFunc) RouteInfo
    Post(path string, handler HandlerFunc) RouteInfo
    Put(path string, handler HandlerFunc) RouteInfo
    Delete(path string, handler HandlerFunc) RouteInfo
    Patch(path string, handler HandlerFunc) RouteInfo
}
Context Interface
type Context interface {
    Method() string
    Path() string
    Param(name string) string
    Query(name string) string
    Queries() map[string]string
    Status(code int) Context
    Send(body []byte) error
    JSON(code int, v any) error
    NoContent(code int) error
    Bind(any) error
    Context() context.Context
    SetContext(context.Context)
    Header(string) string
    SetHeader(string, string)
    Next() error
}

License

MIT

Documentation

Index

Constants

View Source
const (
	CookieSameSiteDisabled   = "disabled" // not in RFC, just control "SameSite" attribute will not be set.
	CookieSameSiteLaxMode    = "lax"
	CookieSameSiteStrictMode = "strict"
	CookieSameSiteNoneMode   = "none"
)
View Source
const (
	HeaderAuthorization = "Authorization"
	HeaderContentType   = "Content-Type"
)
View Source
const (
	StatusContinue           = http.StatusContinue
	StatusSwitchingProtocols = http.StatusSwitchingProtocols
	StatusProcessing         = http.StatusProcessing
	StatusEarlyHints         = http.StatusEarlyHints

	StatusOK                   = http.StatusOK
	StatusCreated              = http.StatusCreated
	StatusAccepted             = http.StatusAccepted
	StatusNonAuthoritativeInfo = http.StatusNonAuthoritativeInfo
	StatusNoContent            = http.StatusNoContent
	StatusResetContent         = http.StatusResetContent
	StatusPartialContent       = http.StatusPartialContent
	StatusMultiStatus          = http.StatusMultiStatus
	StatusAlreadyReported      = http.StatusAlreadyReported
	StatusIMUsed               = http.StatusIMUsed

	StatusMultipleChoices   = http.StatusMultipleChoices
	StatusMovedPermanently  = http.StatusMovedPermanently
	StatusFound             = http.StatusFound
	StatusSeeOther          = http.StatusSeeOther
	StatusNotModified       = http.StatusNotModified
	StatusUseProxy          = http.StatusUseProxy
	StatusTemporaryRedirect = http.StatusTemporaryRedirect
	StatusPermanentRedirect = http.StatusPermanentRedirect

	StatusBadRequest                   = http.StatusBadRequest
	StatusUnauthorized                 = http.StatusUnauthorized
	StatusPaymentRequired              = http.StatusPaymentRequired
	StatusForbidden                    = http.StatusForbidden
	StatusNotFound                     = http.StatusNotFound
	StatusMethodNotAllowed             = http.StatusMethodNotAllowed
	StatusNotAcceptable                = http.StatusNotAcceptable
	StatusProxyAuthRequired            = http.StatusProxyAuthRequired
	StatusRequestTimeout               = http.StatusRequestTimeout
	StatusConflict                     = http.StatusConflict
	StatusGone                         = http.StatusGone
	StatusLengthRequired               = http.StatusLengthRequired
	StatusPreconditionFailed           = http.StatusPreconditionFailed
	StatusRequestEntityTooLarge        = http.StatusRequestEntityTooLarge
	StatusRequestURITooLong            = http.StatusRequestURITooLong
	StatusUnsupportedMediaType         = http.StatusUnsupportedMediaType
	StatusRequestedRangeNotSatisfiable = http.StatusRequestedRangeNotSatisfiable
	StatusExpectationFailed            = http.StatusExpectationFailed
	StatusTeapot                       = http.StatusTeapot
	StatusMisdirectedRequest           = http.StatusMisdirectedRequest
	StatusUnprocessableEntity          = http.StatusUnprocessableEntity
	StatusLocked                       = http.StatusLocked
	StatusFailedDependency             = http.StatusFailedDependency
	StatusTooEarly                     = http.StatusTooEarly
	StatusUpgradeRequired              = http.StatusUpgradeRequired
	StatusPreconditionRequired         = http.StatusPreconditionRequired
	StatusTooManyRequests              = http.StatusTooManyRequests
	StatusRequestHeaderFieldsTooLarge  = http.StatusRequestHeaderFieldsTooLarge
	StatusUnavailableForLegalReasons   = http.StatusUnavailableForLegalReasons

	StatusInternalServerError           = http.StatusInternalServerError
	StatusNotImplemented                = http.StatusNotImplemented
	StatusBadGateway                    = http.StatusBadGateway
	StatusServiceUnavailable            = http.StatusServiceUnavailable
	StatusGatewayTimeout                = http.StatusGatewayTimeout
	StatusHTTPVersionNotSupported       = http.StatusHTTPVersionNotSupported
	StatusVariantAlsoNegotiates         = http.StatusVariantAlsoNegotiates
	StatusInsufficientStorage           = http.StatusInsufficientStorage
	StatusLoopDetected                  = http.StatusLoopDetected
	StatusNotExtended                   = http.StatusNotExtended
	StatusNetworkAuthenticationRequired = http.StatusNetworkAuthenticationRequired
)
View Source
const ErrorHandlerConfigKey = "error_handler_config"

Variables

View Source
var LoggerEnabled = false

Functions

func DefaultFiberOptions

func DefaultFiberOptions(app *fiber.App) *fiber.App

func DefaultHTTPRouterOptions

func DefaultHTTPRouterOptions(router *httprouter.Router) *httprouter.Router

func GetContextValue added in v0.0.2

func GetContextValue[T any](c Context, key string, def T) T

GetContextValue functions for type assertion

func LogError added in v0.0.2

func LogError(logger Logger, err *RouterError, c Context)

LogError logs the error with context information

func SerializeAsContext added in v0.1.0

func SerializeAsContext(m any) (map[string]any, error)

SerializeAsContext will return any object as a PageContext instance

func ServeOpenAPI added in v0.0.2

func ServeOpenAPI[T any](router Router[T], renderer OpenApiMetaGenerator, opts ...OpenAPIOption)

func StatusText added in v0.1.0

func StatusText(code int) string

Types

type BaseRouter added in v0.0.3

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

Common fields for both FiberRouter and HTTPRouter

func (*BaseRouter) GetRoute added in v0.1.0

func (br *BaseRouter) GetRoute(name string) *RouteDefinition

func (*BaseRouter) PrintRoutes added in v0.0.3

func (br *BaseRouter) PrintRoutes()

func (*BaseRouter) Routes added in v0.0.3

func (br *BaseRouter) Routes() []RouteDefinition

type Context

type Context interface {
	RequestContext
	ResponseWriter
	ContextStore
	// Body parsing
	Bind(v any) error // TODO: Myabe rename to ParseBody

	// Context methods
	Context() context.Context
	SetContext(context.Context)
	Next() error
}

Context represents a generic HTTP context

func NewFiberContext

func NewFiberContext(c *fiber.Ctx) Context

func NewHTTPRouterContext

func NewHTTPRouterContext(w http.ResponseWriter, r *http.Request, ps httprouter.Params, views Views) Context

type ContextStore added in v0.0.2

type ContextStore interface {
	Set(key string, value any)
	Get(key string, def any) any
	GetString(key string, def string) string
	GetInt(key string, def int) int
	GetBool(key string, def bool) bool
}

ContextStore is a request scoped, in-memoroy store to pass data between middleware/handlers in the same request in a fremework agnostic way. If you need persistence between requests use Store e.g. for authentication middleware.

func NewContextStore added in v0.0.2

func NewContextStore() ContextStore
type Cookie struct {
	Name        string    `json:"name"`
	Value       string    `json:"value"`
	Path        string    `json:"path"`
	Domain      string    `json:"domain"`
	MaxAge      int       `json:"max_age"`
	Expires     time.Time `json:"expires"`
	Secure      bool      `json:"secure"`
	HTTPOnly    bool      `json:"http_only"`
	SameSite    string    `json:"same_site"`
	SessionOnly bool      `json:"session_only"`
}

Cookie data for c.Cookie

type ErrorHandler added in v0.1.0

type ErrorHandler = func(Context, error) error

type ErrorHandlerConfig added in v0.0.2

type ErrorHandlerConfig struct {
	// Include stack traces in non-production environments
	IncludeStack bool
	// Custom error mapping functions
	ErrorMappers []ErrorMapper
	// Logger interface for error logging
	Logger Logger
	// Environment (development, production, etc.)
	Environment string

	GetRequestID func(c Context) string

	GetStackTrace func() []string
}

ErrorHandlerConfig allows customization of error handling behavior

func DefaultErrorHandlerConfig added in v0.0.2

func DefaultErrorHandlerConfig() ErrorHandlerConfig

DefaultErrorHandlerConfig provides sensible defaults

type ErrorHandlerOption added in v0.0.2

type ErrorHandlerOption func(*ErrorHandlerConfig)

ErrorHandlerOption defines a function that can modify ErrorHandlerConfig

func WithEnvironment added in v0.0.2

func WithEnvironment(env string) ErrorHandlerOption

WithEnvironment sets the environment for error handling

func WithErrorMapper added in v0.0.2

func WithErrorMapper(mapper ErrorMapper) ErrorHandlerOption

WithErrorMapper adds additional error mappers

func WithGetStackTrace added in v0.0.2

func WithGetStackTrace(stacker func() []string) ErrorHandlerOption

WithGetStackTrace adds additional error mappers

func WithLogger added in v0.0.2

func WithLogger(logger Logger) ErrorHandlerOption

WithLogger sets the logger for error handling

func WithStackTrace added in v0.0.2

func WithStackTrace(include bool) ErrorHandlerOption

WithStackTrace enables or disables stack traces

type ErrorMapper added in v0.0.2

type ErrorMapper func(error) *RouterError

ErrorMapper is a function that can map specific error types to RouterError

type ErrorResponse added in v0.0.2

type ErrorResponse struct {
	Error struct {
		Type       string            `json:"type"`
		Message    string            `json:"message"`
		Code       int               `json:"code"`
		RequestID  string            `json:"request_id,omitempty"`
		Stack      []string          `json:"stack,omitempty"`
		Metadata   map[string]any    `json:"metadata,omitempty"`
		Validation []ValidationError `json:"validation,omitempty"`
	} `json:"error"`
}

ErrorResponse represents the structure of error responses

func PrepareErrorResponse added in v0.0.2

func PrepareErrorResponse(err *RouterError, config ErrorHandlerConfig) ErrorResponse

type ErrorType added in v0.0.2

type ErrorType string

Error Types

const (
	ErrorTypeValidation       ErrorType = "VALIDATION_ERROR"
	ErrorTypeMiddleware       ErrorType = "MIDDLEWARE_ERROR"
	ErrorTypeRouting          ErrorType = "ROUTING_ERROR"
	ErrorTypeHandler          ErrorType = "HANDLER_ERROR"
	ErrorTypeInternal         ErrorType = "INTERNAL_ERROR"
	ErrorTypeUnauthorized     ErrorType = "UNAUTHORIZED"
	ErrorTypeForbidden        ErrorType = "FORBIDDEN"
	ErrorTypeNotFound         ErrorType = "NOT_FOUND"
	ErrorTypeBadRequest       ErrorType = "BAD_REQUEST"
	ErrorTypeConflict         ErrorType = "CONFLICT"
	ErrorTypeTooManyRequests  ErrorType = "TOO_MANY_REQUESTS"
	ErrorTypeMethodNotAllowed ErrorType = "METHOD_NOT_ALLOWED"
)

type FiberAdapter

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

func (*FiberAdapter) Init added in v0.1.0

func (a *FiberAdapter) Init()

func (*FiberAdapter) Router

func (a *FiberAdapter) Router() Router[*fiber.App]

func (*FiberAdapter) Serve

func (a *FiberAdapter) Serve(address string) error

func (*FiberAdapter) Shutdown

func (a *FiberAdapter) Shutdown(ctx context.Context) error

func (*FiberAdapter) WrapHandler

func (a *FiberAdapter) WrapHandler(h HandlerFunc) any

func (*FiberAdapter) WrappedRouter

func (a *FiberAdapter) WrappedRouter() *fiber.App

type FiberRouter

type FiberRouter struct {
	BaseRouter
	// contains filtered or unexported fields
}

func (*FiberRouter) Delete

func (r *FiberRouter) Delete(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Get

func (r *FiberRouter) Get(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) GetPrefix added in v0.0.3

func (r *FiberRouter) GetPrefix() string

func (*FiberRouter) Group

func (r *FiberRouter) Group(prefix string) Router[*fiber.App]

func (*FiberRouter) Handle

func (r *FiberRouter) Handle(method HTTPMethod, pathStr string, handler HandlerFunc, m ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Head added in v0.1.0

func (r *FiberRouter) Head(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Patch

func (r *FiberRouter) Patch(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Post

func (r *FiberRouter) Post(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) PrintRoutes added in v0.0.2

func (r *FiberRouter) PrintRoutes()

func (*FiberRouter) Put

func (r *FiberRouter) Put(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*FiberRouter) Static added in v0.1.0

func (r *FiberRouter) Static(prefix, root string, config ...Static) Router[*fiber.App]

func (*FiberRouter) Use

func (r *FiberRouter) Use(m ...MiddlewareFunc) Router[*fiber.App]

func (*FiberRouter) WithGroup added in v0.1.0

func (r *FiberRouter) WithGroup(path string, cb func(r Router[*fiber.App])) Router[*fiber.App]

type HTTPMethod

type HTTPMethod string

HTTPMethod represents HTTP request methods

const (
	GET    HTTPMethod = "GET"
	POST   HTTPMethod = "POST"
	PUT    HTTPMethod = "PUT"
	DELETE HTTPMethod = "DELETE"
	PATCH  HTTPMethod = "PATCH"
	HEAD   HTTPMethod = "HEAD"
)

type HTTPRouter

type HTTPRouter struct {
	BaseRouter
	// contains filtered or unexported fields
}

HTTPRouter implements Router for httprouter

func (*HTTPRouter) Delete

func (r *HTTPRouter) Delete(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Get

func (r *HTTPRouter) Get(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) GetPrefix added in v0.0.3

func (r *HTTPRouter) GetPrefix() string

func (*HTTPRouter) Group

func (r *HTTPRouter) Group(prefix string) Router[*httprouter.Router]

func (*HTTPRouter) Handle

func (r *HTTPRouter) Handle(method HTTPMethod, pathStr string, handler HandlerFunc, m ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Head added in v0.1.0

func (r *HTTPRouter) Head(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Patch

func (r *HTTPRouter) Patch(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Post

func (r *HTTPRouter) Post(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) PrintRoutes added in v0.0.2

func (r *HTTPRouter) PrintRoutes()

func (*HTTPRouter) Put

func (r *HTTPRouter) Put(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

func (*HTTPRouter) Static added in v0.1.0

func (r *HTTPRouter) Static(prefix, root string, config ...Static) Router[*httprouter.Router]

func (*HTTPRouter) Use

func (*HTTPRouter) WithGroup added in v0.1.0

func (r *HTTPRouter) WithGroup(path string, cb func(r Router[*httprouter.Router])) Router[*httprouter.Router]

type HTTPServer

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

func (*HTTPServer) Init added in v0.1.0

func (a *HTTPServer) Init()

func (*HTTPServer) Router

func (a *HTTPServer) Router() Router[*httprouter.Router]

func (*HTTPServer) Serve

func (a *HTTPServer) Serve(address string) error

func (*HTTPServer) Shutdown

func (a *HTTPServer) Shutdown(ctx context.Context) error

func (*HTTPServer) WrapHandler

func (a *HTTPServer) WrapHandler(h HandlerFunc) any

func (*HTTPServer) WrappedRouter

func (a *HTTPServer) WrappedRouter() *httprouter.Router

type HandlerFunc

type HandlerFunc func(Context) error

func WrapHandler added in v0.0.2

func WrapHandler(handler func(Context) error) HandlerFunc

WrapHandler function to wrap handlers that return error

func (HandlerFunc) AsMiddlware added in v0.0.2

func (h HandlerFunc) AsMiddlware() MiddlewareFunc

type Logger added in v0.0.2

type Logger interface {
	Debug(format string, args ...any)
	Info(format string, args ...any)
	Error(format string, args ...any)
}

type MetadataAggregator added in v0.0.3

type MetadataAggregator struct {

	////
	Paths      map[string]any
	Schemas    map[string]any
	Tags       []any
	Components map[string]any
	// contains filtered or unexported fields
}

MetadataAggregator collects and merges metadata from multiple providers

func NewMetadataAggregator added in v0.0.3

func NewMetadataAggregator() *MetadataAggregator

NewMetadataAggregator creates a new aggregator

func (*MetadataAggregator) AddProvider added in v0.0.3

func (ma *MetadataAggregator) AddProvider(provider MetadataProvider)

AddProvider adds a metadata provider to the aggregator

func (*MetadataAggregator) AddProviders added in v0.0.3

func (ma *MetadataAggregator) AddProviders(providers ...MetadataProvider)

AddProviders adds multiple metadata providers to the aggregator

func (*MetadataAggregator) Compile added in v0.0.3

func (ma *MetadataAggregator) Compile()

GenerateOpenAPI generates a complete OpenAPI specification from all providers

func (*MetadataAggregator) GenerateOpenAPI added in v0.0.3

func (ma *MetadataAggregator) GenerateOpenAPI() map[string]any

func (*MetadataAggregator) SetTags added in v0.0.3

func (ma *MetadataAggregator) SetTags(tags []string)

SetTags sets global tags that will be added to all operations

type MetadataProvider added in v0.0.3

type MetadataProvider interface {
	GetMetadata() ResourceMetadata
}

MetadataProvider interface for components that can provide API metadata

type MiddlewareFunc added in v0.0.2

type MiddlewareFunc func(HandlerFunc) HandlerFunc

func MiddlewareFromFiber added in v0.0.3

func MiddlewareFromFiber(userFiberMw func(*fiber.Ctx) error) MiddlewareFunc

MiddlewareFromFiber adapts a user-provided Fiber middleware to your router's chain, preserving c.Next() semantics by spinning up a sub-Fiber app for each request.

func MiddlewareFromHTTP added in v0.0.2

func MiddlewareFromHTTP(mw func(next http.Handler) http.Handler) MiddlewareFunc

MiddlewareFromHTTP that transforms a standard Go HTTP middleware which takes and returns http.Handler, into a MiddlewareFunc suitable for use with our router. This function essentially adapts the http.Handler pattern to the HandlerFunc (Context) error interface

func ToMiddleware added in v0.0.2

func ToMiddleware(h HandlerFunc) MiddlewareFunc

ToMiddleware function to wrap handlers and run them as a middleware

func WithErrorHandlerMiddleware added in v0.0.2

func WithErrorHandlerMiddleware(opts ...ErrorHandlerOption) MiddlewareFunc

WithErrorHandlerMiddleware creates a middleware that handles errors for all routes in a group

type NamedHandler added in v0.0.2

type NamedHandler struct {
	Name    string
	Handler HandlerFunc
}

NamedHandler is a handler with a name for debugging/printing

type OpenAPIFieldContact added in v0.0.2

type OpenAPIFieldContact struct {
	Email string
	Name  string
	URL   string
}

type OpenAPIInfo added in v0.1.0

type OpenAPIInfo struct {
	Title          string
	Version        string
	Description    string
	TermsOfService string
	Contact        OpenAPIFieldContact
	License        OpenAPIInfoLicense
}

type OpenAPIInfoLicense added in v0.1.0

type OpenAPIInfoLicense struct {
	Name string
	Url  string
}

type OpenAPIOption added in v0.0.2

type OpenAPIOption func(*openAPIConfig)

func WithDocsPath added in v0.0.2

func WithDocsPath(path string) OpenAPIOption

func WithOpenAPIPath added in v0.0.2

func WithOpenAPIPath(path string) OpenAPIOption

func WithTitle added in v0.0.2

func WithTitle(title string) OpenAPIOption

type OpenAPIRenderer added in v0.0.2

type OpenAPIRenderer struct {
	Info *OpenAPIInfo

	Servers  []OpenAPIServer
	Security []OpenAPISecuritySchemas
	// TODO: Remove
	Title          string
	Version        string
	Description    string
	TermsOfService string
	Contact        *OpenAPIFieldContact
	License        *OpenAPIInfoLicense

	Routes     []RouteDefinition
	Paths      map[string]any
	Tags       []any
	Components map[string]any
	// contains filtered or unexported fields
}

func NewOpenAPIRenderer added in v0.1.0

func NewOpenAPIRenderer() *OpenAPIRenderer

func (*OpenAPIRenderer) AppenRouteInfo added in v0.0.3

func (o *OpenAPIRenderer) AppenRouteInfo(routes []RouteDefinition) *OpenAPIRenderer

AppenRouteInfo updates the renderer with route information

func (*OpenAPIRenderer) AppendServer added in v0.1.0

func (o *OpenAPIRenderer) AppendServer(url, description string) *OpenAPIRenderer

func (*OpenAPIRenderer) GenerateOpenAPI added in v0.0.2

func (o *OpenAPIRenderer) GenerateOpenAPI() map[string]any

func (*OpenAPIRenderer) WithMetadataProviders added in v0.0.3

func (o *OpenAPIRenderer) WithMetadataProviders(providers ...OpenApiMetaGenerator) *OpenAPIRenderer

type OpenAPISecurity added in v0.1.0

type OpenAPISecurity struct {
	Name         string
	Requirements []SecurityRequirement
}

type OpenAPISecuritySchema added in v0.1.0

type OpenAPISecuritySchema struct {
	Name        string
	Type        string
	In          string
	Description string
}

type OpenAPISecuritySchemas added in v0.1.0

type OpenAPISecuritySchemas struct {
	Name    string
	Schemas []OpenAPISecuritySchema
}

type OpenAPIServer added in v0.1.0

type OpenAPIServer struct {
	Url         string
	Description string
}

type OpenApiMetaGenerator added in v0.0.3

type OpenApiMetaGenerator interface {
	GenerateOpenAPI() map[string]any
}

type Parameter added in v0.0.2

type Parameter struct {
	Name        string         `json:"name"`
	In          string         `json:"in"` // query, path, header, cookie
	Required    bool           `json:"required"`
	Description string         `json:"description,omitempty"`
	Schema      map[string]any `json:"schema,omitempty"`
	Example     any            `json:"example,omitempty"`
}

Parameter unifies the parameter definitions

type PrefixedRouter added in v0.0.3

type PrefixedRouter interface {
	GetPrefix() string
}

TODO: Maybe incorporate into Router[T]

type PropertyInfo added in v0.0.3

type PropertyInfo struct {
	Type        string                  `json:"type"`
	Format      string                  `json:"format,omitempty"`
	Description string                  `json:"description,omitempty"`
	Required    bool                    `json:"required"`
	Nullable    bool                    `json:"nullable"`
	ReadOnly    bool                    `json:"read_only"`
	WriteOnly   bool                    `json:"write_only"`
	Example     any                     `json:"example,omitempty"`
	Properties  map[string]PropertyInfo `json:"properties,omitempty"` // For nested objects
	Items       *PropertyInfo           `json:"items,omitempty"`      // For arrays
}

type RequestBody added in v0.0.2

type RequestBody struct {
	Description string         `json:"description,omitempty"`
	Required    bool           `json:"required"`
	Content     map[string]any `json:"content,omitempty"`
}

RequestBody unifies the request body definitions

type RequestContext added in v0.0.2

type RequestContext interface {
	Method() string
	Path() string

	Param(name string, defaultValue ...string) string
	ParamsInt(key string, defaultValue int) int

	Query(name string, defaultValue string) string
	QueryInt(name string, defaultValue int) int
	Queries() map[string]string

	Body() []byte

	Locals(key any, value ...any) any
	Render(name string, bind any, layouts ...string) error

	Cookie(cookie *Cookie)
	Cookies(key string, defaultValue ...string) string
	CookieParser(out any) error
	Redirect(location string, status ...int) error
	RedirectToRoute(routeName string, params ViewContext, status ...int) error
	RedirectBack(fallback string, status ...int) error

	Header(string) string
	Referer() string
	OriginalURL() string
}

type ResourceMetadata added in v0.0.3

type ResourceMetadata struct {
	// Resource identifiers
	Name        string   `json:"name"`
	PluralName  string   `json:"plural_name"`
	Description string   `json:"description"`
	Tags        []string `json:"tags"`

	// Routes metadata
	Routes []RouteDefinition `json:"routes"`

	// Schema information
	Schema SchemaMetadata `json:"schema"`
}

ResourceMetadata represents collected metadata about an API resource

type Response added in v0.0.2

type Response struct {
	Code        int            `json:"code"`
	Description string         `json:"description"`
	Headers     map[string]any `json:"headers,omitempty"`
	Content     map[string]any `json:"content,omitempty"`
}

Response unifies the response definitions

type ResponseWriter added in v0.0.2

type ResponseWriter interface {
	Status(code int) Context
	Send(body []byte) error
	SendString(body string) error
	JSON(code int, v any) error
	// NoContent for status codes that shouldn't have response bodies (204, 205, 304).
	NoContent(code int) error
	SetHeader(string, string) Context
}

type Route added in v0.0.2

type Route[T any] struct {
	// contains filtered or unexported fields
}

func (*Route[T]) Build added in v0.0.2

func (r *Route[T]) Build() error

func (*Route[T]) DELETE added in v0.0.2

func (r *Route[T]) DELETE() *Route[T]

func (*Route[T]) Description added in v0.0.2

func (r *Route[T]) Description(description string) *Route[T]

func (*Route[T]) GET added in v0.0.2

func (r *Route[T]) GET() *Route[T]

func (*Route[T]) Handler added in v0.0.2

func (r *Route[T]) Handler(handler HandlerFunc) *Route[T]

func (*Route[T]) Method added in v0.0.2

func (r *Route[T]) Method(method HTTPMethod) *Route[T]

func (*Route[T]) Middleware added in v0.0.2

func (r *Route[T]) Middleware(middleware ...MiddlewareFunc) *Route[T]

func (*Route[T]) Name added in v0.0.2

func (r *Route[T]) Name(name string) *Route[T]

func (*Route[T]) PATCH added in v0.0.2

func (r *Route[T]) PATCH() *Route[T]

func (*Route[T]) POST added in v0.0.2

func (r *Route[T]) POST() *Route[T]

func (*Route[T]) PUT added in v0.0.2

func (r *Route[T]) PUT() *Route[T]

func (*Route[T]) Parameter added in v0.0.2

func (r *Route[T]) Parameter(name, in string, required bool, schema map[string]any) *Route[T]

func (*Route[T]) Path added in v0.0.2

func (r *Route[T]) Path(path string) *Route[T]

func (*Route[T]) RequestBody added in v0.0.2

func (r *Route[T]) RequestBody(desc string, required bool, content map[string]any) *Route[T]

func (*Route[T]) Response added in v0.0.2

func (r *Route[T]) Response(code int, desc string, content map[string]any) *Route[T]

func (*Route[T]) Responses added in v0.0.2

func (r *Route[T]) Responses(responses []Response) *Route[T]

func (*Route[T]) Summary added in v0.0.2

func (r *Route[T]) Summary(summary string) *Route[T]

func (*Route[T]) Tags added in v0.0.2

func (r *Route[T]) Tags(tags ...string) *Route[T]

type RouteBuilder added in v0.0.2

type RouteBuilder[T any] struct {
	// contains filtered or unexported fields
}

func NewRouteBuilder added in v0.0.2

func NewRouteBuilder[T any](router Router[T]) *RouteBuilder[T]

func (*RouteBuilder[T]) BuildAll added in v0.0.2

func (b *RouteBuilder[T]) BuildAll() error

func (*RouteBuilder[T]) GetMetadata added in v0.0.3

func (b *RouteBuilder[T]) GetMetadata() []RouteDefinition

func (*RouteBuilder[T]) Group added in v0.0.2

func (b *RouteBuilder[T]) Group(prefix string) *RouteBuilder[T]

Group creates a new RouteBuilder with a prefix path

func (*RouteBuilder[T]) NewRoute added in v0.0.2

func (b *RouteBuilder[T]) NewRoute() *Route[T]

NewRoute starts the configuration of a new route

type RouteDefinition added in v0.0.2

type RouteDefinition struct {
	// Core routing
	Method   HTTPMethod     `json:"method"`
	Path     string         `json:"path"`
	Name     string         `json:"name"`
	Handlers []NamedHandler `json:"-"` // Runtime only, not exported to JSON

	// metadata e.g. OpenAPI
	Summary     string       `json:"summary,omitempty"`
	Description string       `json:"description,omitempty"`
	Tags        []string     `json:"tags,omitempty"`
	Parameters  []Parameter  `json:"parameters,omitempty"`
	RequestBody *RequestBody `json:"request_body,omitempty"`
	Responses   []Response   `json:"responses,omitempty"`
	Security    []string     `json:"security,omitempty"`
	// contains filtered or unexported fields
}

RouteDefinition represents all metadata about a route, combining both runtime routing information and metadata

func NewRouteDefinition added in v0.0.3

func NewRouteDefinition() *RouteDefinition

func (*RouteDefinition) AddParameter added in v0.0.2

func (r *RouteDefinition) AddParameter(name, in string, required bool, schema map[string]any) RouteInfo

func (*RouteDefinition) AddResponse added in v0.0.2

func (r *RouteDefinition) AddResponse(code int, desc string, content map[string]any) RouteInfo

func (*RouteDefinition) AddTags added in v0.0.3

func (r *RouteDefinition) AddTags(t ...string) RouteInfo

func (*RouteDefinition) SetDescription added in v0.0.3

func (r *RouteDefinition) SetDescription(d string) RouteInfo

func (*RouteDefinition) SetName added in v0.0.3

func (r *RouteDefinition) SetName(n string) RouteInfo

func (*RouteDefinition) SetRequestBody added in v0.0.2

func (r *RouteDefinition) SetRequestBody(desc string, required bool, content map[string]any) RouteInfo

func (*RouteDefinition) SetSummary added in v0.0.3

func (r *RouteDefinition) SetSummary(s string) RouteInfo

type RouteInfo

type RouteInfo interface {
	SetName(string) RouteInfo
	SetDescription(string) RouteInfo
	SetSummary(s string) RouteInfo
	AddTags(...string) RouteInfo
	AddParameter(name, in string, required bool, schema map[string]any) RouteInfo
	SetRequestBody(desc string, required bool, content map[string]any) RouteInfo
	AddResponse(code int, desc string, content map[string]any) RouteInfo
}

type Router

type Router[T any] interface {
	Handle(method HTTPMethod, path string, handler HandlerFunc, middlewares ...MiddlewareFunc) RouteInfo
	Group(prefix string) Router[T]
	WithGroup(path string, cb func(r Router[T])) Router[T]
	Use(m ...MiddlewareFunc) Router[T]
	Get(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Post(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Put(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Delete(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Patch(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo
	Head(path string, handler HandlerFunc, mw ...MiddlewareFunc) RouteInfo

	Static(prefix, root string, config ...Static) Router[T]

	// TODO: Move to a different interface e.g. MetaRouter
	Routes() []RouteDefinition
	// For debugging: Print a table of routes and their middleware chain
	PrintRoutes()
}

Router represents a generic router interface

type RouterError added in v0.0.2

type RouterError struct {
	Type      ErrorType
	Code      int
	Message   string
	Internal  error
	Metadata  map[string]any
	RequestID string
}

RouterError represents a custom error type for the router package

func MapToRouterError added in v0.0.2

func MapToRouterError(err error, mappers []ErrorMapper) *RouterError

MapToRouterError converts any error to RouterError

func NewBadRequestError added in v0.0.2

func NewBadRequestError(message string) *RouterError

NewBadRequestError for generic bad requests outside of validation context

func NewConflictError added in v0.0.2

func NewConflictError(message string) *RouterError

NewConflictError for requests that could not be completed due to a conflict

func NewForbiddenError added in v0.0.2

func NewForbiddenError(message string) *RouterError

func NewInternalError added in v0.0.2

func NewInternalError(err error, message string) *RouterError

func NewMethodNotAllowedError added in v0.0.2

func NewMethodNotAllowedError(message string) *RouterError

NewMethodNotAllowedError for requests that use an unallowed HTTP method

func NewNotFoundError added in v0.0.2

func NewNotFoundError(message string) *RouterError

func NewTooManyRequestsError added in v0.0.2

func NewTooManyRequestsError(message string) *RouterError

NewTooManyRequestsError for rate-limiting scenarios

func NewUnauthorizedError added in v0.0.2

func NewUnauthorizedError(message string) *RouterError

func NewValidationError added in v0.0.2

func NewValidationError(message string, validationErrs []ValidationError) *RouterError

NewValidationError

func (*RouterError) Error added in v0.0.2

func (e *RouterError) Error() string

func (*RouterError) Unwrap added in v0.0.2

func (e *RouterError) Unwrap() error

func (*RouterError) WithMetadata added in v0.0.2

func (e *RouterError) WithMetadata(meta map[string]any) *RouterError

type SchemaMetadata added in v0.0.3

type SchemaMetadata struct {
	Properties  map[string]PropertyInfo `json:"properties"`
	Required    []string                `json:"required"`
	Description string                  `json:"description"`
}

func ExtractSchemaFromType added in v0.0.3

func ExtractSchemaFromType(t reflect.Type) SchemaMetadata

ExtractSchemaFromType generates SchemaMetadata from a Go type using reflection

type SecurityRequirement added in v0.1.0

type SecurityRequirement = string

type Serializer added in v0.1.0

type Serializer interface {
	Serialize() ([]byte, error)
}

type Server

type Server[T any] interface {
	Init()
	Router() Router[T]
	WrapHandler(HandlerFunc) any
	WrappedRouter() T
	Serve(address string) error
	Shutdown(ctx context.Context) error
}

Server represents a generic server interface

func NewFiberAdapter

func NewFiberAdapter(opts ...func(*fiber.App) *fiber.App) Server[*fiber.App]

TODO: We should make this asynchronous so that we can gather options in our app before we call fiber.New (since at that point it calls init and we are done)

func NewHTTPServer

func NewHTTPServer(opts ...func(*httprouter.Router) *httprouter.Router) Server[*httprouter.Router]

type Static added in v0.1.0

type Static struct {
	//TODO: make an array of fs.FS
	FS             fs.FS               // Optional filesystem implementation
	Root           string              // Root directory
	Browse         bool                // Enable directory browsing
	Index          string              // Index file (default: index.html)
	MaxAge         int                 // Max-Age for cache control header
	Download       bool                // Force download
	Compress       bool                // Enable compression
	ModifyResponse func(Context) error // Hook to modify response
}

Static configuration options

type ValidationError added in v0.0.2

type ValidationError struct {
	Field   string `json:"field"`
	Message string `json:"message"`
}

ValidationError represents a validation error for a specific field

func (*ValidationError) Error added in v0.0.2

func (v *ValidationError) Error() string

type ViewConfigProvider added in v0.1.0

type ViewConfigProvider interface {
	ViewFactoryConfigProvider

	GetCSSPath() string
	GetJSPath() string
	GetRemovePathPrefix() string
	GetReload() bool
	GetDebug() bool
	GetAssetsFS() fs.FS
	GetTemplateFunctions() map[string]any
}

type ViewContext added in v0.1.0

type ViewContext map[string]any

ViewContext provide template values

func (ViewContext) Update added in v0.1.0

func (c ViewContext) Update(other ViewContext) ViewContext

Update updates this context with the key/value-pairs from another context.

type ViewFactory added in v0.1.0

type ViewFactory func(ViewFactoryConfigProvider) Views

type ViewFactoryConfigProvider added in v0.1.0

type ViewFactoryConfigProvider interface {
	GetEmbed() bool
	GetDirFS() string
	GetDirOS() string
	GetExt() string
	GetTemplatesFS() fs.FS
}

type Views added in v0.1.0

type Views interface {
	Load() error
	Render(io.Writer, string, any, ...string) error
}

Views is the interface that wraps the Render function.

func DefaultViewEngine added in v0.1.0

func DefaultViewEngine(opts ViewFactoryConfigProvider) Views

func InitializeViewEngine added in v0.1.0

func InitializeViewEngine(opts ViewConfigProvider) Views

InitializeViewEngine will initialize a view engine with default values

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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