handlers

package
v0.28.1 Latest Latest
Warning

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

Go to latest
Published: Aug 11, 2026 License: MIT Imports: 28 Imported by: 0

README

Handlers Package Documentation

The handlers package provides reusable request-processing components for common backend workflows such as:

  • querying databases
  • executing DML operations
  • external API calls
  • pagination
  • recovery handling
  • request consumption pipelines

The package is designed around composable handler logic that can be integrated with the broader requestCore ecosystem.


Overview

The handlers package acts as an orchestration layer between:

  • request context handling
  • query execution
  • request lifecycle management
  • response generation
  • external service communication

It provides reusable building blocks to reduce repetitive endpoint and service logic.


Package Structure

handlers/
├── baseHandler.go
├── callApi.go
├── consumeHandler.go
├── dmlHandler.go
├── ormQueryHandler.go
├── pagination.go
├── persistence.go
├── queryHandler.go
├── recovery.go
└── *_test.go

Core Concepts

The handlers package follows several architectural principles:

  • reusable request-processing pipelines
  • separation of query/DML concerns
  • framework-independent business flow handling
  • composable handler utilities
  • centralized error and recovery behavior
  • testing-friendly abstractions

Handlers

Base Handler

File:

handlers/baseHandler.go

The base handler provides common functionality shared across specialized handlers.

Typical responsibilities may include:

  • request initialization
  • context preparation
  • validation flow integration
  • shared response handling
  • standardized execution behavior
  • common logging/tracing hooks

This acts as the foundation for other handler implementations.


Query Handler

File:

handlers/queryHandler.go

The query handler is responsible for read-oriented operations.

Typical use cases:

  • SELECT queries
  • fetching paginated data
  • filtering/search operations
  • response mapping
  • query execution orchestration

This handler integrates with the query layer provided by:

libQuery

and may use ORM or direct query execution depending on the implementation.


ORM Query Handler

File:

handlers/ormQueryHandler.go

The ORM query handler provides query execution behavior specifically tailored for ORM-backed flows.

Typical responsibilities:

  • ORM query execution
  • model-based retrieval
  • entity mapping
  • ORM abstraction integration
  • repository-style operations

This handler is useful when the application prefers ORM-based data access instead of raw SQL execution.


DML Handler

File:

handlers/dmlHandler.go

The DML handler manages write-oriented database operations.

Typical operations include:

  • INSERT
  • UPDATE
  • DELETE
  • transactional workflows
  • persistence orchestration

This handler centralizes mutation logic and promotes consistency across write operations.


Call API Handler

File:

handlers/callApi.go

The API call handler manages outbound HTTP/API interactions.

Typical responsibilities:

  • calling external services
  • handling authentication flows
  • request serialization
  • response parsing
  • retry/error handling integration
  • multi-service orchestration

This handler works alongside:

libCallApi

to standardize external communication behavior.


Consume Handler

File:

handlers/consumeHandler.go

The consume handler is intended for request or event consumption workflows.

Possible use cases:

  • async processing
  • event/message consumption
  • queue-driven workflows
  • background task handling
  • request replay flows

This handler helps encapsulate consumption-oriented execution patterns.


Pagination Utilities

File:

handlers/pagination.go

Pagination utilities provide reusable pagination behavior for query endpoints.

Typical capabilities:

  • page-based pagination
  • offset/limit handling
  • response metadata generation
  • pagination validation
  • standardized paging responses

Useful for:

  • REST APIs
  • admin panels
  • search endpoints
  • reporting APIs

Recovery Handler

File:

handlers/recovery.go

Recovery utilities provide panic/error recovery behavior for safer request execution.

Typical responsibilities:

  • panic recovery
  • structured error conversion
  • centralized failure handling
  • logging unexpected failures
  • preventing application crashes from request-level errors

This improves resiliency and operational stability.


Architectural Role

The handlers package sits between:

Transport Layer
    ↓
Context Initialization
    ↓
Handlers
    ↓
Query / Request / Response Layers
    ↓
Database / External Services

This creates a reusable execution pipeline that keeps endpoint logic thin and consistent.


Integration with requestCore

Handlers integrate closely with:

Package Purpose
libContext unified request context
libQuery DB/query execution
libRequest request lifecycle
response standardized responses
libCallApi external API communication
libTracing observability/tracing
libLogger structured logging

Typical Request Flow

A typical flow using handlers may look like:

Incoming Request
    ↓
Framework Adapter (Gin/Fiber/nethttp)
    ↓
libContext Initialization
    ↓
Handler Execution
    ↓
Query/DML/API Logic
    ↓
Response Generation

Observability

Handlers are designed to work with the repository’s observability stack:

  • OpenTelemetry tracing
  • structured logging
  • request-scoped metadata
  • framework-aware context propagation

This allows consistent visibility across request pipelines.


Request persistence (optional)

Handlers support optional request/result persistence via RequestPersister[Req, Resp] on generic HandlerParameters[Req, Resp].

When Persistence is nil (default for built-in query/DML/call handlers), no insert or update runs. When set, the framework calls:

  1. Insert(path, req) after parse — failure aborts the request
  2. Update(path, req) in Recovery after Finalizer and log collection — best-effort; errors are logged only and not retried
type RequestPersister[Req, Resp any] interface {
    Insert(path string, req *HandlerRequest[Req, Resp]) error
    Update(path string, req *HandlerRequest[Req, Resp]) error
}
Handler outcome fields

After the response is sent (or after a panic is captured in Recovery), Update receives a HandlerRequest with populated outcome metadata:

type HandlerOutcome struct {
    Error      error // nil on success; set on handler/init/parse/insert errors and panics
    HTTPStatus int   // HTTP status sent or intended (500 on panic); 0 if no response was sent
}

type HandlerRequest[Req, Resp any] struct {
    ...
    Outcome  HandlerOutcome
    Duration time.Duration // elapsed handler time, set in Recovery
    RespSent bool
}

