requestcore

package module
v2.0.0-...-51e8ac7 Latest Latest
Warning

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

Go to latest
Published: Aug 25, 2026 License: MIT Imports: 10 Imported by: 0

README

requestCore v2

Go Reference Go Version

A generics-first, framework-agnostic HTTP application toolkit for Go. Requires Go 1.27+.

v2 builds on the root requestCore module with fully typed endpoints, resources, sessions, and response helpers — eliminating runtime type assertions and reflection throughout the request lifecycle.


Why v2?

v1 normalizes request parsing across Gin, Fiber, and net/http but uses any for request/response types, requiring runtime type assertions and reflection. v2 leverages Go generics to make the entire handler lifecycle compile-time type-safe:

  • Endpoint[Req, Resp] flows types through parse → initialize → handle → render → finalize
  • Resource[ID cmp.Ordered] constrains resource IDs to comparable types
  • GetTyped[T] / SetTyped[T] eliminate session value type assertions
  • OKTyped[Resp] renders typed responses without any

Features

  • Generic typed endpointshandlers.Endpoint[Req, Resp] with typed lifecycle hooks
  • Generic resourcesresources.Resource[ID cmp.Ordered] with 7 CRUD operations, registered via ResourceBuilder[ID] fluent API
  • TypedResource — advanced 14-type-parameter interface (overkill for simple CRUD; use only when strictest per-operation type guarantees are needed)
  • Typed session accessGetTyped[T] / SetTyped[T] generic accessors
  • Generic response helpersOKTyped[Resp] / OKWithStatusTyped[Resp]
  • Framework-agnostic routing — Gin, Fiber, chi, net/http via adapters
  • Pluggable renderers — JSON, XML, text, CSV
  • Error handler registry — per-status handlers with legacy fallback
  • Background workers — bounded pool with retry, tracing, and mandatory observability
  • Scheduler — periodic background tasks
  • Sessions & flash — cookie store with signed tokens
  • CLIrequestcore code generator for handlers, resources, middleware, projects

Quick Start

package main

import (
    "context"
    "log"
    "log/slog"
    "os/signal"
    "syscall"

    "github.com/hmmftg/requestCore/libRequest"
    "github.com/hmmftg/requestCore/webFramework"

    "github.com/hmmftg/requestCore/v2/app"
    "github.com/hmmftg/requestCore/v2/handlers"
    "github.com/hmmftg/requestCore/v2/renderers"
)

type HealthResp struct {
    Status string `json:"status"`
}

func main() {
    application, err := app.Bootstrap(app.Config{
        Framework: app.FrameworkChi,
        Renderer:  renderers.JSONRenderer{},
    })
    if err != nil {
        log.Fatal(err)
    }
    defer application.Close()

    // Register a typed GET endpoint
    err = handlers.GetEndpoint[struct{}, HealthResp](
        application.Router, nil, application.RespHandler, "/health",
        func(req *struct{}, trx *handlers.HandlerRequest[struct{}, HealthResp]) (HealthResp, error) {
            webFramework.AddLog(trx.W, "health-check", slog.String("status", "healthy"))
            return HealthResp{Status: "healthy"}, nil
        },
    )
    if err != nil {
        log.Fatal(err)
    }

    ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
    defer stop()

    if err := application.StartWithContext(ctx, ":8080"); err != nil {
        log.Fatal(err)
    }
}

Core Concepts

Generic Endpoints

handlers.Endpoint[Req, Resp] is the typed descriptor for a route handler. The Req and Resp type parameters flow through the entire lifecycle without type erasure:

e := handlers.NewEndpoint[MyReq, MyResp]("my-handler", libRequest.JSON, MyHandler).
    WithPath("/users").
    WithInitializer(func(trx *handlers.HandlerRequest[MyReq, MyResp]) error {
        // Runs after parsing, before the handler. Compile-time typed.
        return nil
    }).
    WithFinalizer(func(trx *handlers.HandlerRequest[MyReq, MyResp]) {
        // Always runs, even on panic. Compile-time typed.
    }).
    WithPersistence(persister) // typed persister

handlers.RegisterEndpoint(router, core, respHandler, "POST", "/users", e)

Lifecycle hooks are methods on *Endpoint[Req, Resp], not free functions — this means type mismatches are caught at compile time, not at runtime via reflection.

Resources

resources.Resource[ID cmp.Ordered] defines 7 CRUD operations:

Operation Method Path
List GET /{resource}
Show GET /{resource}/{id}
New GET /{resource}/new
Create POST /{resource}
Edit GET /{resource}/{id}/edit
Update PUT /{resource}/{id}
Destroy DELETE /{resource}/{id}

