httpbara

package module
v1.0.14 Latest Latest
Warning

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

Go to latest
Published: Jul 31, 2025 License: MIT Imports: 14 Imported by: 5

Documentation

Index

Constants

View Source
const (
	// MiddlewareTag is a struct tag key used to specify a single middleware name.
	MiddlewareTag = "middleware"

	// MiddlewaresTag is a struct tag key used to specify a comma-separated list of middleware names.
	MiddlewaresTag = "middlewares"

	// GroupTag is a struct tag key used to specify the group path prefix for routes.
	GroupTag = "group"

	// RouteTag is a struct tag key used to define the route's HTTP method and path.
	RouteTag = "route"
)

Variables

View Source
var (
	// ErrTerminating is returned when attempting to start a new task after
	// the shutdown process has already been initiated. Once the tracker
	// begins terminating, no new tasks can be registered.
	ErrTerminating = errors.New("received terminating signal")

	// ErrTaskTrackerNotFound is returned when the specified task tracker cannot be located or does not exist.
	ErrTaskTrackerNotFound = errors.New("task tracker not found")
)
View Source
var (
	ErrTaskTrackerNotSet = errors.New("task tracker is not set")
	ErrLoggerNotSet      = errors.New("logger is not set")

	ErrShutdown = casual.NewHTTPErrorFromMessage(503, "server is shutting down")
)

Functions

func AddLogFieldToAccessLog

func AddLogFieldToAccessLog(ctx *gin.Context, value ...interface{})

Types

type Engine

type Engine interface {
	Run(addr string) error
	// contains filtered or unexported methods
}

Engine defines the interface for an HTTP engine capable of registering routes, groups, and middleware and running the server. Implementations should integrate with a Gin engine.

Methods: - flatHandlers([]*Handler): Process a collection of Handler objects to flatten their routes, groups, and middleware. - applyHandlers(): Apply all collected routes, groups, and middleware to the underlying Gin engine. - Run(addr string) chan error: Run the HTTP server at the specified address and return a channel for errors.

func New

func New(handlers []*Handler, opts ...ParamsCb) (Engine, error)

New creates a new Engine (core implementation) given a list of Handler objects and optional parameters. Handlers usually come from the logic of `NewHandler` (not shown here), which reflectively extracts routes, groups, and middleware from a user-defined struct.

Parameters: - handlers: A slice of Handler objects containing routes, groups, and middleware definitions. - opts: A list of options (param functions) that configure the engine (e.g., setting a custom Gin instance or logger).

Returns: - Engine: a configured engine ready to register routes and run. - error: If any configuration step fails, an error is returned.

Example usage: ```go engine, err := New([]*Handler{handler1, handler2}, WithCustomLogger(myLogger))

if err != nil {
    log.Fatal(err)
}

err := engine.Run(":8080") // waiting for error ```

type Group

type Group struct {
	Path string
	// contains filtered or unexported fields
}

Group defines a group of routes that share a common path prefix and possibly a set of middlewares.

Fields: - `name`: The group's name, derived from the field name (e.g., "v3" from "V3"). - `Path`: The prefix path for all routes in this group (e.g., "/api/v3"). - `Middlewares`: A list of middleware names applied to all routes in the group.

**Example:**

```go

type IV3Group struct {
    V3 Group `group:"/api/v3"`
}

type V3GroupImpl struct {
    IV3Group
}

```

All routes referencing `group:"v3"` will be placed under "/api/v3".

type Handler

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

Handler processes a given handler struct to extract and configure routes, groups, and middlewares. It uses reflection to parse struct tags and associates them with the actual Gin handler functions.

The workflow is as follows: 1. Recursively scan the provided struct (including embedded and nested structs) for fields of type `Route`, `Group`, and `Middleware`. 2. Extract corresponding tags (e.g. `route:"POST /checkout/apply"`) to determine routes, their HTTP methods, paths, and middleware associations. 3. Match field names with struct methods (signature `func(*gin.Context)`) to create fully configured routes and middleware. 4. Store all parsed routes, groups, and middleware for later registration in a Gin router.

**Example:**

Consider a scenario in an online store application. We might have a versioned API group (`/api/v3`) and routes for products, cart, and checkout processes.

For example, define a group for version 3 of our API:

```go

type IV3Group struct {
    V3 Group `group:"/api/v3"`
}

type V3GroupImpl struct {
    IV3Group
}

```

Now, inside this versioned group, we could define product routes:

```go

type IProductRoutes struct {
    ListProducts Route `route:"GET /products" middlewares:"auth,logging" group:"v3"`
    GetProduct   Route `route:"GET /products/:id" group:"v3"`
}

type ProductRoutesImpl struct {
    IProductRoutes
}

func (p *ProductRoutesImpl) ListProducts(ctx *gin.Context) {
    // Handler logic for listing products
    // e.g., ctx.JSON(http.StatusOK, productList)
}

func (p *ProductRoutesImpl) GetProduct(ctx *gin.Context) {
    // Handler logic for getting a single product by ID
    // e.g., product := findProductByID(ctx.Param("id"))
    // ctx.JSON(http.StatusOK, product)
}

```

We can also define middleware and checkout routes that use these middlewares:

```go

type ICheckoutRouter struct {
    ApplyCart Route `route:"POST /checkout/apply" middlewares:"log,cors,analytics" group:"v3"`

    LogMiddleware       Middleware `middleware:"log"`
    CorsMiddleware      Middleware `middleware:"cors"`
    AnalyticsMiddleware Middleware `middleware:"analytics"`
}

type CheckoutRouterImpl struct {
    ICheckoutRouter
}

func (c *CheckoutRouterImpl) ApplyCart(ctx *gin.Context) {
    // Handler logic for applying cart items to the checkout process
    // e.g., ctx.JSON(http.StatusOK, checkoutResponse)
}

// Middleware example methods:

func (c *CheckoutRouterImpl) LogMiddleware(ctx *gin.Context) {
    // Logging middleware logic
    ctx.Next()
}

func (c *CheckoutRouterImpl) CorsMiddleware(ctx *gin.Context) {
    // CORS middleware logic (set headers, etc.)
    ctx.Next()
}

func (c *CheckoutRouterImpl) AnalyticsMiddleware(ctx *gin.Context) {
    // Analytics middleware logic (track requests)
    ctx.Next()
}

```

By creating a `Handler` with these structures, you can automatically discover and set up all routes, groups, and middleware:

```go handler := NewHandler(&CheckoutRouterImpl{}) // handler now includes all defined routes and associated middleware within the V3 group. ```

func AsHandler

func AsHandler(handlerStruct interface{}) (*Handler, error)

AsHandler creates a new Handler by analyzing the provided `handlerStruct`. It recursively extracts all methods and fields, builds routes, groups, and middleware, and returns a fully initialized Handler instance.

**Example:** Given `CheckoutRouterImpl` and `ProductRoutesImpl` as in the examples above, you could do:

```go handler := AsHandler(&ProductRoutesImpl{}) // The handler now holds routes like GET /api/v3/products (with auth, logging middleware), // and GET /api/v3/products/:id, ready to be registered in your Gin engine. ```

func NewAccessLogMiddleware

func NewAccessLogMiddleware(log Logger) (*Handler, error)

func NewTaskTrackerMiddleware

func NewTaskTrackerMiddleware(log Logger, tt TaskTracker) (*Handler, error)

type Logger

type Logger interface {
	Info(message string, args ...any)
	Debug(message string, args ...any)
	Error(message string, args ...any)
	Panic(message string, args ...any)
	Warn(message string, args ...any)
}

func NewFmtLogger

func NewFmtLogger() Logger

type Middleware

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

Middleware defines a middleware associated with a handler function and possibly other nested middlewares.

Fields: - `middleware`: The primary middleware name (from `middleware:"name"` tag or derived from the field name). - `middlewares`: A list of additional middleware names that this middleware applies internally. - `handler`: The Gin handler function for the middleware.

**Example:** ```go

type ICheckoutRouter struct {
    ApplyCart Route `route:"POST /checkout/apply" middlewares:"log,cors,analytics" group:"v3"`

    LogMiddleware       Middleware `middleware:"log"`
    CorsMiddleware      Middleware `middleware:"cors"`
    AnalyticsMiddleware Middleware `middleware:"analytics"`
}

```

Here, the `ApplyCart` route will be executed with the "log", "cors", and "analytics" middleware in the defined order.

type ParamsCb

type ParamsCb func(*params) error

func WithGinEngine

func WithGinEngine(r *gin.Engine) ParamsCb

func WithLogger

func WithLogger(log Logger) ParamsCb

func WithRootMiddlewares

func WithRootMiddlewares(middlewares ...*Handler) ParamsCb

func WithShutdownTimeout

func WithShutdownTimeout(timeout time.Duration) ParamsCb

func WithTaskTracker

func WithTaskTracker(tracker ...TaskTracker) ParamsCb

type Route

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

Route defines an HTTP endpoint with a method, path, associated handler, and optional middlewares or group prefix.

Fields: - `method`: The HTTP method (e.g., "GET", "POST"). - `path`: The HTTP path (e.g., "/checkout/apply"). - `handler`: The Gin handler function that processes the request. - `middlewares`: A list of middleware names applied before the handler. - `group`: The name of the group this route belongs to, if any.

**Example:** ```go

type IProductRoutes struct {
    ListProducts Route `route:"GET /products" middlewares:"auth,logging" group:"v3"`
}

``` This defines a GET route at `/api/v3/products` that applies "auth" and "logging" middleware.

type TaskTracker

type TaskTracker interface {
	StartTask() error
	FinishTask()
	TaskCount() int32
	Shutdown(ctx context.Context) error
}

func GetTaskTracker

func GetTaskTracker(ctx *gin.Context) (TaskTracker, error)

GetTaskTracker retrieves the activeTaskTracker instance from the gin.Context. Returns an error if task tracker is not provided

func NewActiveTaskTracker

func NewActiveTaskTracker() TaskTracker

NewActiveTaskTracker creates and returns a new TaskTracker impl. By default, it starts with zero active tasks and a background context that can be canceled when shutdown is initiated.

Example usage:

tracker := NewActiveTaskTracker()

// Start a new task
if err := tracker.StartTask(); err == nil {
	go func() {
		// Do some work...
		defer tracker.FinishTask()
	}()
}

// Once you decide to stop the application:
tracker.Shutdown() // Blocks until all tasks have finished.

Directories

Path Synopsis
examples
otel module
uber-fx module
pkg
httpbarafx module
httpbarazap module

Jump to

Keyboard shortcuts

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