HTTPStatus is recorded by the response layer (response.LastHTTPStatusLocal) after Responder().OK / Responder().Error, so it reflects the status actually emitted — not a duplicate mapping in handlers. On panic, Recovery sets HTTPStatus to 500 before Update runs.

Use trx.Outcome.Error with libError.Unwrap to build persistence outcome without reading parser locals such as errorArray.

Record ID handoff

Use a shared local key instead of per-domain names (shahkar_request_id, card_issue_id, etc.):

handlers.SetPersistedRecordID(req.W, recordID) // any type: int64, string UUID, etc.
id, ok := handlers.GetPersistedRecordID(req.W)
FuncPersister

For tests or thin adapters, implement persistence with function fields:

p := handlers.FuncPersister[MyReq, MyResp]{
    InsertFn: func(path string, req *handlers.HandlerRequest[MyReq, MyResp]) error { ... },
    UpdateFn: func(path string, req *handlers.HandlerRequest[MyReq, MyResp]) error { ... },
}

Nil function fields are no-ops. Use Persistence: nil when no persistence is needed.

Example service persister

Consumers implement RequestPersister when they need audit storage, for example delegating to libRequest:

type ServiceRequestPersister[Req, Resp any] struct{}

func (ServiceRequestPersister[Req, Resp]) Insert(path string, req *handlers.HandlerRequest[Req, Resp]) error {
    err := req.Core.RequestTools().InitRequest(req.W, req.Title, path)
    if err != nil {
        return err
    }
    handlers.SetPersistedRecordID(req.W, req.W.Parser.GetLocal("reqLog").(libRequest.RequestPtr).GetId())
    return nil
}

func (ServiceRequestPersister[Req, Resp]) Update(path string, req *handlers.HandlerRequest[Req, Resp]) error {
    reqLogLocal := req.W.Parser.GetLocal("reqLog")
    reqLog, ok := reqLogLocal.(libRequest.RequestPtr)
    if !ok || reqLog == nil {
        return nil
    }
    reqLog.Outgoing = req.Response
    if req.Outcome.Error != nil {
        if ok, errData := libError.Unwrap(req.Outcome.Error); ok {
            _ = errData // map code/status into your storage model
        }
    }
    return req.Core.RequestTools().UpdateRequestWithContext(req.W.Ctx, reqLog)
}

SQL and table shape for the service-tier request table live in application setup (libApplication/env.go), not in handlers.


Testing

The handlers package includes test coverage through files such as:

baseHanlder_test.go
persistence_test.go
callApi_test.go
consumeHandler_test.go
dmlHandler_test.go
queryHandler_test.go

This indicates handlers are designed for isolated testing and reusable execution flows.


Keep handlers orchestration-focused

Handlers should primarily:

  • coordinate flows
  • validate execution paths
  • call lower-level services
  • standardize responses

Avoid embedding heavy business logic directly in handlers.


Use specialized handlers

Prefer:

  • QueryHandler for reads
  • DMLHandler for writes
  • CallApiHandler for external communication

instead of combining unrelated concerns.


Keep business logic independent

Business logic should remain in:

  • services
  • domain modules
  • repositories

while handlers remain execution coordinators.


Suggested Future Enhancements

Potential improvements for the handlers package:

  • middleware chaining support
  • generic handler pipelines
  • transactional scopes
  • retry policies
  • circuit breaker integration
  • async workflow helpers
  • event-driven handler abstractions
  • CQRS-oriented handler separation

Summary

The handlers package provides reusable orchestration components for:

  • query execution
  • DML operations
  • external API communication
  • pagination
  • recovery
  • request consumption flows

It serves as a reusable execution layer that helps standardize backend request processing while remaining framework-independent and observability-friendly.

Documentation

Overview

Package handlers provides request handler primitives for requestCore applications.

Index

Constants

View Source
const (
	// HeadersMap is the local key for the extracted headers map.
	HeadersMap = "headersMap"
	// FinalPath is the local key for the computed final request path.
	FinalPath = "finalPath"
)
View Source
const (
	// DefaultPageText is the default query parameter name for the page number.
	DefaultPageText = "page"
	// DefaultSizeText is the default query parameter name for the page size.
	DefaultSizeText = "size"
	// DefaultPage is the default page number when not specified.
	DefaultPage = "1"
	// DefaultPageSize is the default page size when not specified.
	DefaultPageSize = "10"
	// DefaultMinPageSize is the minimum allowed page size.
	DefaultMinPageSize = 10
	// DefaultMaxPageSize is the maximum allowed page size.
	DefaultMaxPageSize = 100
)
View Source
const (
	// Asc is the ascending sort order constant.
	Asc = "asc"
	// Dsc is the descending sort order constant.
	Dsc = "desc"
)
View Source
const (
	CallAPILogEntry string = "ApiCall"
)

CallAPILogEntry is the log key used for API call log entries.

View Source
const CorrelationIDHeader = "X-Correlation-ID"

CorrelationIDHeader is the HTTP header name used to propagate the correlation ID to downstream services.

View Source
const CorrelationIDLocalKey = "correlation_id"

CorrelationIDLocalKey is the per-request local-storage key for the correlation ID, an alternative cross-service correlation identifier to the request ID. Set it during request initialization via w.Parser.SetLocal(CorrelationIDLocalKey, correlationID).

View Source
const PersistedRecordIDKey = "handlers.persisted_record_id"

PersistedRecordIDKey is the local-storage key for the persisted record ID.

View Source
const RequestIDHeader = "X-Request-ID"

RequestIDHeader is the HTTP header name used to propagate the request ID to downstream services.

View Source
const RequestIDLocalKey = "request_id"

RequestIDLocalKey is the per-request local-storage key for the request ID used for cross-service correlation. Set it during request initialization via w.Parser.SetLocal(RequestIDLocalKey, requestID).

Variables

View Source
var ErrServerTimeout = errors.New("server-side timeout exceeded")