Recommended path for v2 migration: implement Resource[ID] and register via ResourceBuilder. Each operation returns handlers.EndpointRuntime (satisfied by *handlers.Endpoint[Req, Resp]). Operations returning nil are skipped or registered with a 405 default handler.

type UserResource struct{}

func (r *UserResource) List() handlers.EndpointRuntime {
    return handlers.NewEndpoint[struct{}, UserListResp](
        "list-users", libRequest.NoBinding,
        func(req *struct{}, trx *handlers.HandlerRequest[struct{}, UserListResp]) (UserListResp, error) {
            return UserListResp{Users: []User{}}, nil
        },
    )
}
// ... similarly for Show, New, Create, Edit, Update, Destroy

// Register via ResourceBuilder (recommended)
err := resources.NewResource[string]("/users").
    EnablePatch().
    WithCustom(reloadOp).
    Register(application.Router, core, application.RespHandler, &UserResource{})

Advanced: TypedResource (14 type parameters). For cases requiring the strictest compile-time guarantees on every operation's request/response types simultaneously, implement TypedResource[ID, ListReq, ListResp, ...]. This is overkill for simple CRUD + custom resources — the 14 type parameters add verbosity without practical benefit for most use cases. Any TypedResource automatically satisfies Resource[ID].

Typed Session Access

Session values are stored as any but accessed via generic functions for compile-time type safety:

// Store a typed value
session.SetTyped(sess, "user_id", 42)

// Retrieve with compile-time type checking
userID, err := session.GetTyped[int](sess, "user_id")

The RequestContext.Session field is typed as webFramework.SessionContext (an interface), not any — you can call Get, Set, Delete directly without type-asserting to *session.Session.

Generic Response Helpers
// Typed response (compile-time type safety)
respHandler.OKTyped(req, MyResp{ID: "1"})

// Typed response with custom status
respHandler.OKWithStatusTyped(req, http.StatusCreated, MyResp{ID: "1"})
Framework Adapters

Switch frameworks by changing one config field:

app.Bootstrap(app.Config{Framework: app.FrameworkGin})    // Gin
app.Bootstrap(app.Config{Framework: app.FrameworkFiber})  // Fiber
app.Bootstrap(app.Config{Framework: app.FrameworkChi})    // chi + net/http

All handlers, resources, and middleware work unchanged across frameworks.

Background Workers
err := application.Worker.Submit(context.Background(), workers.Job{
    Name: "send-email",
    Handler: func(ctx *workers.JobContext) error {
        webFramework.AddLog(ctx.WebFramework, webFramework.HandlerLogTag,
            slog.String("recipient", email))
        // ... send email ...
        return nil
    },
    Options: workers.JobOptions{MaxAttempts: 3},
})

For periodic tasks, use application.Scheduler.Schedule(...).

Renderers
app.Bootstrap(app.Config{
    Framework: app.FrameworkChi,
    Renderer:  renderers.JSONRenderer{},  // or XMLRenderer{}, TextRenderer{}, CSVRenderer{}
})

Package Map

Package Description
app Bootstrap, Config, App — application entry point
handlers Endpoint[Req, Resp], HandlerRequest, lifecycle hooks, RegisterEndpoint
resources Resource[ID], TypedResource, ResourceBuilder[ID], Register, CustomOperation
routing Router, RouteGroup, Middleware, Chain — framework-agnostic routing
session Session, Flash, Manager, CookieStore, GetTyped[T], SetTyped[T]
workers InProcessWorker, Scheduler, Job, JobContext
renderers Renderer interface, JSON/XML/text/CSV renderers
response Handler, Registry, OKTyped[Resp], OKWithStatusTyped[Resp]
webFramework RequestContext, RequestParser, SessionContext, FlashContext
libGin Gin adapter
libFiber Fiber adapter
libChi chi adapter
libNetHttp net/http adapter
testingtools Test helpers and mock infrastructure
cmd/requestcore CLI for code generation

CLI

# Build the CLI
go build -o requestcore ./cmd/requestcore/cmd

# Generate a handler
./requestcore generate handler user-profile

# Generate a resource (7 CRUD operations)
./requestcore generate resource user

# Generate middleware
./requestcore generate middleware auth

# Generate a new project
./requestcore generate project my-app

Observability

webFramework.AddLog is mandatory for all external API calls, transaction steps, and critical business events. It flows into the Splunk transaction pipeline. Never replace it with slog.* or log.*.

The handler lifecycle automatically emits <title>-req (success) and <title>-req-failed (failure) log entries.


