fastecho

package module
v0.13.1 Latest Latest
Warning

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

Go to latest
Published: May 29, 2026 License: Apache-2.0 Imports: 32 Imported by: 0

README

Fastecho

Fastecho is a Go library that provides an easily configurable, ready-to-use echo server. It is a wrapper on top of the echo framework and it adds extra functionalities that are often required when setting up web servers.

Getting started

For specifics, check the detailed features below.

// load env vars
err := envs.SetEnv()
if err != nil {
    log.Fatalf("failed to set environment variables: %s", err)
}

// set up a DB and pass it to handler as you like
// optionally you can provide a gorm config to customize your gorm instance
db, err := fastecho.NewDB(&gorm.Config{
    Logger: newLogger,
})
if err != nil {
    log.Fatalf("failed to connect to the database: %s", err)
}

config := fastecho.Config{
    ExtraEnvs:           envs,
    ValidationRegistrar: validator.RegisterValidations,
    Routes: func(e *echo.Echo, r *router.Router) error {
        return configureRoutes(e, r, db)
    },
    Opts: fastecho.Opts{
        Tracing: fastecho.TracingOpts{
            Skip: !envs["OTEL_ENABLED"].BooleanValue,
        },
        Metrics: fastecho.MetricsOpts{
            Skip: !envs["OTEL_ENABLED"].BooleanValue,
        },
        HealthChecks: fastecho.HealthChecksOpts{
            Skip: false,
            DB:   db,
        },
    },
}

// Starting service...
if err := fastecho.Run(&config); err != nil {
    log.Fatalf("Service stopped! \n %s", err)
}

Features

Logger

We integrated go.uber.org/zap

Request context

Fastecho injects a request-scoped logger, tracer, and request ID into the request's context.Context. Access them via the fctx package:

import "github.com/ingka-group/fastecho/fctx"

func (h *Handler) GetData(ec echo.Context) error {
    ctx := fctx.From(ec)
    log := fctx.Logger(ctx)
    reqID := fctx.RequestID(ctx)

    log.Info("handling request", zap.String("request_id", reqID))
    // ...
}

The logger automatically includes trace_id, span_id, and request_id fields when available.

Routing

The router provides preset endpoints for swagger, monitoring and health checks. Custom endpoints can be injected via the Routes function in the config.

func configureRoutes(e *echo.Echo, r *router.Router, db *gorm.DB) error {
	myHandler := NewHandler(db)

	v1 := e.Group("/v1")
	myGroup := v1.Group("/example")

	router.AddRoute(r, myGroup, "/data", myHandler, http.MethodGet)
	return nil
}
Request validation

Custom validation can be registered using the provided validator. Define a function in which you register custom validations and add it to the config.

func RegisterValidations(validator *router.Validator) error {
	validator.Vdt.RegisterStructValidation(daterange.ValidateBasicDateRange(), daterange.BasicDateRange{})

	return nil
}
Middleware

Custom middleware can be injected via the route configuration function.

func configureRoutes(e *echo.Echo, r *router.Router, db *gorm.DB) error {
	v1 := e.Group("/v1")
	myGroup := v1.Group("/data")

	myGroup.Use(middleware.MyCustomMiddleware())

	return nil
}
Swagger

Swagger is baked into the router wrapper. The title and JSON path can be configured via environment variables:

SWAGGER_UI_TITLE SWAGGER_JSON_PATH

The swagger documentation is configured on the root path suffixed with /swagger/.

Health probe endpoints

The health endpoints are configured on the root path suffixed with /health/live and /health/ready.

Environment variables

Environment variables are read by default from the environment or from a .env file in the root of the directory.

Fastecho defines the following env vars internally:

Variable Default Notes
HOSTNAME localhost Server hostname
PORT 8080 Server port
SWAGGER_UI_TITLE FastEcho Service Title for Swagger UI
SWAGGER_JSON_PATH /swagger/swagger.json Path to swagger.json
LOG_LEVEL dev One of: dev, test, prod

You can define additional env vars via ExtraEnvs in the config. These are merged with the defaults and loaded automatically when Run() or Initialize() is called:

var envs = env.Map{
	"OTEL_ENABLED": {
		DefaultValue: "false",
		IsBoolean:    true,
	},
}

// load them
err := envs.SetEnv()
if err != nil {
    log.Fatalf("failed to set environment variables: %s", err)
}

config := fastecho.Config{
	ExtraEnvs: envs,
	// ...
}
OTEL tracing (optional)

Tracing is enabled when Opts.Tracing.Skip is false (the default). The service name and exporter endpoint are configured via standard OpenTelemetry env vars:

Env Variable Purpose
OTEL_SERVICE_NAME Sets the service name for traces
OTEL_RESOURCE_ATTRIBUTES Additional resource attributes (e.g. deployment.environment=prod)
OTEL_EXPORTER_OTLP_ENDPOINT gRPC endpoint for the OTLP exporter
Layer How Effort
HTTP requests Automatic via middleware Zero config
Database (GORM) gorm.io/plugin/opentelemetry Add plugin yourself
Service functions otel.StartSpan(ctx) 2 lines
Functions without ctx otel.SpanFunc(ctx, name, fn) 3 lines
Outbound HTTP otelhttp.NewTransport(rt) Wrap your client

