zrouter

package
v0.18.3 Latest Latest
Warning

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

Go to latest
Published: Apr 19, 2024 License: Apache-2.0 Imports: 16 Imported by: 0

README

ZRouter package

ZRouter is a Golang routing library built on the robust foundation of the chi router.

Table of Contents

Features

  • Intuitive Routing Interface: Define your routes with ease using all major HTTP methods.
  • Middleware Chaining: Introduce layers of middleware to your HTTP requests and responses.
  • Flexible Adapters: Seamlessly integrate with the chi router's context.
  • Enhanced Monitoring: Integrated metrics server and structured logging for in-depth observability.
  • Customizable Settings: Adjust server configurations like timeouts to suit your needs.

Getting Started

Installation

To incorporate ZRouter into your project:

go get github.com/zondax/golem/pkg/zrouter

Usage

Crafting a web service using ZRouter:

import "github.com/zondax/golem/pkg/zrouter"

config := &zrouter.Config{ReadTimeOut: 10 * time.Second, WriteTimeOut: 10 * time.Second}
router := zrouter.New("ServiceName", metricServer, config)

router.Use(middlewareLogic)

groupedRoutes := router.Group("/grouped")
groupedRoutes.GET("/{param}", handlerFunction)

or

import "github.com/zondax/golem/pkg/zrouter"

func main() {
router := zrouter.New("MyService", metricServer, nil)

router.GET("/endpoint", func(ctx zrouter.Context) (domain.ServiceResponse, error) {
// Handler implementation
})

router.Run()
}

Routing

For dynamic URL parts, utilize the chi style, e.g., /entities/{entityID}.

Middleware

Add pre- and post-processing steps to your routes. Chain multiple middlewares for enhanced functionality.

Default Middlewares

ZRouter comes bundled with certain default middlewares for enhanced functionality and ease of use:

  • ErrorHandlerMiddleware: Systematically manages errors by translating them into a consistent response format.
  • RequestID(): Attaches a unique request ID to every request, facilitating request tracking and debugging.
  • RequestMetrics(): Monitors and logs metrics associated with requests, responses, and other interactions for performance insights.

To activate these middlewares, make sure to call:

zr := zrouter.New("AppName", metricsServer, nil)
zr.SetDefaultMiddlewares() //Call this method!
Additional Middlewares

Beyond the default offerings, ZRouter also provides extra middlewares to address specific needs:

  • DefaultCors(): Introduces a predefined set of Cross-Origin Resource Sharing (CORS) rules, facilitating browsers to make requests across origins safely.
  • Cors(options CorsOptions): A flexible CORS middleware that allows you to set specific CORS policies, such as permitted origins, headers, and methods, tailored to your application's demands.
  • RateLimit(maxRPM int): Shields your application from being swamped by imposing a rate limit on the influx of requests. By setting maxRPM, you can decide the maximum number of permissible requests per minute.

Adapters

Use chiContextAdapter for translating the chi router's context to ZRouter's.

Custom Configurations

Specify server behavior with Config. Use default settings or customize as needed.

Default settings:

  • ReadTimeOut: 240000 milliseconds.
  • WriteTimeOut: 240000 milliseconds.
  • Logger: Uses production logger settings by default.

Override these defaults by providing values during initialization.

Example:

   config := &Config{
   ReadTimeOut:  25000 * time.Millisecond,
   WriteTimeOut: 25000 * time.Millisecond,
   Logger:       zapLoggerInstance,
   }
   zr := New("YourAppName", metricsServerInstance, config)

Response Standards

ServiceResponse

When handling responses, ZRouter provides a standardized way to return them using ServiceResponse, which includes status, headers, and body.

Example:

func MyHandler(ctx Context) (domain.ServiceResponse, error) {
    data := map[string]string{"message": "Hello, World!"}
    return domain.NewServiceResponse(http.StatusOK, data), nil
}
Handling Headers

With ServiceResponse, you can easily set custom headers for your responses:

