Documentation
¶
Overview ¶
blocks/server/errors.go
blocks/server/http.go
blocks/server/lambda.go
blocks/server/middleware.go
blocks/server/options.go
blocks/server/router.go
blocks/server/tcp.go
blocks/server/types.go Package server provides inbound integration blocks that receive requests from AWS API Gateway (v1/v2), Application Load Balancer, or as a standalone HTTP server. All three transports normalize incoming events into the same *Request type and serialize *Response back to the appropriate wire format.
A single Handler function works unchanged across all three transports:
handler := func(ctx context.Context, req *server.Request) (*server.Response, error) {
return server.JSON(200, map[string]string{"hello": req.PathParam("id")}), nil
}
// Run as HTTP server
http := server.NewHTTP("api", server.WithPort(8080), server.WithRouter(router))
// Run as Lambda (API Gateway v2 / ALB)
fn := server.NewLambda("api", server.WithSource(server.SourceAPIGatewayV2), server.WithRouter(router))
Index ¶
- type CORSConfig
- type Conn
- type ConnHandler
- type HTTPBlock
- type Handler
- type LambdaBlock
- type Middleware
- type Option
- func WithHandler(h Handler) Option
- func WithIdleTimeout(d time.Duration) Option
- func WithMiddleware(middleware ...Middleware) Option
- func WithPort(port int) Option
- func WithReadTimeout(d time.Duration) Option
- func WithRouter(r *Router) Option
- func WithShutdownTimeout(d time.Duration) Option
- func WithSource(s Source) Option
- func WithTLS(certFile, keyFile string) Option
- func WithTLSConfig(cfg *tls.Config) Option
- func WithWriteTimeout(d time.Duration) Option
- type Request
- type Response
- type Router
- func (r *Router) DELETE(pattern string, h Handler, middleware ...Middleware)
- func (r *Router) GET(pattern string, h Handler, middleware ...Middleware)
- func (r *Router) HEAD(pattern string, h Handler, middleware ...Middleware)
- func (r *Router) Handle(method, pattern string, h Handler, middleware ...Middleware)
- func (r *Router) NotFound(h Handler)
- func (r *Router) OPTIONS(pattern string, h Handler, middleware ...Middleware)
- func (r *Router) PATCH(pattern string, h Handler, middleware ...Middleware)
- func (r *Router) POST(pattern string, h Handler, middleware ...Middleware)
- func (r *Router) PUT(pattern string, h Handler, middleware ...Middleware)
- func (r *Router) ServeHTTP(w http.ResponseWriter, httpReq *http.Request)
- func (r *Router) Use(middleware ...Middleware)
- type Source
- type TCPBlock
- type TCPOption
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CORSConfig ¶
type CORSConfig struct {
// AllowOrigins is the list of allowed origins.
// Use ["*"] to allow all origins.
AllowOrigins []string
// AllowMethods lists the HTTP methods allowed for cross-origin requests.
// Defaults to GET, POST, PUT, PATCH, DELETE, OPTIONS.
AllowMethods []string
// AllowHeaders lists additional headers the browser is allowed to send.
AllowHeaders []string
// ExposeHeaders lists headers the browser is allowed to read from the response.
ExposeHeaders []string
// AllowCredentials enables cookies and auth headers in cross-origin requests.
AllowCredentials bool
// MaxAge sets the preflight cache duration in seconds.
MaxAge int
}
CORSConfig configures the CORS middleware.
type Conn ¶
type Conn struct {
// contains filtered or unexported fields
}
Conn wraps a raw net.Conn and provides convenience methods for reading frames and writing responses.
func (*Conn) Read ¶
Read reads up to len(p) bytes into p from the connection. It is a direct pass-through to the underlying net.Conn.
func (*Conn) ReadMessage ¶
ReadMessage reads a single chunk of data up to the configured buffer size. Returns io.EOF when the client disconnects gracefully.
func (*Conn) RemoteAddr ¶
RemoteAddr returns the remote address string of the connection.
type ConnHandler ¶
ConnHandler is the function signature for handling a raw TCP connection. It is called in its own goroutine for each accepted connection and must return when the connection is done (either by the client disconnecting or when the context is cancelled).
handler := func(ctx context.Context, conn *server.Conn) {
for {
msg, err := conn.ReadMessage()
if err != nil { return }
fmt.Printf("[%s] %x\n", conn.RemoteAddr(), msg)
}
}
type HTTPBlock ¶
type HTTPBlock struct {
// contains filtered or unexported fields
}
HTTPBlock is a standalone HTTP server block. It listens on a configurable port and dispatches requests to the configured Router or Handler.
router := server.NewRouter()
router.GET("/health", func(ctx context.Context, req *server.Request) (*server.Response, error) {
return server.JSON(200, map[string]string{"status": "ok"}), nil
})
httpBlock := server.NewHTTP("api",
server.WithPort(8080),
server.WithRouter(router),
server.WithMiddleware(server.Logging(), server.Recovery()),
)
app.MustRegister(httpBlock)
app.InitAll(ctx) // starts listening
httpBlock.Wait() // blocks until Shutdown is called
func (*HTTPBlock) Init ¶
Init implements core.Block. It builds the http.Server and starts listening in a background goroutine. Returns immediately — call Wait to block until the server stops.
type Handler ¶
Handler is the universal request handler. Its signature is identical regardless of transport — API Gateway, ALB, or direct HTTP.
type LambdaBlock ¶
type LambdaBlock struct {
// contains filtered or unexported fields
}
LambdaBlock is a Lambda integration block that normalizes API Gateway (v1/v2) and ALB events into the universal *Request type and translates *Response back to the wire format expected by each event source.
router := server.NewRouter()
router.GET("/users/:id", getUserHandler)
router.POST("/users", createUserHandler)
fn := server.NewLambda("api",
server.WithSource(server.SourceAPIGatewayV2),
server.WithRouter(router),
server.WithMiddleware(server.Logging(), server.Recovery()),
)
app.MustRegister(fn)
app.InitAll(ctx)
fn.Start() // blocks — calls lambda.Start() internally
func NewLambda ¶
func NewLambda(name string, opts ...Option) *LambdaBlock
NewLambda creates a new Lambda block. WithSource is required — it determines how events are decoded and how responses are encoded.
func (*LambdaBlock) Init ¶
func (b *LambdaBlock) Init(_ context.Context) error
Init implements core.Block. It resolves the effective handler and validates that a source type has been configured.
func (*LambdaBlock) Shutdown ¶
func (b *LambdaBlock) Shutdown(_ context.Context) error
Shutdown implements core.Block. Lambda manages its own lifecycle; this is a no-op but satisfies the interface.
func (*LambdaBlock) Start ¶
func (b *LambdaBlock) Start()
Start registers the Lambda handler and begins polling the Lambda runtime. This call blocks until the Lambda execution environment shuts down. It must be called after app.InitAll.
app.InitAll(ctx) defer app.ShutdownAll(ctx) fn.Start() // hand control to the Lambda runtime
type Middleware ¶
Middleware wraps a Handler to form a processing chain. The pattern is identical to standard http.Handler middleware:
logging := func(next server.Handler) server.Handler {
return func(ctx context.Context, req *server.Request) (*server.Response, error) {
start := time.Now()
resp, err := next(ctx, req)
slog.Info("request", "method", req.Method, "path", req.Path,
"status", resp.StatusCode, "latency", time.Since(start))
return resp, err
}
}
func CORS ¶
func CORS(cfg CORSConfig) Middleware
CORS returns a Middleware that adds Cross-Origin Resource Sharing headers. Pass an empty CORSConfig{} to use permissive defaults suitable for development.
func Logging ¶
func Logging() Middleware
Logging returns a Middleware that logs each request using slog. It records method, path, status code, and latency at Info level. Errors returned by the handler are logged at Error level.
func Recovery ¶
func Recovery() Middleware
Recovery returns a Middleware that catches panics and converts them into HTTP 500 responses, preventing the entire process from crashing.
func RequestID ¶
func RequestID() Middleware
RequestID returns a Middleware that ensures every request has a request ID. It reads X-Request-Id from the incoming headers; if absent, it uses the transport-supplied ID (API Gateway / ALB request ID). The ID is propagated as X-Request-Id on the response.
type Option ¶
type Option func(*blockConfig)
Option configures a server block.
func WithHandler ¶
WithHandler sets a single Handler that receives every request. Use WithRouter instead when you need method/path routing.
func WithIdleTimeout ¶
WithIdleTimeout sets the maximum time to wait for the next keep-alive request. Defaults to 60 s.
func WithMiddleware ¶
func WithMiddleware(middleware ...Middleware) Option
WithMiddleware registers global middleware applied to every request before it reaches the router or handler. Declared in outermost-first order.
func WithReadTimeout ¶
WithReadTimeout sets the maximum duration for reading the full request. Defaults to 30 s.
func WithRouter ¶
WithRouter sets the Router used to dispatch incoming requests. Either WithRouter or WithHandler must be provided.
func WithShutdownTimeout ¶
WithShutdownTimeout sets the maximum time allowed for graceful shutdown. Defaults to 10 s.
func WithSource ¶
WithSource declares which Lambda event source the block expects. Required for Lambda blocks — must be one of SourceAPIGatewayV1, SourceAPIGatewayV2, or SourceALB.
func WithTLS ¶
WithTLS configures the server to use TLS with the given certificate and key files. Mutually exclusive with WithTLSConfig.
func WithTLSConfig ¶
WithTLSConfig injects a custom *tls.Config.
func WithWriteTimeout ¶
WithWriteTimeout sets the maximum duration for writing the full response. Defaults to 30 s.
type Request ¶
type Request struct {
// Method is the HTTP verb (GET, POST, PUT, PATCH, DELETE, …).
Method string
// Path is the raw URL path (e.g. "/users/123").
Path string
// PathParams holds named path parameters extracted by the Router.
// For the path pattern "/users/:id", PathParams["id"] == "123".
PathParams map[string]string
// Query holds the parsed query string parameters, potentially multi-valued.
Query map[string][]string
// Headers holds the request headers, normalised to lowercase keys.
Headers map[string]string
// Body is the raw request body bytes.
Body []byte
// SourceIP is the originating client IP address.
SourceIP string
// RequestID is a unique identifier for this request (from X-Request-Id,
// API Gateway requestId, or ALB traceId).
RequestID string
// Stage is the API Gateway deployment stage (e.g. "prod"). Empty for HTTP.
Stage string
// Source identifies the transport that delivered this request.
Source Source
// Raw holds the original transport-specific event for advanced use cases.
// For HTTP it is *http.Request; for Lambda it is the raw events struct.
Raw any
}
Request is the unified, transport-agnostic representation of an incoming HTTP request. It is populated identically regardless of whether the request arrived via API Gateway, ALB, or a direct HTTP connection.
func (*Request) Header ¶
Header returns the value of the named header (case-insensitive), or empty string.
func (*Request) PathParam ¶
PathParam returns the value of the named path parameter, or empty string.
func (*Request) QueryParam ¶
QueryParam returns the first value of the named query parameter, or empty string.
type Response ¶
type Response struct {
// StatusCode is the HTTP status code.
StatusCode int
// Headers are added to the response alongside any transport defaults.
Headers map[string]string
// Body is the response payload.
// string and []byte are sent as-is; anything else is JSON-marshalled.
Body any
// IsBase64 signals that Body is a base64-encoded binary payload.
// Only relevant for Lambda transports.
IsBase64 bool
}
Response is the unified outgoing response. The server block serializes it to the appropriate wire format for the active transport.
func JSON ¶
JSON returns a Response with the given status code and a JSON-marshalled body. Content-Type is set to application/json automatically.
func NoContent ¶
func NoContent() *Response
NoContent returns a 204 No Content response with no body.
type Router ¶
type Router struct {
// contains filtered or unexported fields
}
Router dispatches incoming requests to registered handlers based on HTTP method and path pattern. Path patterns support named segments (:param) and a catch-all wildcard (*).
r := server.NewRouter()
r.GET("/users", listUsersHandler)
r.POST("/users", createUserHandler)
r.GET("/users/:id", getUserHandler)
r.PUT("/users/:id", updateUserHandler)
r.DELETE("/users/:id", deleteUserHandler)
Middleware can be applied per-route or globally via Use:
r.Use(loggingMiddleware, authMiddleware)
r.GET("/admin", adminHandler, adminOnlyMiddleware)
func NewRouter ¶
func NewRouter() *Router
NewRouter creates an empty Router. The default not-found handler returns 404 with a JSON error body.
func (*Router) DELETE ¶
func (r *Router) DELETE(pattern string, h Handler, middleware ...Middleware)
DELETE registers a handler for DELETE requests.
func (*Router) GET ¶
func (r *Router) GET(pattern string, h Handler, middleware ...Middleware)
GET registers a handler for GET requests.
func (*Router) HEAD ¶
func (r *Router) HEAD(pattern string, h Handler, middleware ...Middleware)
HEAD registers a handler for HEAD requests.
func (*Router) Handle ¶
func (r *Router) Handle(method, pattern string, h Handler, middleware ...Middleware)
Handle registers a handler for the given method and path pattern. method is the uppercase HTTP verb; pass "" to match any method. Per-route middleware is applied inside the global middleware chain.
func (*Router) OPTIONS ¶
func (r *Router) OPTIONS(pattern string, h Handler, middleware ...Middleware)
OPTIONS registers a handler for OPTIONS requests.
func (*Router) PATCH ¶
func (r *Router) PATCH(pattern string, h Handler, middleware ...Middleware)
PATCH registers a handler for PATCH requests.
func (*Router) POST ¶
func (r *Router) POST(pattern string, h Handler, middleware ...Middleware)
POST registers a handler for POST requests.
func (*Router) PUT ¶
func (r *Router) PUT(pattern string, h Handler, middleware ...Middleware)
PUT registers a handler for PUT requests.
func (*Router) ServeHTTP ¶
func (r *Router) ServeHTTP(w http.ResponseWriter, httpReq *http.Request)
ServeHTTP adapts the Router to net/http.Handler, bridging the HTTP server block with the universal Handler interface.
func (*Router) Use ¶
func (r *Router) Use(middleware ...Middleware)
Use registers middleware applied to every route in this router. Middleware is applied in declaration order (outermost first).
type Source ¶
type Source string
Source identifies the transport that delivered a request.
const ( // SourceHTTP identifies a request received directly via the HTTP server block. SourceHTTP Source = "http" // SourceAPIGatewayV1 identifies an AWS API Gateway REST API (v1) event. SourceAPIGatewayV1 Source = "apigateway_v1" // SourceAPIGatewayV2 identifies an AWS API Gateway HTTP API (v2) event. SourceAPIGatewayV2 Source = "apigateway_v2" // SourceALB identifies an AWS Application Load Balancer target group event. SourceALB Source = "alb" )
type TCPBlock ¶
type TCPBlock struct {
// contains filtered or unexported fields
}
TCPBlock is a raw TCP server block. It listens on a configurable port and dispatches each accepted connection to the registered ConnHandler in its own goroutine.
handler := func(ctx context.Context, conn *server.Conn) {
defer conn.Close()
for {
msg, err := conn.ReadMessage()
if err != nil { return }
// process msg...
}
}
tcp := server.NewTCP("tracker",
server.WithTCPPort(5001),
server.WithConnHandler(handler),
server.WithBufSize(1024),
)
app.MustRegister(tcp)
app.InitAll(ctx)
tcp.Wait()
func NewTCP ¶
NewTCP creates a new TCP server block.
tcp := server.NewTCP("obd-tracker",
server.WithTCPPort(5001),
server.WithConnHandler(myHandler),
server.WithBufSize(2048),
server.WithConnReadTimeout(5*time.Minute),
)
func (*TCPBlock) Init ¶
Init implements core.Block. It opens the TCP listener and starts the accept loop in a background goroutine. Returns immediately.
type TCPOption ¶
type TCPOption func(*tcpConfig)
TCPOption configures a TCPBlock.
func WithBufSize ¶
WithBufSize sets the default buffer size for ReadMessage. Defaults to 1024 bytes.
func WithConnHandler ¶
func WithConnHandler(h ConnHandler) TCPOption
WithConnHandler sets the function called for each accepted connection. Required — Init returns an error if not provided.
func WithConnReadTimeout ¶
WithConnReadTimeout sets a per-read deadline on each connection. 0 means no deadline (default).
func WithConnWriteTimeout ¶
WithConnWriteTimeout sets a per-write deadline on each connection.
func WithTCPPort ¶
WithTCPPort sets the TCP port to listen on. Defaults to 5001.
func WithTCPShutdownTimeout ¶
WithTCPShutdownTimeout sets the maximum time to wait for active connections to finish before forcing close. Defaults to 10 s.