Documentation
¶
Overview ¶
Package endpoint provides type-safe HTTP endpoint definitions and handlers.
This package is the core of pureapi-core, offering generic endpoint handlers with compile-time type safety, middleware composition, and structured error handling. It provides a generic endpoint pipeline that transforms HTTP handlers from error-prone manual parsing to type-safe, composable functions.
Example:
type UserRequest struct {
Name string `json:"name"`
Email string `json:"email"`
}
type UserResponse struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
// Input handler: parse JSON request body
inputHandler := inputJSON[UserRequest]()
// Business logic: create user
businessLogic := func(ctx context.Context, req UserRequest) (UserResponse, error) {
// Your business logic here
return UserResponse{ID: 1, Name: req.Name, Email: req.Email}, nil
}
// Error handler: map errors to HTTP responses
errorHandler := func(err error) (int, string) {
return http.StatusInternalServerError, "Internal server error"
}
// Output handler: write JSON response
outputHandler := outputJSON[UserResponse]()
// Create the endpoint handler
handler := NewHandler(inputHandler, businessLogic, errorHandler, outputHandler)
// Use with your HTTP server
http.HandleFunc("/users", handler.ServeHTTP)
Index ¶
- Constants
- func EventWithRequestID(eventType event.EventType, requestID string, data map[string]any) event.Event
- func RequestIDFromContext(ctx context.Context) string
- func RequestIDFromRequest(r *http.Request) string
- type DefaultEndpoint
- func (e *DefaultEndpoint) Handler() http.HandlerFunc
- func (e *DefaultEndpoint) Method() string
- func (e *DefaultEndpoint) Middlewares() Middlewares
- func (e *DefaultEndpoint) URL() string
- func (e *DefaultEndpoint) WithHandler(handler http.HandlerFunc) Endpoint
- func (e *DefaultEndpoint) WithMethod(method string) Endpoint
- func (e *DefaultEndpoint) WithMiddlewares(middlewares Middlewares) Endpoint
- func (e *DefaultEndpoint) WithURL(url string) Endpoint
- type DefaultErrorHandler
- type DefaultHandler
- func (h *DefaultHandler[Input]) Handle(w http.ResponseWriter, r *http.Request)
- func (h *DefaultHandler[Input]) WithEmitterLogger(emitterLogger event.EventEmitter) *DefaultHandler[Input]
- func (h *DefaultHandler[Input]) WithErrorHandler(errorHandler ErrorHandler) *DefaultHandler[Input]
- func (h *DefaultHandler[Input]) WithHandlerLogicFn(handlerLogicFn HandlerLogicFn[Input]) *DefaultHandler[Input]
- func (h *DefaultHandler[Input]) WithInputHandler(inputHandler InputHandler[Input]) *DefaultHandler[Input]
- type DefaultMiddlewares
- type DefaultStack
- func (s *DefaultStack) AddWrapper(w Wrapper) Stack
- func (s *DefaultStack) Clone() Stack
- func (s *DefaultStack) InsertAfter(id string, w Wrapper) (Stack, bool)
- func (s *DefaultStack) InsertBefore(id string, w Wrapper) (Stack, bool)
- func (s *DefaultStack) Middlewares() Middlewares
- func (s *DefaultStack) Remove(id string) (Stack, bool)
- func (s *DefaultStack) Wrappers() []Wrapper
- type DefaultWrapper
- type Endpoint
- type EndpointSpec
- type ErrorHandler
- type Handler
- type HandlerLogicFn
- type InputHandler
- type Middleware
- type Middlewares
- type OutputHandler
- type RequestIDKey
- type SimpleEndpointSpec
- type Stack
- type Wrapper
Constants ¶
const ( // EventError is emitted when an error occurs during request processing. EventError event.EventType = "event_error" // EventOutputError event is emitted when an output error occurs. EventOutputError event.EventType = "event_output_error" )
Constants for event event.
Variables ¶
This section is empty.
Functions ¶
func EventWithRequestID ¶ added in v1.0.0
func EventWithRequestID(eventType event.EventType, requestID string, data map[string]any) event.Event
EventWithRequestID creates an event with request ID included in the data.
func RequestIDFromContext ¶ added in v1.0.0
RequestIDFromContext extracts the request ID from the context.
func RequestIDFromRequest ¶ added in v1.0.0
RequestIDFromRequest extracts the request ID from the request context.
Types ¶
type DefaultEndpoint ¶
type DefaultEndpoint struct {
URLVal string
MethodVal string
MiddlewaresVal Middlewares
HandlerVal http.HandlerFunc // Optional handler for the endpoint.
}
DefaultEndpoint represents an API endpoint with middlewares.
func NewEndpoint ¶
func NewEndpoint(url string, method string) *DefaultEndpoint
NewEndpoint creates a new DefaultEndpoint with the given details.
Parameters:
- url: The URL of the endpoint.
- method: The HTTP method of the endpoint.
Returns:
- *DefaultEndpoint: A new DefaultEndpoint instance.
func (*DefaultEndpoint) Handler ¶
func (e *DefaultEndpoint) Handler() http.HandlerFunc
Handler returns the handler of the endpoint.
Returns:
- http.HandlerFunc: The handler of the endpoint.
func (*DefaultEndpoint) Method ¶
func (e *DefaultEndpoint) Method() string
Method returns the HTTP method of the endpoint.
Returns:
- string: The HTTP method of the endpoint.
func (*DefaultEndpoint) Middlewares ¶
func (e *DefaultEndpoint) Middlewares() Middlewares
Middlewares returns the middlewares of the endpoint. If no middlewares are set, it returns an empty Middlewares instance.
Returns:
- Middlewares: The middlewares of the endpoint.
func (*DefaultEndpoint) URL ¶
func (e *DefaultEndpoint) URL() string
URL returns the URL of the endpoint.
Returns:
- string: The URL of the endpoint.
func (*DefaultEndpoint) WithHandler ¶
func (e *DefaultEndpoint) WithHandler(handler http.HandlerFunc) Endpoint
WithHandler sets the handler for the endpoint. It returns a new endpoint.
Parameters:
- handler: The handler for the endpoint.
Returns:
- Endpoint: A new Endpoint.
func (*DefaultEndpoint) WithMethod ¶
func (e *DefaultEndpoint) WithMethod(method string) Endpoint
WithMethod sets the method of the endpoint. It returns a new endpoint.
Parameters:
- method: The method of the endpoint.
Returns:
- Endpoint: A new Endpoint.
func (*DefaultEndpoint) WithMiddlewares ¶
func (e *DefaultEndpoint) WithMiddlewares(middlewares Middlewares) Endpoint
WithMiddlewares sets the middlewares for the endpoint. It returns a new endpoint.
Parameters:
- middlewares: The middlewares to apply to the endpoint.
Returns:
- Endpoint: A new Endpoint.
func (*DefaultEndpoint) WithURL ¶
func (e *DefaultEndpoint) WithURL(url string) Endpoint
WithURL sets the URL of the endpoint. It returns a new endpoint.
Parameters:
- url: The URL of the endpoint.
Returns:
- Endpoint: A new Endpoint.
type DefaultErrorHandler ¶ added in v1.0.0
type DefaultErrorHandler struct{}
DefaultErrorHandler provides a sensible default error mapping.
type DefaultHandler ¶
type DefaultHandler[Input any] struct { // contains filtered or unexported fields }
DefaultHandler represents an endpoint with input, business logic, and output.
func NewHandler ¶
func NewHandler[Input any]( inputHandler InputHandler[Input], handlerLogicFn HandlerLogicFn[Input], errorHandler ErrorHandler, outputHandler OutputHandler, ) *DefaultHandler[Input]
NewHandler creates a new handler. During request handling it executes common endpoints logic. It calls the input handler, handler logic, and output handler. If an error occurs during output handling, it will write a 500 error.
Parameters:
- inputHandler: The input handler for processing request input.
- handlerLogicFn: The handler logic function for business logic.
- errorHandler: The error handler for mapping errors to API responses.
- outputHandler: The output handler for writing responses.
Returns:
- *DefaultHandler[Input]: A new DefaultHandler instance.
func (*DefaultHandler[Input]) Handle ¶
func (h *DefaultHandler[Input]) Handle( w http.ResponseWriter, r *http.Request, )
Handle executes common endpoints logic. It calls the input handler, handler logic, and output handler.
Parameters:
- w: The HTTP response writer.
- r: The HTTP request.
func (*DefaultHandler[Input]) WithEmitterLogger ¶
func (h *DefaultHandler[Input]) WithEmitterLogger( emitterLogger event.EventEmitter, ) *DefaultHandler[Input]
WithEmitterLogger adds an emitter logger to the handler and returns a new handler instance.
Parameters:
- emitterLogger: The emitter logger to set.
Returns:
- *DefaultHandler[Input]: A new handler instance.
func (*DefaultHandler[Input]) WithErrorHandler ¶
func (h *DefaultHandler[Input]) WithErrorHandler( errorHandler ErrorHandler, ) *DefaultHandler[Input]
WithErrorHandler adds an error handler to the handler and returns a new handler instance.
Parameters:
- errorHandler: The error handler to set.
Returns:
- *DefaultHandler[Input]: A new handler instance.
func (*DefaultHandler[Input]) WithHandlerLogicFn ¶
func (h *DefaultHandler[Input]) WithHandlerLogicFn( handlerLogicFn HandlerLogicFn[Input], ) *DefaultHandler[Input]
WithHandlerLogicFn adds a handler logic function to the handler and returns a new handler instance.
Parameters:
- handlerLogicFn: The handler logic function to set.
Returns:
- *DefaultHandler[Input]: A new handler instance.
func (*DefaultHandler[Input]) WithInputHandler ¶
func (h *DefaultHandler[Input]) WithInputHandler( inputHandler InputHandler[Input], ) *DefaultHandler[Input]
WithInputHandler adds an input handler to the handler and returns a new handler instance.
Parameters:
- inputHandler: The input handler to set.
Returns:
- *DefaultHandler[Input]: A new handler instance.
type DefaultMiddlewares ¶
type DefaultMiddlewares struct {
// contains filtered or unexported fields
}
DefaultMiddlewares is an immutable slice of Middleware functions. All methods return new instances; the original is never modified.
func NewMiddlewares ¶
func NewMiddlewares(middlewares ...Middleware) *DefaultMiddlewares
NewMiddlewares creates a new DefaultMiddlewares instance with the provided middlewares.
Parameters:
- middlewares: The middlewares to add to the list.
Returns:
- *DefaultMiddlewares: A new DefaultMiddlewares instance.
func (DefaultMiddlewares) Chain ¶
func (m DefaultMiddlewares) Chain(h http.Handler) http.Handler
Chain applies a sequence of middlewares to an http.Handler. During a request the middlewaress are applied in the order they are provided. The middlewares are applied so that the first middleware in the list becomes the outermost wrapper.
Example with middlewares m1, m2
Chain(finalHandler) yields m1(m2(finalHandler)).
Parameters:
- h: The http.Handler to wrap.
Returns:
- http.Handler: The wrapped http.Handler.
func (DefaultMiddlewares) Middlewares ¶
func (m DefaultMiddlewares) Middlewares() []Middleware
Middlewares returns the middlewares in the list.
Returns:
- []Middleware: The middlewares in the list.
func (DefaultMiddlewares) WithAdded ¶ added in v1.0.0
func (m DefaultMiddlewares) WithAdded( middlewares ...Middleware, ) *DefaultMiddlewares
WithAdded adds one or more middlewares to the list and returns a new DefaultMiddlewares instance. The original instance is unchanged.
Parameters:
- middlewares: The middlewares to add to the list.
Returns:
- *DefaultMiddlewares: A new DefaultMiddlewares instance with the added middlewares.
type DefaultStack ¶
type DefaultStack struct {
// contains filtered or unexported fields
}
DefaultStack manages a list of middleware wrappers with concurrency safety for editing the list.
func NewStack ¶
func NewStack(wrappers ...Wrapper) *DefaultStack
NewStack creates and returns an initialized DefaultStack.
Parameters:
- wrappers: The initial list of middleware wrappers.
Returns:
- *DefaultStack: A new DefaultStack instance.
func (*DefaultStack) AddWrapper ¶
func (s *DefaultStack) AddWrapper(w Wrapper) Stack
Add appends a new middleware Wrapper to the stack and returns the stack for chaining.
Parameters:
- w: The wrapper to add.
Returns:
- *Stack: The updated middleware stack.
func (*DefaultStack) Clone ¶
func (s *DefaultStack) Clone() Stack
Clone creates a deep copy of the Stack.
Returns:
- *Stack: The cloned middleware stack.
func (*DefaultStack) InsertAfter ¶
func (s *DefaultStack) InsertAfter( id string, w Wrapper, ) (Stack, bool)
InsertAfter inserts a middleware Wrapper after the one with the specified ID. Returns true if a matching wrapper was found and insertion happened after it. If no match is found, the new wrapper is **appended to the end** and false is returned.
Parameters:
- id: The ID of the wrapper to insert after.
- w: The wrapper to insert.
Returns:
- *Stack: The updated middleware stack.
- bool: True if a matching wrapper was found and insertion succeeded.
func (*DefaultStack) InsertBefore ¶
func (s *DefaultStack) InsertBefore( id string, w Wrapper, ) (Stack, bool)
InsertBefore inserts a middleware Wrapper before the one with the specified ID. Returns true if a matching wrapper was found and insertion happened before it; if no match is found, the new wrapper is **appended to the end** and false is returned.
Parameters:
- id: The ID of the wrapper to insert before.
- w: The wrapper to insert.
Returns:
- *Stack: The updated middleware stack.
- bool: True if a matching wrapper was found and insertion succeeded.
func (*DefaultStack) Middlewares ¶
func (s *DefaultStack) Middlewares() Middlewares
Middlewares returns the middlewares in the stack.
Returns:
- Middlewares: The list of middlewares in the stack.
func (*DefaultStack) Remove ¶
func (s *DefaultStack) Remove(id string) (Stack, bool)
Remove deletes the middleware Wrapper with the specified ID from the stack. Returns true if the middleware was found and removed; false otherwise.
Parameters:
- id: The ID of the wrapper to remove.
Returns:
- *Stack: The updated middleware stack.
- bool: True if the middleware was found and removed; false otherwise.
func (*DefaultStack) Wrappers ¶
func (s *DefaultStack) Wrappers() []Wrapper
Wrappers returns the list of middleware wrappers in the stack.
Returns:
- []Wrapper: The list of middleware wrappers in the stack.
type DefaultWrapper ¶
type DefaultWrapper struct {
// contains filtered or unexported fields
}
DefaultWrapper encapsulates a middleware with an identifier and optional metadata. ID can be used to identify the middleware type (e.g. for reordering or documentation). Data can carry any type of additional information.
func NewWrapper ¶
func NewWrapper( id string, middleware Middleware, ) *DefaultWrapper
NewWrapper creates a new middleware DefaultWrapper.
Parameters:
- id: The ID of the wrapper.
- middleware: The middleware to wrap.
Returns:
- *DefaultWrapper: A new DefaultWrapper instance.
func (*DefaultWrapper) Data ¶
func (m *DefaultWrapper) Data() any
Data returns the data attached to the wrapper.
Returns:
- any: The data attached to the wrapper.
func (*DefaultWrapper) ID ¶
func (m *DefaultWrapper) ID() string
ID returns the ID of the wrapper.
Returns:
- string: The ID of the wrapper.
func (*DefaultWrapper) Middleware ¶
func (m *DefaultWrapper) Middleware() Middleware
Middleware returns the middleware wrapped by this wrapper.
Returns:
- Middleware: The wrapped middleware.
func (*DefaultWrapper) WithData ¶
func (m *DefaultWrapper) WithData(data any) *DefaultWrapper
WithData returns a new DefaultWrapper with the given data.
Parameters:
- data: The data to attach to the wrapper.
Returns:
- *DefaultWrapper: A new DefaultWrapper instance.
type Endpoint ¶
type Endpoint interface {
URL() string
Method() string
Middlewares() Middlewares
Handler() http.HandlerFunc
WithURL(string) Endpoint
WithMethod(string) Endpoint
WithMiddlewares(Middlewares) Endpoint
WithHandler(http.HandlerFunc) Endpoint
}
Endpoint represents an API endpoint with middlewares.
func ToEndpoints ¶ added in v1.0.0
func ToEndpoints(specs ...EndpointSpec) []Endpoint
ToEndpoints converts a list of endpoint specifications to a list of API endpoints. This is a simple helper function that replaces the Definition interface.
Parameters:
- specs: The endpoint specifications to convert.
Returns:
- []Endpoint: A list of API endpoints.
type EndpointSpec ¶ added in v1.0.0
type EndpointSpec interface {
ToEndpoint() Endpoint
}
EndpointSpec represents a specification for creating an endpoint.
type ErrorHandler ¶
ErrorHandler handles apierror and maps them to appropriate HTTP responses.
type Handler ¶
type Handler[Input any] interface { Handle(w http.ResponseWriter, r *http.Request) }
Handler is an interface for handling endpoints.
type HandlerLogicFn ¶
type HandlerLogicFn[Input any] func( w http.ResponseWriter, r *http.Request, i *Input, ) (any, error)
HandlerLogicFn is a function for handling endpoint logic.
type InputHandler ¶
type InputHandler[Input any] interface { Handle(w http.ResponseWriter, r *http.Request) (*Input, error) }
InputHandler defines how to process the request input.
type Middleware ¶
Middleware represents a function that wraps an http.Handler with additional behavior. A Middleware typically performs actions before and/or after calling the next handler.
Example:
finalHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// final processing
})
wrappedHandler := Apply(finalHandler, middleware1, middleware2)
func RequestIDMiddleware ¶ added in v1.0.0
func RequestIDMiddleware() Middleware
RequestIDMiddleware creates a middleware that injects a request ID into the context and response headers, and includes it in emitted events.
type Middlewares ¶
Middlewares is a collection of Middleware functions.
type OutputHandler ¶
type OutputHandler interface {
Handle(
w http.ResponseWriter,
r *http.Request,
out any,
outputError error,
statusCode int,
) error
}
OutputHandler processes and writes the endpoint response.
type RequestIDKey ¶ added in v1.0.0
type RequestIDKey struct{}
RequestIDKey is the context key for request ID.
type SimpleEndpointSpec ¶ added in v1.0.0
type SimpleEndpointSpec struct {
URLVal string
MethodVal string
MiddlewaresVal Middlewares
HandlerVal http.HandlerFunc
}
SimpleEndpointSpec is a simple implementation of EndpointSpec.
func NewEndpointSpec ¶ added in v1.0.0
func NewEndpointSpec(url, method string, middlewares Middlewares, handler http.HandlerFunc) *SimpleEndpointSpec
NewEndpointSpec creates a new endpoint specification.
func (*SimpleEndpointSpec) ToEndpoint ¶ added in v1.0.0
func (s *SimpleEndpointSpec) ToEndpoint() Endpoint
ToEndpoint converts the specification to an Endpoint.
type Stack ¶
type Stack interface {
Wrappers() []Wrapper
Middlewares() Middlewares
Clone() Stack
AddWrapper(w Wrapper) Stack
InsertBefore(id string, w Wrapper) (Stack, bool)
InsertAfter(id string, w Wrapper) (Stack, bool)
Remove(id string) (Stack, bool)
}
Stack is an interface for managing a list of middleware wrappers.
type Wrapper ¶
type Wrapper interface {
ID() string
Middleware() Middleware
Data() any
}
Wrapper is an interface for a middleware wrapper. It encapsulates a Middleware with an identifier and optional metadata.