Examples

  • examples/simple/ — chi-based example with typed endpoints, CRUD resource, workers, and sessions

Migration from v1

See MIGRATION.md for the complete v1-to-v2 migration guide.


License

See LICENSE for license information.

Documentation

Overview

Package requestcore is the v2 module of requestCore.

v2 is a **generics-first**, framework-agnostic HTTP application toolkit that builds on the root github.com/hmmftg/requestCore module while preserving full backward compatibility. It requires **Go 1.27+** for generic methods on [handlers.Endpoint].

Core Features

  • **Generic typed endpoints** — [handlers.Endpoint[Req, Resp]] flows request and response types through the entire lifecycle (parse, initialize, handle, render, finalize) without type erasure. Lifecycle hooks ([handlers.Endpoint.WithInitializer], [handlers.Endpoint.WithFinalizer], [handlers.Endpoint.WithPersistence]) are fully typed methods — no reflection, no runtime type-mismatch panics.

  • **Generic resources** — [resources.Resource[ID]] defines 7 CRUD operations where ID is constrained to cmp.Ordered (string, int, int64, etc.). The recommended path for v2 migration is [resources.Resource[ID]] paired with [resources.ResourceBuilder[ID]] for fluent registration. [resources.TypedResource] (14 type parameters) is an advanced alternative for cases requiring the strictest per-operation type guarantees — it is overkill for simple CRUD + custom resources.

  • **Typed session access** — [session.GetTyped[T]] and [session.SetTyped[T]] provide compile-time type-safe session value access. The [webFramework.SessionContext] and [webFramework.FlashContext] interfaces eliminate `any` type assertions in handlers.

  • **Generic response helpers** — [response.Handler.OKTyped[Resp]] and [response.Handler.OKWithStatusTyped[Resp]] render typed responses without `any` parameters.

  • **Framework-agnostic routing** — [routing.Router] and [routing.RouteGroup] interfaces work across Gin, Fiber, chi, and net/http via adapter packages ([libGin], [libFiber], [libChi], [libNetHttp]).

  • **Pluggable renderers** — renderers.Renderer interface with built-in JSON, XML, text, and CSV renderers.

  • **Error handler registry** — response.Registry with per-status handlers and legacy fallback.

  • **Bounded worker pool** — workers.InProcessWorker with retry, tracing, and mandatory [webFramework.AddLog] observability.

  • **Scheduler** — workers.Scheduler for periodic background tasks.

  • **CLI code generators** — `requestcore` CLI generates handlers, resources, middleware, and project scaffolding.

Module Structure

The v2 module lives in the v2/ directory and imports the root module for delegation to existing query, persistence, response, logging, and tracing infrastructure. The root module never imports v2.

See MIGRATION.md for the v1-to-v2 migration guide and README.md for the v2 module overview.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Model

type Model struct {
	LegacyCore      requestCore.RequestCoreInterface
	ResponseHandler *v2response.Handler
	Errors          v2response.Registry
	Renderer        renderers.Renderer
	Worker          workers.Worker
	Sessions        *session.Manager
}

Model is the default Runtime implementation. It composes the v1 RequestCoreInterface with v2 features.

func NewModel

func NewModel(
	legacyCore requestCore.RequestCoreInterface,
	legacyHandler response.WebHanlder,
	renderer renderers.Renderer,
	worker workers.Worker,
	sessionStore session.Store,
) *Model

NewModel creates a v2 Model from the given v1 core and v2 feature components. If any v2 component is nil, safe defaults are used.

func (*Model) DefaultRenderer

func (m *Model) DefaultRenderer() renderers.Renderer

DefaultRenderer returns the default renderer.

func (*Model) ErrorHandlers

func (m *Model) ErrorHandlers() v2response.Registry

ErrorHandlers returns the error handler registry.

func (*Model) GetDB

func (m *Model) GetDB() libQuery.QueryRunnerInterface

GetDB delegates to the v1 core.

func (*Model) Legacy

Legacy returns the v1 RequestCoreInterface.

func (*Model) ORM

func (m *Model) ORM() liborm.OrmInterface

ORM delegates to the v1 core.

func (*Model) Params

func (m *Model) Params() libParams.ParamInterface

Params delegates to the v1 core.

func (*Model) RequestTools

func (m *Model) RequestTools() libRequest.RequestInterface

RequestTools delegates to the v1 core.

func (*Model) Responder

func (m *Model) Responder() response.ResponseHandler

Responder returns the v1 response handler, implementing RequestCoreInterface.

func (*Model) SessionManager

func (m *Model) SessionManager() *session.Manager