func MyHandler(ctx Context) (domain.ServiceResponse, error) {
  headers := make(http.Header)
  headers.Set("X-Custom-Header", "My Value")
  
  data := map[string]string{"message": "Hello, World!"}
  response := domain.NewServiceResponseWithHeader(http.StatusOK, data, headers)
  return response, nil
}
Error Handling

Whenever you return an error, ZRouter translates it to a structured error response, maintaining consistency across your services.

Example:

func MyHandler(ctx Context) (domain.ServiceResponse, error) {
    return nil, domain.NewAPIErrorResponse(http.StatusNotFound, "not_found", "message")
}

Context in ZRouter

The Context is an essential part of ZRouter, providing a consistent interface to interact with the HTTP request and offering helper methods to streamline handler operations. This abstraction ensures that, as your router's needs evolve, the core interface to access request information remains consistent.

Functions and Usage:
  1. Request:

    Retrieve the raw *http.Request from the context:

    req := ctx.Request()
    
  2. BindJSON:

    Decode a JSON request body directly into a provided object:

    var myData MyStruct
    err := ctx.BindJSON(&myData)
    
  3. Header:

    Set an HTTP header for the response:

    ctx.Header("X-Custom-Header", "Custom Value")
    
  4. Param:

    Get URL parameters (path variables):

    userID := ctx.Param("userID")
    
  5. Query:

    Retrieve a query parameter from the URL:

    sortBy := ctx.Query("sortBy")
    
  6. DefaultQuery:

    Retrieve a query parameter from the URL, but return a default value if it's not present:

    order := ctx.DefaultQuery("order", "asc")
    
Adapting to chi:

Behind the scenes, ZRouter leverages the powerful chi router. The chiContextAdapter translates the chi context to ZRouter's, ensuring that you get the benefits of chi's speed and power with ZRouter's simplified and consistent interface.

Monitoring and Logging

Monitor request metrics and employ structured logging for in-depth insights.

Advanced Topics

  • Route Grouping: Consolidate routes under specific prefixes using Group().
  • NotFound Handling: Specify custom logic for unmatched routes.
  • Route Tracking: Fetch a structured list of all registered routes.
Why ZRouter?
  • Consistent Standard: In a world full of routers, ZRouter gives us a way to keep things standard across our projects.
  • Flexibility: Today we're using chi, but what about tomorrow? With ZRouter, if we ever want to switch, we can do it here and keep everything else unchanged.
  • Speed & Power of Chi: We get all the speed and flexibility of routers like chi but without tying ourselves down to one specific router.
  • Unified Approach: ZRouter sets a clear standard for how we handle metrics, responses, errors, and more. It's about making sure everything works the same way, every time.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func LogTopJWTPathMetrics added in v0.17.0

func LogTopJWTPathMetrics(ctx context.Context, zCache zcache.RemoteCache, updateInterval time.Duration, topN int)

func NotFoundHandler

func NotFoundHandler(_ Context) (domain.ServiceResponse, error)

Types

type Config

type Config struct {
	ReadTimeOut           time.Duration
	WriteTimeOut          time.Duration
	Logger                *logger.Logger
	SystemMetrics         SystemMetrics
	EnableRequestID       bool
	JWTUsageMetricsConfig JWTUsageMetricsConfig
	AppVersion            string
	AppRevision           string
}

type Context

type Context interface {
	Request() *http.Request
	BindJSON(obj interface{}) error
	Header(key, value string)
	Param(key string) string
	Query(key string) string
	DefaultQuery(key, defaultValue string) string
	Context() context.Context
}

type HandlerFunc

type HandlerFunc func(ctx Context) (domain.ServiceResponse, error)

func ToHandlerFunc added in v0.17.3

func ToHandlerFunc(h http.Handler) HandlerFunc

type JWTUsageMetricsConfig added in v0.17.0

type JWTUsageMetricsConfig struct {
	RemoteCache       zcache.RemoteCache
	Enable            bool
	TokenDetailsTTL   time.Duration
	UsageMetricTTL    time.Duration
	UpdateInterval    time.Duration
	TopNRequestMetric int
}