Per-function tracing:

import "github.com/ingka-group/fastecho/otel"

func (s *Service) Process(ctx context.Context, input Input) error {
    ctx, span := otel.StartSpan(ctx)
    defer span.End()
    // span name auto-discovered: "mypackage.Service.Process"
    return s.repo.Save(ctx, input)
}

Tracing a function without context:

var result T
otel.SpanFunc(ctx, "heavy-algorithm", func() {
    result = computeHeavyAlgorithm(data)
})

For database tracing, add gorm.io/plugin/opentelemetry to your project:

import "gorm.io/plugin/opentelemetry/tracing"

_ = db.Use(tracing.NewPlugin())

Important: Always pass context to GORM queries (db.WithContext(ctx).Find(...)) so DB spans attach to the request trace.

Database (optional)

Fastecho has an optional postgres DB connection baked into it using gorm. We are using goose for migrations rather than gorm Automigrate. The migrations are expected to be under db/migrations in the root of your folder.

Plugins

Plugins are a set of handlers and their bound components (validators, middlewares, etc) which can be reused across multiple services using fastecho.

fastechoConfig.Use(<pluginConfig>)

Access Echo instance

The underlying Echo instance can be accessed by passing the value for EchoFn in the config. This is useful for binding service level middlewares, enabling echo's debug mode or any other Echo features.

config := fastecho.Config{
	ValidationRegistrar: func(*router.Validator) error {
		return nil
	},
	Routes: func(e *echo.Echo, r *router.Router) error {
		return configureRoutes(e, r, db)
	},
	EchoFn: func(e *echo.Echo) error {
		// Use a service level middleware
		e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
			AllowOrigins:     []string{"https://example.com"},
			AllowHeaders:     []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept, echo.HeaderAuthorization},
			MaxAge:           3600,
			AllowCredentials: true,
			ExposeHeaders:    []string{echo.HeaderContentLength},
		}))
		// Enable debug mode in echo
		e.Debug = true
		return nil
	},
	...
}

Miscellaneous

Fastecho is fully compatible with Echoprobe

Contributing

Please read CONTRIBUTING for more details about making a contribution to this open source project and ensure that you follow our CODE_OF_CONDUCT.

Contact

If you have any other issues or questions regarding this project, feel free to contact one of the code owners/maintainers for a more in-depth discussion.

Licence

This open source project is licensed under the "Apache-2.0", read the LICENCE terms for more details.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func BindValidate added in v0.13.0

func BindValidate(ec echo.Context, v any) error

BindValidate binds the request body to v and validates it using the registered validator. Use this at the handler boundary.

func NewDB

func NewDB(cfg *gorm.Config) (*gorm.DB, error)

NewDB creates a new *gorm.DB the configuration of which is through environment variables.

func Run

func Run(cfg *Config) error

Run starts a new instance of fastecho.

Types

type Config

type Config struct {
	ExtraEnvs           env.Map
	ValidationRegistrar func(v *router.Validator) error
	Routes              func(e *echo.Echo, r *router.Router) error
	// ContextProps would be shared across all requests in the service
	ContextProps any
	Opts         Opts
	Plugins      []Plugin
	EchoFn       func(e *echo.Echo) error
}

Config serves as input configuration for fastecho.

func (*Config) Use added in v0.1.0

func (c *Config) Use(p Plugin)

type FastEcho

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

func Initialize

func Initialize(cfg *Config) (*FastEcho, error)

Initialize sets up a new instance of FastEcho and returns a prepared FastEcho type, but does not boot the server.

func (*FastEcho) Handler

func (fe *FastEcho) Handler() http.Handler

Handler returns the Echo handler for the defined FastEcho server.

func (*FastEcho) Shutdown

func (fe *FastEcho) Shutdown(ctx gocontext.Context) error

Shutdown cleanly shuts down the server and any tracing providers.

type HealthChecksOpts

type HealthChecksOpts struct {
	Skip bool     `json:"skip"`
	DB   *gorm.DB `json:"db,omitempty"`
}

HealthChecksOpts define configuration options for health checks.

type MetricsOpts

type MetricsOpts struct {
	Skip bool `json:"skip"`
}

MetricsOpts define configuration options for metrics.

type Opts

type Opts struct {
	Metrics      MetricsOpts      `json:"metrics"`
	Tracing      TracingOpts      `json:"tracing"`
	HealthChecks HealthChecksOpts `json:"health_checks"`
}

Opts define configuration options for fastecho.

type Plugin added in v0.1.0

type Plugin struct {
	ValidationRegistrar func(v *router.Validator) error
	Routes              func(e *echo.Echo, r *router.Router) error
}

type TracingOpts

type TracingOpts struct {
	Skip bool `json:"skip"`
}

TracingOpts define configuration options for tracing.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

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