SessionManager returns the session manager.

func (*Model) V2Responder

func (m *Model) V2Responder() *v2response.Handler

V2Responder returns the v2 response handler.

func (*Model) WorkerPool

func (m *Model) WorkerPool() workers.Worker

WorkerPool returns the worker pool.

type Runtime

type Runtime interface {
	// Legacy returns the v1 RequestCoreInterface for access to existing
	// query, persistence, response, logging, and tracing infrastructure.
	Legacy() requestCore.RequestCoreInterface

	// V2Responder returns the v2 response handler with renderer support
	// and error handler registry. Named V2Responder to avoid conflict
	// with the v1 RequestCoreInterface.Responder method.
	V2Responder() *v2response.Handler

	// ErrorHandlers returns the error handler registry.
	ErrorHandlers() v2response.Registry

	// DefaultRenderer returns the default renderer (JSON by default).
	DefaultRenderer() renderers.Renderer

	// WorkerPool returns the in-process worker pool.
	WorkerPool() workers.Worker

	// SessionManager returns the session manager.
	SessionManager() *session.Manager

	// GetDB returns the query runner interface (delegates to v1).
	GetDB() libQuery.QueryRunnerInterface
	// ORM returns the ORM interface (delegates to v1).
	ORM() liborm.OrmInterface
	// RequestTools returns the request interface (delegates to v1).
	RequestTools() libRequest.RequestInterface
	// Responder returns the v1 response handler (delegates to v1).
	// This matches the v1 RequestCoreInterface.Responder signature.
	Responder() response.ResponseHandler
	// Params returns the parameter interface (delegates to v1).
	Params() libParams.ParamInterface
}

Runtime is the v2 runtime façade providing access to all v2 features while delegating to the v1 RequestCoreInterface for existing infrastructure.

Directories

Path Synopsis
Package app provides a framework-neutral application bootstrap for v2 requestCore applications.
Package app provides a framework-neutral application bootstrap for v2 requestCore applications.
cmd
requestcore
Package cmd provides the requestcore CLI for generating v2 application scaffolding, including handlers, resources, middleware, and project structure.
Package cmd provides the requestcore CLI for generating v2 application scaffolding, including handlers, resources, middleware, and project structure.
requestcore/cmd command
examples
simple command
Package main is a v2 requestCore example application using chi.
Package main is a v2 requestCore example application using chi.
Package handlers provides the v2 request handler lifecycle, typed endpoint descriptors, and resource primitives for requestCore applications.
Package handlers provides the v2 request handler lifecycle, typed endpoint descriptors, and resource primitives for requestCore applications.
Package libChi provides the v2 chi web framework adapter for requestCore.
Package libChi provides the v2 chi web framework adapter for requestCore.
Package libFiber provides the v2 Fiber web framework adapter for requestCore.
Package libFiber provides the v2 Fiber web framework adapter for requestCore.
Package libGin provides the v2 Gin web framework adapter for requestCore.
Package libGin provides the v2 Gin web framework adapter for requestCore.
Package libNetHttp provides the v2 net/http web framework adapter for requestCore.
Package libNetHttp provides the v2 net/http web framework adapter for requestCore.
Package renderers provides pluggable content renderers for v2 response handling.
Package renderers provides pluggable content renderers for v2 response handling.
Package resources provides v2 resource registration with seven standard CRUD operations, inspired by Buffalo's resource pattern.
Package resources provides v2 resource registration with seven standard CRUD operations, inspired by Buffalo's resource pattern.
Package response provides the v2 response handler with a centralized error handler registry and pluggable renderers.
Package response provides the v2 response handler with a centralized error handler registry and pluggable renderers.
Package routing provides framework-agnostic route groups, middleware, and a Router interface implemented by Gin, Fiber, and net/http+chi adapters.
Package routing provides framework-agnostic route groups, middleware, and a Router interface implemented by Gin, Fiber, and net/http+chi adapters.
Package session provides pluggable session and flash management for v2.
Package session provides pluggable session and flash management for v2.
Package testingtools provides test utilities for v2 handler and middleware testing, including a test parser, test router, and initialization helpers.
Package testingtools provides test utilities for v2 handler and middleware testing, including a test parser, test router, and initialization helpers.
Package webFramework provides the v2 web framework abstraction layer.
Package webFramework provides the v2 web framework abstraction layer.
Package workers provides a bounded in-process worker pool with retry, tracing, and mandatory observability through webFramework.AddLog.
Package workers provides a bounded in-process worker pool with retry, tracing, and mandatory observability through webFramework.AddLog.

Jump to

Keyboard shortcuts

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