type MockContext

type MockContext struct {
	mock.Mock
}

func (*MockContext) BindJSON

func (m *MockContext) BindJSON(obj interface{}) error

func (*MockContext) Context added in v0.15.4

func (m *MockContext) Context() context.Context

func (*MockContext) DefaultQuery

func (m *MockContext) DefaultQuery(key, defaultValue string) string

func (*MockContext) Header

func (m *MockContext) Header(key, value string)

func (*MockContext) Param

func (m *MockContext) Param(key string) string

func (*MockContext) Query

func (m *MockContext) Query(key string) string

func (*MockContext) Request

func (m *MockContext) Request() *http.Request

type MockZRouter

type MockZRouter struct {
	mock.Mock
}

func (*MockZRouter) DELETE

func (m *MockZRouter) DELETE(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes

func (*MockZRouter) GET

func (m *MockZRouter) GET(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes

func (*MockZRouter) GetHandler added in v0.17.3

func (m *MockZRouter) GetHandler() http.Handler

func (*MockZRouter) GetRegisteredRoutes added in v0.17.3

func (m *MockZRouter) GetRegisteredRoutes() []RegisteredRoute

func (*MockZRouter) Group

func (m *MockZRouter) Group(prefix string) Routes

func (*MockZRouter) Handle added in v0.17.3

func (m *MockZRouter) Handle(pattern string, handler HandlerFunc)

func (*MockZRouter) Mount added in v0.17.3

func (m *MockZRouter) Mount(pattern string, handler HandlerFunc)

func (*MockZRouter) NoRoute added in v0.17.3

func (m *MockZRouter) NoRoute(handler HandlerFunc)

func (*MockZRouter) PATCH

func (m *MockZRouter) PATCH(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes

func (*MockZRouter) POST

func (m *MockZRouter) POST(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes

func (*MockZRouter) PUT

func (m *MockZRouter) PUT(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes

func (*MockZRouter) Route

func (m *MockZRouter) Route(method, path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes

func (*MockZRouter) Run

func (m *MockZRouter) Run(addr ...string) error

func (*MockZRouter) ServeFiles added in v0.17.3

func (m *MockZRouter) ServeFiles(routePattern string, httpHandler http.Handler)

func (*MockZRouter) ServeHTTP added in v0.17.3

func (m *MockZRouter) ServeHTTP(w http.ResponseWriter, req *http.Request)

func (*MockZRouter) SetDefaultMiddlewares added in v0.17.3

func (m *MockZRouter) SetDefaultMiddlewares(loggingOptions zmiddlewares.LoggingMiddlewareOptions)

func (*MockZRouter) Use

func (m *MockZRouter) Use(middlewares ...zmiddlewares.Middleware) Routes

type RegisteredRoute

type RegisteredRoute struct {
	Method string
	Path   string
}

type Routes

type Routes interface {
	NewSubRouter() ZRouter
	GET(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes
	POST(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes
	PUT(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes
	PATCH(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes
	DELETE(path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes
	Handle(pattern string, handler HandlerFunc)
	Route(method, path string, handler HandlerFunc, middlewares ...zmiddlewares.Middleware) Routes
	Mount(pattern string, subRouter Routes)
	Group(prefix string) Routes
	Use(middlewares ...zmiddlewares.Middleware) Routes
	NoRoute(handler HandlerFunc)
	GetRegisteredRoutes() []RegisteredRoute
	SetDefaultMiddlewares(loggingOptions zmiddlewares.LoggingMiddlewareOptions)
	GetHandler() http.Handler
	ServeHTTP(w http.ResponseWriter, req *http.Request)
	ServeFiles(routePattern string, httpHandler http.Handler)
}

type SystemMetrics added in v0.16.2

type SystemMetrics struct {
	Enable         bool
	UpdateInterval time.Duration
}

type ZRouter

type ZRouter interface {
	Routes
	Run(addr ...string) error
}

func New

func New(metricsServer metrics.TaskMetrics, config *Config) ZRouter

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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