apiweaver

package module
v0.2.3 Latest Latest
Warning

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

Go to latest
Published: Dec 3, 2025 License: MIT Imports: 0 Imported by: 0

README

APIWeaver

Composable building blocks for resilient Go APIs: consistent responders, self-documenting info endpoints, and pragmatic health probes.

Table of Contents

Highlights

  • Functional options everywhere; wire only the collaborators you care about.
  • Shared Responder keeps JSON envelopes, trace IDs, and structured logs in sync across handlers.
  • InfoHandler exposes /status, /version, and /docs (with an embedded OpenAPI viewer) in just a few lines.
  • Probe adapters convert database/client checks into HTTP-friendly readiness handlers.
  • Lightweight helpers (jsonutil) wrap sonic for high-throughput encoding without sprinkling boilerplate through your code.

Packages at a Glance

Package What it solves
responder JSON rendering, error envelopes, request decoding, metadata + ULIDs.
info Status/version endpoints, OpenAPI + AsyncAPI JSON + HTML viewers, build metadata.
probe Ready-made checks for databases or custom closures wired to HTTP.
jsonutil Tiny helpers around sonic for fast (un)marshalling.
router ServeMux with OpenAPI validation, CORS, timeout, and logging defaults via functional options.

Each package can be imported independently, keeping binaries trim and focused.

Install

go get github.com/drblury/apiweaver/responder
go get github.com/drblury/apiweaver/info
go get github.com/drblury/apiweaver/probe
go get github.com/drblury/apiweaver/jsonutil
go get github.com/drblury/apiweaver/router

Requires Go 1.21+ (module declares 1.25) so you can rely on the latest stdlib improvements and generics.

Quick Start

import (
    "net/http"

    "github.com/drblury/apiweaver/info"
    "github.com/drblury/apiweaver/probe"
    "github.com/drblury/apiweaver/responder"
)

resp := responder.NewResponder(
    responder.WithLogger(logger),
    responder.WithStatusMetadata(http.StatusBadRequest, responder.Metadata{
        Level: "warn",
        Label: "validation",
    }),
)

infoHandler := info.NewInfoHandler(
    info.WithInfoResponder(resp),
    info.WithBaseURL("https://api.example.com"),
    info.WithUIType(info.UIScalar), // Choose your preferred OpenAPI UI
    info.WithInfoProvider(func() any {
        return map[string]string{
            "version": version,
            "commit":  commit,
        }
    }),
    info.WithSwaggerProvider(func() ([]byte, error) {
        return embeddedSpec, nil
    }),
    info.WithReadinessChecks(
        probe.NewMongoPingProbe(mongoClient, nil),
    ),
)

mux := http.NewServeMux()
mux.HandleFunc("/status", infoHandler.GetStatus)
mux.HandleFunc("/version", infoHandler.GetVersion)
mux.HandleFunc("/docs", infoHandler.GetOpenAPIHTML)
mux.HandleFunc("/openapi.json", infoHandler.GetOpenAPIJSON)

Share the same Responder anywhere you need consistent tracing metadata or error semantics (routers, middleware, background workers, etc.).

Examples

Every package now includes runnable Example* functions demonstrating typical and optional advanced integrations. Execute them directly via go test:

go test ./info     -run Example
go test ./jsonutil -run Example
go test ./responder -run Example
go test ./router   -run Example
go test ./probe    -run Example

Refer to the following table to jump into a concrete scenario:

Package Example Highlights
info Wires InfoHandler with custom base URL, swagger provider, and probes, then exercises /healthz + /version. Also demonstrates AsyncAPI support for event-driven APIs.
jsonutil Demonstrates struct marshal/unmarshal plus streaming Encode/Decode.
responder End-to-end handler showing request decoding, validation, custom error classification, and structured problem payloads.
router Builds a mux with OpenAPI validation, logger, tuned CORS, timeout, and prepend/append middlewares.
probe Covers generic ping probes plus configurable HTTP checks (status windows, request mutators, response validators) via NewHTTPProbe.

The examples double as documentation for go doc, so you can read and run them without scaffolding a separate binary.

Router

router.New wraps your generated handlers with a configurable middleware stack—OpenAPI validation, CORS, per-request timeouts, and structured logging are enabled by default and can be reordered or replaced via functional options.

swagger, _ := openapi3.NewLoader().LoadFromFile("./internal/server/_gen/openapi.json")

mux := router.New(
  generatedHandler,
  router.WithSwagger(swagger),
  router.WithLogger(logger),
  router.WithConfig(router.Config{
    Timeout: 5 * time.Second,
    CORS: router.CORSConfig{
      Origins: []string{"https://app.example.com"},
      Methods: []string{"GET", "POST"},
      Headers: []string{"Content-Type", "Authorization"},
      AllowCredentials: true,
    },
    QuietdownRoutes: []string{"/status"},
    HideHeaders:     []string{"Authorization"},
  }),
  router.WithMiddlewares(metricsMiddleware),
)