ErrServerTimeout is the sentinel error wrapped inside BuildTimeoutError. Use errors.Is(err, handlers.ErrServerTimeout) to check for server-side timeout errors regardless of additional context.

Functions

func BaseHandler

func BaseHandler[Req any, Resp any, Handler HandlerInterface[Req, Resp]](
	core requestCore.RequestCoreInterface,
	handler Handler,
	simulation bool,
	args ...any,
) any

BaseHandler returns a handler function that orchestrates the full request lifecycle.

func BuildBaseRemoteHeaders added in v0.27.0

func BuildBaseRemoteHeaders(w webFramework.WebFramework, appName, correlationID string) map[string]string

BuildBaseRemoteHeaders returns a fresh map of base headers for an outbound remote API call. It sets:

  • Accept: application/json
  • X-App-ID: <appName>-<pid>
  • X-Request-ID: <requestID> (when present in the parser's local storage)
  • X-Correlation-ID: <correlationID> (from the argument when non-empty, otherwise from CorrelationIDLocalKey in parser locals when present)

The correlationID argument takes precedence over the parser local. It does not add authorization; RemoteAPI.EnsureAuthorization remains responsible for that. Each invocation returns a new map; callers can safely mutate the result.

func BuildRequestURL added in v0.27.0

func BuildRequestURL(domain, path, query string) string

BuildRequestURL constructs the full request URL from domain, path, and query. It mirrors the URL construction in libCallApi.PrepareCall, which builds the request URL as Domain + "/" + Path + Query (direct concatenation). Callers must ensure Query is either empty or begins with "?".

func BuildTimeoutError added in v0.27.0

func BuildTimeoutError(domain string, statusCode int) error

BuildTimeoutError creates a standardized libError for server-side timeout conditions. The domain is included for context. The returned error wraps ErrServerTimeout so callers can use errors.Is to detect timeout errors.

statusCode selects the status stored in the returned libError. When zero, it defaults to http.StatusRequestTimeout (408). Note: this status is the application-level error status of the returned error only; it does not override the observed remote HTTP status recorded in metrics or TransactionInfo.StatusCode.

func CallAPI added in v0.28.1

func CallAPI[Resp any](
	w webFramework.WebFramework,
	core requestCore.RequestCoreInterface,
	method string,
	param libCallApi.CallParam) (*Resp, error)

CallAPI performs a remote API call and returns the typed result.

func CallAPIForm added in v0.28.1

func CallAPIForm[Req any, Resp any](
	w webFramework.WebFramework,
	_ requestCore.RequestCoreInterface,
	method string,
	param *libCallApi.RemoteCallParamData[Req, Resp],
) (Resp, error)

CallAPIForm performs a form-encoded remote API call and returns the typed response.

func CallAPIInternal added in v0.28.1

func CallAPIInternal[Resp any](
	w webFramework.WebFramework,
	_ requestCore.RequestCoreInterface,
	method string,
	param libCallApi.CallParam) (*Resp, error)

CallAPIInternal performs a remote API call and returns the raw response.

func CallAPIJSON added in v0.28.1

func CallAPIJSON[Req any, Resp any](
	w webFramework.WebFramework,
	_ requestCore.RequestCoreInterface,
	method string,
	param *libCallApi.RemoteCallParamData[Req, Resp],
) (Resp, error)

CallAPIJSON performs a JSON remote API call and returns the typed response.

func CallAPIJSONWithOpts added in v0.28.1

func CallAPIJSONWithOpts[Req any, Resp any](
	w webFramework.WebFramework,
	_ requestCore.RequestCoreInterface,
	param *libCallApi.RemoteCallParamData[Req, Resp],
	opts CallAPIOptions,
) (Resp, error)

CallAPIJSONWithOpts is an enhanced version of CallAPIJSON that adds:

  • Prometheus metrics recording via libTracing.RecordHTTPClientCallWithOutcome
  • A server-side elapsed-time timeout guard (in addition to the HTTP client timeout)
  • HTTP status code preservation via RemoteCallError (independently of the caller's builder)
  • Framework-level transaction logging via webFramework.TransactionLogger
  • An optional OnComplete callback for application-layer extension hooks
  • Optional error normalization via NormalizeError
  • Optional retry via RetryPolicy
  • Configurable log keys via LogKeys

webFramework.AddLog is called on every code path (request, error, response) and is never skipped or conditionally bypassed. Transaction logging runs after AddLog and never replaces it.

Custom headers: set param.Headers directly (e.g. param.Headers["SIGNATURE"] = "...").

func CallAPINoLog added in v0.28.1

func CallAPINoLog[Resp any](
	w webFramework.WebFramework,
	method string,
	param libCallApi.CallParam) (*Resp, error)

CallAPINoLog performs a remote API call without logging and returns the typed result.

func CallAPIWithReceipt added in v0.28.1

func CallAPIWithReceipt[Resp any](
	w webFramework.WebFramework,
	core requestCore.RequestCoreInterface,
	method string,
	param libCallApi.CallParam) (*Resp, *response.Receipt, error)

CallAPIWithReceipt performs a remote API call and returns the result and receipt.

func CallRemote added in v0.9.7

func CallRemote[Req any, Resp any](
	core requestCore.RequestCoreInterface,
	callArg CallArgs[Req, Resp],
	simulation bool,
	args ...string,
) any

CallRemote returns a base handler that forwards requests to a remote service.

func CallRemoteWithRespParser added in v0.9.7

func CallRemoteWithRespParser[Req any, Resp any](
	core requestCore.RequestCoreInterface,
	callArgs CallArgs[Req, Resp],
	simulation bool,
	args ...string,
) any

CallRemoteWithRespParser returns a base handler that forwards requests with a response parser.

func ConsumeHandler added in v0.9.52

func ConsumeHandler[Req, Resp any](
	core requestCore.RequestCoreInterface,
	params *ConsumeHandlerType[Req, Resp],
	simulation bool,
) any

ConsumeHandler returns a base handler that consumes a remote API endpoint.

func Default added in v0.10.29

func Default() gin.HandlerFunc

Default returns a new pagination middleware with default values.

func DmlHandler

func DmlHandler[Req libQuery.DmlModel](
	core requestCore.RequestCoreInterface,
	handler DmlHandlerType[Req, map[string]any],
	simulation bool,
) any

DmlHandler returns a base handler that executes DML commands.

func ExecDML

func ExecDML(request libQuery.DmlModel, key, title string, w webFramework.WebFramework, core requestCore.RequestCoreInterface) (map[string]any, error)

ExecDML runs the pre-control, execute, and finalize phases of a DML model.

func ExecuteDML

ExecuteDML executes the DML commands and returns the results map.

func ExtractHeaders added in v0.10.3

func ExtractHeaders(w webFramework.WebFramework, headers, locals []string) map[string]string

ExtractHeaders builds a map of headers and locals from the web framework parser.

func ExtractValue added in v0.10.3

func ExtractValue(name string, source func(string) string, dest map[string]string)

ExtractValue extracts a value from source and stores it in dest, supporting header#alias syntax.

func Filterate added in v0.11.2

func Filterate[Row any](paginationData libRequest.PaginationData, data []Row, filterFunc func(Filter) func(Row) bool) []Row

Filterate applies filter conditions from pagination data to the row slice.

func FinalizeDML

FinalizeDML executes the finalize commands for a DML model.

func GetPersistedRecordID added in v0.26.0

func GetPersistedRecordID(w webFramework.WebFramework) (any, bool)

GetPersistedRecordID retrieves the persisted record ID from the parser's local storage.

func InitPostRequest added in v0.9.7

func InitPostRequest(
	w webFramework.WebFramework,
	reqLog libRequest.RequestPtr,
	_, url string,
	checkDuplicate func(libRequest.Request) error,
	insertRequest func(libRequest.Request) error,
	args ...any,
) (int, map[string]string, error)

InitPostRequest validates and persists a request, then builds the formatted path.

func New added in v0.10.29

func New(pageText, sizeText, defaultPage, defaultPageSize string, minPageSize, maxPageSize int) gin.HandlerFunc

New returns a new pagination middleware with custom values.

func NormalizeCallError added in v0.27.0

func NormalizeCallError(err error) error

NormalizeCallError converts a raw remote-call error into a standardized libError with a consistent API_CALL_ERROR description. It uses libError.Unwrap to detect typed errors and preserves specific error codes that require special handling (e.g., API_CONNECT_TIMED_OUT for retry predicates).

Behavior:

  • nil → nil
  • API_CONNECT_TIMED_OUT: returned unchanged (retry predicates depend on it)
  • API_UNABLE_PARSE_RESP: re-wrapped with useful child text if available
  • Other libError values: re-wrapped as API_CALL_ERROR with original context
  • Non-libError errors: returned unchanged

func Paginate added in v0.11.0

func Paginate[Row any](paginationData libRequest.PaginationData, data []Row, less func(string) func(i int, j int) bool) []Row

Paginate sorts and slices the data according to the pagination parameters.

func PreControlDML

PreControlDML executes the pre-control commands for a DML model.

func Query added in v0.11.6

func Query[Row, Resp any](
	core requestCore.RequestCoreInterface,
	handler QueryHandlerType[Row, Resp],
	simulation bool,
) any

Query returns a base handler that executes a database query.

func QueryHandler added in v0.9.20

func QueryHandler[Row any, Resp []Row](
	title, key, path string, queryMap map[string]libQuery.QueryCommand,
	core requestCore.RequestCoreInterface,
	mode libRequest.Type,
	validateHeader, simulation bool,
	recoveryHandler func(any),
) any

QueryHandler returns a base handler for database queries using the database's default mode.

func QueryHandlerWithCaching added in v0.11.4

func QueryHandlerWithCaching[Row any, Resp []Row](
	title, key, path string, queryMap map[string]libQuery.QueryCommand,
	core requestCore.RequestCoreInterface,
	mode libRequest.Type,
	validateHeader, simulation bool,
	recoveryHandler func(any),
	caching *CachingArgs,
) any

QueryHandlerWithCaching returns a base handler for database queries with caching support.

func QueryHandlerWithOrm added in v0.16.4

func QueryHandlerWithOrm[Row any, Resp []Row](
	title, key, path string, queryMap map[string]libQuery.QueryCommand,
	core requestCore.RequestCoreInterface,
	mode libRequest.Type,
	validateHeader, simulation bool,
	recoveryHandler func(any),
	caching *CachingArgs,
) any

QueryHandlerWithOrm returns a base handler for ORM queries using the database's default mode.

func QueryHandlerWithTransform added in v0.10.25

func QueryHandlerWithTransform[Row, Resp any](
	title, key, path string, queryMap map[string]libQuery.QueryCommand,
	core requestCore.RequestCoreInterface,
	mode libRequest.Type,
	validateHeader, simulation bool,
	recoveryHandler func(any),
	replacer CommandReplacer[libRequest.PaginationData],
	translator RowTranslator[Row, Resp],
	caching *CachingArgs,
) any

QueryHandlerWithTransform returns a base handler for queries with a custom translator and command replacer.

func QueryWithOrm added in v0.16.4

func QueryWithOrm[Row, Resp any](
	core requestCore.RequestCoreInterface,
	handler OrmHandlerType[Row, Resp],
	simulation bool,
) any

QueryWithOrm returns a base handler that executes an ORM query.

func Recovery added in v0.15.0

func Recovery[Req any, Resp any, Handler HandlerInterface[Req, Resp]](
	start time.Time,
	w webFramework.WebFramework,
	handler Handler,
	params HandlerParameters[Req, Resp],
	trx *HandlerRequest[Req, Resp],
	core requestCore.RequestCoreInterface,
	requestInserted bool,
	panicVal any,
)

Recovery handles panic recovery, finalization, and log collection for a handler request.

func SetPersistedRecordID added in v0.26.0

func SetPersistedRecordID(w webFramework.WebFramework, id any)

SetPersistedRecordID stores the persisted record ID in the parser's local storage.

func ShouldSkipAPICall added in v0.28.1

func ShouldSkipAPICall(endpoint, method string, skipPatterns []string) bool

ShouldSkipAPICall reports whether an endpoint matches one of the supplied skip patterns. It is an application-layer decision helper only: it must not be invoked by CallAPIJSONWithOpts to control webFramework.AddLog, and a match must never be used to suppress the mandatory request, success, or failure framework logs.

Pattern grammar:

  • "endpoint" matches any HTTP method
  • "endpoint:METHOD" matches only when the call's method equals METHOD

Matching rules:

  • Patterns are trimmed of surrounding whitespace; empty patterns are ignored.
  • A pattern containing more than one ':' separator is malformed and is ignored (it never matches), rather than being treated as a broad match.
  • Method comparison is case-insensitive.
  • Endpoint matching is either an exact match or a path-boundary prefix match: the endpoint equals the pattern endpoint, or the endpoint begins with patternEndpoint + "/". Substring matching is never used, so "api/card" does not match "api/cardholder".
  • Leading and trailing slashes are normalized away from both the endpoint and the pattern endpoint before comparison, so "/api/card/", "api/card", and "/api/card" are equivalent.

Types

type APICallInfo added in v0.28.1

type APICallInfo = webFramework.TransactionInfo

APICallInfo is a compatibility alias for webFramework.TransactionInfo. New code should use webFramework.TransactionInfo directly.

type CachingArgs added in v0.11.4

type CachingArgs struct {
	Cache       bool
	CacheMaxAge time.Duration
}

CachingArgs holds caching configuration for query handlers.

type CallAPILogKeys added in v0.28.1

type CallAPILogKeys struct {
	Request  string // default: <Method>
	Response string // default: <Method>-resp
	Failure  string // default: <Method>-error
}

CallAPILogKeys holds configurable log key templates for AddLog entries. When a field is empty, the corresponding default is used.

type CallAPIOptions added in v0.28.1

type CallAPIOptions struct {
	Method  string        // log key, e.g. "soha-authorize"
	Timeout time.Duration // server-side elapsed-time guard (0 = no guard)

	// LogKeys, when set, overrides the default AddLog key templates.
	// Empty fields fall back to the defaults.
	LogKeys CallAPILogKeys

	// MetricsRecorder, if set, records Prometheus-style metrics for the call.
	// If nil, the default global Prometheus recorder is used.
	MetricsRecorder libTracing.HTTPClientMetricsRecorder

	// OnComplete is an optional callback invoked after the remote call
	// finishes (success or failure). It receives the call metadata so the
	// application layer can record it in its own transaction logger, metrics,
	// or any other observability system. nil = no callback.
	OnComplete func(webFramework.TransactionInfo)

	// NormalizeError, when set, is applied to the returned error after
	// raw observability (AddLog, metrics, transaction logging, OnComplete)
	// has been recorded. This preserves raw Splunk logs while allowing
	// callers to normalize the error returned to their consumers.
	NormalizeError func(error) error

	// RetryPolicy, when set, enables retry behavior. The single-attempt
	// logic is reused for each attempt with full observability per attempt.
	// nil = no retries (single attempt, existing behavior).
	RetryPolicy *libRetry.RetryPolicy

	// TimeoutStatusCode selects the status stored in the returned timeout
	// libError when the server-side elapsed-time guard fires. Zero = default
	// (http.StatusRequestTimeout, 408). This affects ONLY the returned
	// libError's application status; TransactionInfo.StatusCode and metrics
	// status_class continue to represent the actual observed remote HTTP
	// status.
	TimeoutStatusCode int

	// MaskFunc, when set, is applied to Request, parsed Response, and
	// ResponseBody (the result is stored in MaskedResponseBody) before
	// TransactionLogger and OnComplete receive TransactionInfo. nil = no
	// masking (raw values passed through). Must NOT mutate the outbound
	// request or the typed response returned by CallAPIJSONWithOpts. Never
	// applied to webFramework.AddLog attrs (AddLog uses
	// RemoteCallParamData.LogValue which independently masks Authorization).
	MaskFunc func(any) any
}

CallAPIOptions holds optional parameters for CallAPIJSONWithOpts.

type CallArgs added in v0.9.7

type CallArgs[Req any, Resp any] struct {
	Title, Path, API, Method string
	HasQuery, IsJSON         bool
	HasInitializer           bool
	ForwardAuth              bool
	Transmitter              func(
		path, api, method string,
		requestByte []byte,
		headers map[string]string,
		parseRemoteResp func([]byte, string, int) (int, map[string]string, any, error),
		consumer func([]byte, string, string, string, string, map[string]string) ([]byte, string, int, error),
	) (int, map[string]string, any, error)
	Args, Locals, Headers []string
	Parser                func(respBytes []byte, desc string, status int) (int, map[string]string, any, error)
	RecoveryHandler       func(any)
}

CallArgs holds the arguments for a remote call handler.

func (CallArgs[Req, Resp]) Finalizer added in v0.9.7

func (c CallArgs[Req, Resp]) Finalizer(_ HandlerRequest[Req, Resp])

Finalizer is a no-op finalizer for the CallArgs handler.

func (CallArgs[Req, Resp]) Handler added in v0.9.7

func (c CallArgs[Req, Resp]) Handler(req HandlerRequest[Req, Resp]) (Resp, error)

Handler performs the remote call for the CallArgs handler.

func (CallArgs[Req, Resp]) Initializer added in v0.9.7

func (c CallArgs[Req, Resp]) Initializer(req HandlerRequest[Req, Resp]) error

Initializer prepares headers and the final path for the remote call.

func (CallArgs[Req, Resp]) Parameters added in v0.9.7

func (c CallArgs[Req, Resp]) Parameters() HandlerParameters[Req, Resp]

Parameters returns the handler parameters for the CallArgs.

func (CallArgs[Req, Resp]) Simulation added in v0.9.19

func (c CallArgs[Req, Resp]) Simulation(req HandlerRequest[Req, Resp]) (Resp, error)

Simulation returns the default response for simulation mode.

type CommandReplacer added in v0.10.29

type CommandReplacer[T any] struct {
	Token   string
	Builder func(T) string
}

CommandReplacer replaces a token in a query command string using a builder function.

func (CommandReplacer[T]) Replace added in v0.10.29

func (c CommandReplacer[T]) Replace(command string, data T) string

Replace substitutes the token in the command with the value built from data.

type ConsumeHandlerType added in v0.9.52

type ConsumeHandlerType[Req, Resp any] struct {
	Title           string
	Params          libCallApi.RemoteCallParamData[Req, Resp]
	Path            string
	Mode            libRequest.Type
	VerifyHeader    bool
	HasReceipt      bool
	Headers         []string
	API             string
	Method          string
	Query           string
	RecoveryHandler func(any)
}

ConsumeHandlerType holds configuration for a consume handler that proxies remote API calls.

func (*ConsumeHandlerType[Req, Resp]) Finalizer added in v0.9.52

func (h *ConsumeHandlerType[Req, Resp]) Finalizer(_ HandlerRequest[Req, Resp])

Finalizer is a no-op finalizer for the ConsumeHandlerType.

func (*ConsumeHandlerType[Req, Resp]) Handler added in v0.9.52

func (h *ConsumeHandlerType[Req, Resp]) Handler(req HandlerRequest[Req, Resp]) (Resp, error)

Handler performs the remote JSON call for the ConsumeHandlerType.

func (*ConsumeHandlerType[Req, Resp]) Initializer added in v0.9.52

func (h *ConsumeHandlerType[Req, Resp]) Initializer(req HandlerRequest[Req, Resp]) error

Initializer appends URL parameters to the handler path.

func (*ConsumeHandlerType[Req, Resp]) Parameters added in v0.9.52

func (h *ConsumeHandlerType[Req, Resp]) Parameters() HandlerParameters[Req, Resp]

Parameters returns the handler parameters for the ConsumeHandlerType.

func (*ConsumeHandlerType[Req, Resp]) Simulation added in v0.9.52

func (h *ConsumeHandlerType[Req, Resp]) Simulation(req HandlerRequest[Req, Resp]) (Resp, error)

Simulation returns the default response for simulation mode.

type DmlHandlerType

type DmlHandlerType[Req libQuery.DmlModel, Resp map[string]any] struct {
	Title           string
	Path            string
	Mode            libRequest.Type
	VerifyHeader    bool
	Key             string
	RecoveryHandler func(any)
}

DmlHandlerType holds configuration for a DML handler.

func (DmlHandlerType[Req, Resp]) Finalizer

func (h DmlHandlerType[Req, Resp]) Finalizer(req HandlerRequest[Req, Resp])

Finalizer runs the finalize DML phase if the response was sent.

func (DmlHandlerType[Req, Resp]) Handler

func (h DmlHandlerType[Req, Resp]) Handler(req HandlerRequest[Req, Resp]) (Resp, error)

Handler executes the DML commands for the handler.

func (DmlHandlerType[Req, Resp]) Initializer

func (h DmlHandlerType[Req, Resp]) Initializer(req HandlerRequest[Req, Resp]) error

Initializer runs the pre-control DML phase for the handler.

func (DmlHandlerType[Req, Resp]) Parameters

func (h DmlHandlerType[Req, Resp]) Parameters() HandlerParameters[Req, Resp]

Parameters returns the handler parameters for the DmlHandlerType.

func (DmlHandlerType[Req, Resp]) Simulation added in v0.9.19

func (h DmlHandlerType[Req, Resp]) Simulation(req HandlerRequest[Req, Resp]) (Resp, error)

Simulation returns the default response for simulation mode.

type Filter added in v0.11.2

type Filter struct {
	Field    string
	Operator string
	Value    string
	Value2nd string
}

Filter holds a single filter condition for query result filtering.

type FuncPersister added in v0.26.0

type FuncPersister[Req, Resp any] struct {
	InsertFn func(path string, req *HandlerRequest[Req, Resp]) error
	UpdateFn func(path string, req *HandlerRequest[Req, Resp]) error
}

FuncPersister is a RequestPersister backed by insert and update functions.

func (FuncPersister[Req, Resp]) Insert added in v0.26.0

func (p FuncPersister[Req, Resp]) Insert(path string, req *HandlerRequest[Req, Resp]) error

Insert delegates to the InsertFn if set.

func (FuncPersister[Req, Resp]) Update added in v0.26.0

func (p FuncPersister[Req, Resp]) Update(path string, req *HandlerRequest[Req, Resp]) error

Update delegates to the UpdateFn if set.

type HandlerInterface

type HandlerInterface[Req any, Resp any] interface {
	// returns handler title
	//   Request Bodymode
	//   and validate header option
	//   and optional request persistence
	//   and url path of handler
	Parameters() HandlerParameters[Req, Resp]
	// runs after validating request
	Initializer(req HandlerRequest[Req, Resp]) error
	// main handler runs after initialize
	Handler(req HandlerRequest[Req, Resp]) (Resp, error)
	// runs after sending back response
	Finalizer(req HandlerRequest[Req, Resp])
	// handles simulation mode
	Simulation(req HandlerRequest[Req, Resp]) (Resp, error)
}

HandlerInterface is the interface that request handlers must implement.

type HandlerOutcome added in v0.26.0

type HandlerOutcome struct {
	Error      error
	HTTPStatus int
}

HandlerOutcome holds the error and HTTP status result of a handler request.

type HandlerParameters added in v0.9.45

type HandlerParameters[Req, Resp any] struct {
	Title           string
	Body            libRequest.Type
	ValidateHeader  bool
	Path            string
	HasReceipt      bool
	RecoveryHandler func(any)
	FileResponse    bool
	LogArrays       []string
	LogTags         []string
	Persistence     RequestPersister[Req, Resp]
	// Tracing parameters
	EnableTracing   bool
	TracingSpanName string
}

HandlerParameters holds configuration for a request handler.

type HandlerRequest

type HandlerRequest[Req any, Resp any] struct {
	Title    string
	Core     requestCore.RequestCoreInterface
	Header   *libRequest.RequestHeader
	Request  *Req
	Response Resp
	W        webFramework.WebFramework
	Args     []any
	RespSent bool
	Builder  func(status int, rawResp []byte, headers map[string]string) (*Resp, error)
	Outcome  HandlerOutcome
	Duration time.Duration
	// Tracing fields
	Span    trace.Span
	SpanCtx context.Context
}

HandlerRequest holds the per-request state passed through the handler lifecycle.

func (*HandlerRequest[Req, Resp]) AddSpanAttribute added in v0.18.0

func (trx *HandlerRequest[Req, Resp]) AddSpanAttribute(key, value string)

AddSpanAttribute adds a string key-value attribute to the request's span.

func (*HandlerRequest[Req, Resp]) AddSpanAttributes added in v0.18.0

func (trx *HandlerRequest[Req, Resp]) AddSpanAttributes(attrs map[string]string)

AddSpanAttributes adds multiple string key-value attributes to the request's span.

func (*HandlerRequest[Req, Resp]) AddSpanEvent added in v0.18.0

func (trx *HandlerRequest[Req, Resp]) AddSpanEvent(name string, attrs map[string]string)

AddSpanEvent records an event with attributes on the request's span.

func (HandlerRequest[Req, Resp]) GetParser added in v0.22.0

func (trx HandlerRequest[Req, Resp]) GetParser() webFramework.RequestParser

GetParser returns the RequestParser from WebFramework for tracing.

func (*HandlerRequest[Req, Resp]) RecordSpanError added in v0.18.0

func (trx *HandlerRequest[Req, Resp]) RecordSpanError(err error, attrs map[string]string)

RecordSpanError records an error with attributes on the request's span.

func (*HandlerRequest[Req, Resp]) SetOutcome added in v0.26.0

func (trx *HandlerRequest[Req, Resp]) SetOutcome(err error, httpStatus int)

SetOutcome sets the error and HTTP status on the handler request's outcome.

func (*HandlerRequest[Req, Resp]) StartChildSpan added in v0.18.0

func (trx *HandlerRequest[Req, Resp]) StartChildSpan(name string, attrs map[string]string) (context.Context, trace.Span)

StartChildSpan starts a child span with attributes from the request's span context.

type OrmHandlerType added in v0.16.4

type OrmHandlerType[Row, Resp any] struct {
	Title           string
	Path            string
	Mode            libRequest.Type
	VerifyHeader    bool
	Key             string
	DbMode          libQuery.DBMode
	Command         libQuery.QueryCommand
	Translator      RowTranslator[Row, Resp]
	RecoveryHandler func(any)
	PaginateCommand func(string, libRequest.PaginationData) string
	Cache           bool
	CacheTime       time.Time
	CacheMaxAge     time.Duration
	CacheData       map[string][]Row
	OnEmpty200      bool
}

OrmHandlerType holds configuration for an ORM-based query handler.

func (OrmHandlerType[Row, Resp]) CacheKey added in v0.16.4

func (q OrmHandlerType[Row, Resp]) CacheKey(args []any) string

CacheKey builds a cache key from the handler title and arguments.

func (OrmHandlerType[Row, Resp]) CacheResult added in v0.16.4

func (q OrmHandlerType[Row, Resp]) CacheResult(args []any, rows []Row)

CacheResult stores rows in the cache under the key derived from the arguments.

func (OrmHandlerType[Row, Resp]) CheckCache added in v0.16.4

func (q OrmHandlerType[Row, Resp]) CheckCache(args []any) []Row

CheckCache returns cached rows for the given arguments if still valid.

func (OrmHandlerType[Req, Resp]) Finalizer added in v0.16.4

func (q OrmHandlerType[Req, Resp]) Finalizer(_ HandlerRequest[Req, Resp])

Finalizer is a no-op finalizer for the OrmHandlerType.

func (OrmHandlerType[Row, Resp]) Handler added in v0.16.4

func (q OrmHandlerType[Row, Resp]) Handler(req HandlerRequest[Row, Resp]) (Resp, error)

Handler executes the ORM query and translates the rows into the response.

func (OrmHandlerType[Row, Resp]) Initializer added in v0.16.4

func (q OrmHandlerType[Row, Resp]) Initializer(_ HandlerRequest[Row, Resp]) error

Initializer is a no-op initializer for the OrmHandlerType.

func (OrmHandlerType[Row, Resp]) Parameters added in v0.16.4

func (q OrmHandlerType[Row, Resp]) Parameters() HandlerParameters[Row, Resp]

Parameters returns the handler parameters for the OrmHandlerType.

func (OrmHandlerType[Req, Resp]) Simulation added in v0.16.4

func (q OrmHandlerType[Req, Resp]) Simulation(req HandlerRequest[Req, Resp]) (Resp, error)

Simulation returns the default response for simulation mode.

type QueryAllTransformer added in v0.10.25

type QueryAllTransformer[Row any, Resp []Row] struct {
}

QueryAllTransformer translates all query rows into a slice response.

func (QueryAllTransformer[Row, Resp]) Translate added in v0.10.25

func (s QueryAllTransformer[Row, Resp]) Translate(rows []Row, _ HandlerRequest[Row, Resp]) (QueryResp[Resp], error)

Translate wraps all rows into a slice response.

func (QueryAllTransformer[Row, Resp]) TranslateWithPaginate added in v0.11.0

func (s QueryAllTransformer[Row, Resp]) TranslateWithPaginate(rows []Row, _ HandlerRequest[Row, Resp], _ libRequest.PaginationData) (QueryResp[Resp], error)

TranslateWithPaginate wraps all rows into a slice response with pagination.

type QueryHandlerType added in v0.9.20

type QueryHandlerType[Row, Resp any] struct {
	Title           string
	Path            string
	Mode            libRequest.Type
	VerifyHeader    bool
	Key             string
	DbMode          libQuery.DBMode
	Command         libQuery.QueryCommand
	Translator      RowTranslator[Row, Resp]
	RecoveryHandler func(any)
	PaginateCommand func(string, libRequest.PaginationData) string
	Cache           bool
	CacheTime       time.Time
	CacheMaxAge     time.Duration
	CacheData       map[string][]Row
	OnEmpty200      bool
}

QueryHandlerType holds configuration for a database query handler.

func (QueryHandlerType[Row, Resp]) CacheKey added in v0.11.3

func (q QueryHandlerType[Row, Resp]) CacheKey(args []any) string

CacheKey builds a cache key from the handler title and arguments.

func (QueryHandlerType[Row, Resp]) CacheResult added in v0.11.3

func (q QueryHandlerType[Row, Resp]) CacheResult(args []any, rows []Row)

CacheResult stores rows in the cache under the key derived from the arguments.

func (QueryHandlerType[Row, Resp]) CheckCache added in v0.11.3

func (q QueryHandlerType[Row, Resp]) CheckCache(args []any) []Row

CheckCache returns cached rows for the given arguments if still valid.

func (QueryHandlerType[Req, Resp]) Finalizer added in v0.9.20

func (q QueryHandlerType[Req, Resp]) Finalizer(_ HandlerRequest[Req, Resp])

Finalizer is a no-op finalizer for the QueryHandlerType.

func (QueryHandlerType[Row, Resp]) Handler added in v0.9.20

func (q QueryHandlerType[Row, Resp]) Handler(req HandlerRequest[Row, Resp]) (Resp, error)

Handler executes the query and translates the rows into the response.

func (QueryHandlerType[Row, Resp]) Initializer added in v0.9.20

func (q QueryHandlerType[Row, Resp]) Initializer(_ HandlerRequest[Row, Resp]) error

Initializer is a no-op initializer for the QueryHandlerType.

func (QueryHandlerType[Row, Resp]) Parameters added in v0.9.20

func (q QueryHandlerType[Row, Resp]) Parameters() HandlerParameters[Row, Resp]

Parameters returns the handler parameters for the QueryHandlerType.

func (QueryHandlerType[Req, Resp]) Simulation added in v0.9.20

func (q QueryHandlerType[Req, Resp]) Simulation(req HandlerRequest[Req, Resp]) (Resp, error)

Simulation returns the default response for simulation mode.

type QueryResp added in v0.10.28

type QueryResp[Resp any] struct {
	TotalRows int
	Resp      Resp
}

QueryResp holds the total row count and the translated response for a query.

type QuerySingleTransformer added in v0.10.25

type QuerySingleTransformer[Row any, Resp []Row] struct {
}

QuerySingleTransformer translates a single-row query result into a one-element slice response.

func (QuerySingleTransformer[Row, Resp]) Translate added in v0.10.25

func (s QuerySingleTransformer[Row, Resp]) Translate(rows []Row, _ HandlerRequest[Row, Resp]) (QueryResp[Resp], error)

Translate wraps the first row into a single-element response.

func (QuerySingleTransformer[Row, Resp]) TranslateWithPaginate added in v0.11.0

func (s QuerySingleTransformer[Row, Resp]) TranslateWithPaginate(rows []Row, _ HandlerRequest[Row, Resp], _ libRequest.PaginationData) (QueryResp[Resp], error)

TranslateWithPaginate wraps the first row into a single-element response with pagination.

type RequestPersister added in v0.25.0

type RequestPersister[Req, Resp any] interface {
	Insert(path string, req *HandlerRequest[Req, Resp]) error
	Update(path string, req *HandlerRequest[Req, Resp]) error
}

RequestPersister optionally persists request lifecycle data for a handler. When HandlerParameters.Persistence is nil, insert/update are not called.

Insert must succeed before the handler runs; failure aborts the request. Update is best-effort after the response may have been sent; the framework logs errors only and does not retry.

type RowPaginator added in v0.11.0

type RowPaginator[Row any] struct {
	Less func(libRequest.PaginationData) func(i, j int) bool
}

RowPaginator provides a less function for sorting rows based on pagination data.

type RowTranslator added in v0.10.25

type RowTranslator[Row, Resp any] interface {
	Translate([]Row, HandlerRequest[Row, Resp]) (QueryResp[Resp], error)
	TranslateWithPaginate([]Row, HandlerRequest[Row, Resp], libRequest.PaginationData) (QueryResp[Resp], error)
}

RowTranslator is the interface for translating query rows into a response.

type WsResponse added in v0.9.7

type WsResponse[Result any] struct {
	HTTPStatus   int                      `json:"-"`
	HTTPHeaders  map[string]string        `json:"-"`
	Status       int                      `json:"status"`
	Description  string                   `json:"description"`
	Result       Result                   `json:"result,omitempty"`
	ErrorData    []response.ErrorResponse `json:"errors,omitempty"`
	PrintReceipt *response.Receipt        `json:"printReceipt,omitempty"`
}

WsResponse is the generic web-service response wrapper for remote API calls.

func (*WsResponse[any]) SetHeaders added in v0.9.57

func (w *WsResponse[any]) SetHeaders(headers map[string]string)

SetHeaders sets the HTTP headers on the response.

func (*WsResponse[any]) SetStatus added in v0.9.57

func (w *WsResponse[any]) SetStatus(status int)

SetStatus sets the HTTP status code on the response.

Jump to

Keyboard shortcuts

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