http.ListenAndServe(":8080", mux)

Additional helpers (router.WithTrailingMiddlewares, router.WithMiddlewareChain, router.Without*) make it easy to blend your own middleware with the built-in defaults.

Health, Docs & Probes

  • HTML docs: Multiple OpenAPI documentation UIs are supported out of the box:

    • Stoplight Elements (default): info/assets/stoplight.html
    • Scalar: Modern, interactive API documentation
    • SwaggerUI: The classic OpenAPI documentation tool
    • Redoc: Clean, responsive OpenAPI documentation

    Use info.WithUIType() to select your preferred UI (e.g., info.WithUIType(info.UIScalar)).

  • AsyncAPI docs: For event-driven APIs, AsyncAPI documentation is also supported:

    • Use info.WithAsyncAPIProvider() to supply your AsyncAPI spec
    • Use info.WithAsyncAPITemplate() for custom HTML templates
    • Use info.WithAsyncAPITemplateData() for custom template data
    • Default template uses AsyncAPI React Component
    • Use info.AsyncAPISpecURL(baseURL) helper to construct spec URLs
  • JSON docs: Provide a SwaggerProvider (or OpenAPIProvider) to serve the raw spec alongside the viewer.

  • Readiness/Liveness: Compose the built-in probes (probe package) or pass your own func(context.Context) error implementations. Failures are surfaced via the responder with correlation IDs intact.

  • Reverse proxies: set info.WithBaseURL so generated links point to the external host.

Tooling & Generation

  • task gen-api (from taskfile.yml) runs the Dockerised oapi-codegen pipeline described in generate.go to keep server stubs current.
  • Generated assets and the documentation viewer live under info/assets/ and are embedded so you can ship a single binary.

Development

# Run unit tests for every package
go test ./...

# Regenerate OpenAPI-based handlers and assets
task gen-api
  • Keep docs.go (this repo) updated as packages evolve so go doc stays helpful.
  • Pair info with your router package of choice for validation, logging, or other cross-cutting plugins.
  • Contributions welcome—open an issue or PR before making large changes.

Documentation

Overview

Package apiweaver bundles composable HTTP helpers for building well-instrumented Go services. The module stays intentionally small and encourages teams to pull in only the packages they need, keeping binaries lean and dependencies predictable.

The responder package centralises JSON rendering, structured errors, and trace-friendly metadata. The info package layers on status, version, and documentation endpoints along with an HTML viewer for your OpenAPI document. Probe helpers make it trivial to wire health checks for databases or bespoke functions into readiness/liveness routes, while jsonutil provides thin sonic wrappers for high-throughput encoding and decoding.

Packages

  • responder: consistent JSON success/error envelopes and structured logging hooks via functional options.
  • info: batteries-included health, version, and docs endpoints (including an embedded OpenAPI viewer and static assets).
  • probe: adapters that turn database ping functions or arbitrary closures into HTTP-friendly readiness checks.
  • jsonutil: tiny helpers around sonic for performance-sensitive encoding tasks.

Quick Start

resp := responder.NewResponder(responder.WithLogger(logger))
infoHandler := info.NewInfoHandler(
    info.WithInfoResponder(resp),
    info.WithBaseURL("https://api.example.com"),
    info.WithReadinessChecks(probe.NewMongoPingProbe(mongoClient, nil)),
)

mux := http.NewServeMux()
mux.HandleFunc("/status", infoHandler.GetStatus)
mux.HandleFunc("/version", infoHandler.GetVersion)
mux.HandleFunc("/docs", infoHandler.GetOpenAPIHTML)

Sharing the responder keeps JSON payloads, error envelopes, and trace IDs consistent. Additional options expose Swagger JSON, tweak the HTML template, or register extra readiness probes for bespoke dependencies.

Directories

Path Synopsis
Package info exposes build metadata, health probes, OpenAPI, and AsyncAPI endpoints.
Package info exposes build metadata, health probes, OpenAPI, and AsyncAPI endpoints.
Package jsonutil wraps sonic with ergonomic helpers.
Package jsonutil wraps sonic with ergonomic helpers.
Package probe converts database, HTTP, and custom ping functions into readiness/liveness helpers.
Package probe converts database, HTTP, and custom ping functions into readiness/liveness helpers.
Package responder centralises JSON rendering, request parsing, and structured error payloads.
Package responder centralises JSON rendering, request parsing, and structured error payloads.
Package router wraps http.ServeMux with OpenAPI validation, CORS, timeouts, and logging defaults.
Package router wraps http.ServeMux with OpenAPI validation, CORS, timeouts, and logging defaults.

Jump to

Keyboard shortcuts

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