Documentation
¶
Overview ¶
Package info exposes build metadata, health probes, OpenAPI, and AsyncAPI endpoints.
The package includes support for multiple OpenAPI documentation UIs:
- Stoplight Elements (default)
- Scalar
- SwaggerUI
- Redoc
Use WithUIType to select your preferred UI when creating an InfoHandler.
For event-driven APIs, the package also supports AsyncAPI documentation:
- Use WithAsyncAPIProvider to supply the AsyncAPI spec
- Use WithAsyncAPITemplate for custom HTML templates
- Use WithAsyncAPITemplateData for custom template data
- The default template uses AsyncAPI React Component
See ExampleInfoHandler_full for a runnable wiring of the handler and probes, ExampleInfoHandler_differentUITypes for examples of using different OpenAPI UIs, and ExampleInfoHandler_asyncAPI for AsyncAPI documentation examples.
Index ¶
- func AsyncAPISpecURL(baseURL string) string
- type AsyncAPIProvider
- type AsyncAPITemplateDataProvider
- type InfoHandler
- func (ih *InfoHandler) GetAsyncAPIHTML(w http.ResponseWriter, r *http.Request)
- func (ih *InfoHandler) GetAsyncAPIJSON(w http.ResponseWriter, r *http.Request)
- func (ih *InfoHandler) GetHealthz(w http.ResponseWriter, r *http.Request)
- func (ih *InfoHandler) GetOpenAPIHTML(w http.ResponseWriter, r *http.Request)
- func (ih *InfoHandler) GetOpenAPIJSON(w http.ResponseWriter, r *http.Request)
- func (ih *InfoHandler) GetReadyz(w http.ResponseWriter, r *http.Request)
- func (ih *InfoHandler) GetStatus(w http.ResponseWriter, r *http.Request)
- func (ih *InfoHandler) GetVersion(w http.ResponseWriter, r *http.Request)
- type InfoOption
- func WithAsyncAPIProvider(provider AsyncAPIProvider) InfoOption
- func WithAsyncAPITemplate(tmpl *template.Template) InfoOption
- func WithAsyncAPITemplateData(provider AsyncAPITemplateDataProvider) InfoOption
- func WithBaseURL(baseURL string) InfoOption
- func WithInfoProvider(provider InfoProvider) InfoOption
- func WithInfoResponder(responder *responder.Responder) InfoOption
- func WithLivenessChecks(checks ...ProbeFunc) InfoOption
- func WithOpenAPITemplate(tmpl *template.Template) InfoOption
- func WithOpenAPITemplateData(provider TemplateDataProvider) InfoOption
- func WithProbeTimeout(timeout time.Duration) InfoOption
- func WithReadinessChecks(checks ...ProbeFunc) InfoOption
- func WithSwaggerProvider(provider SwaggerProvider) InfoOption
- func WithUIType(uiType UIType) InfoOption
- type InfoProvider
- type ProbeFunc
- type SwaggerProvider
- type TemplateDataProvider
- type UIType
Examples ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func AsyncAPISpecURL ¶ added in v0.2.3
AsyncAPISpecURL returns the URL path where the AsyncAPI JSON spec is served. This helper can be used to construct links to the AsyncAPI documentation.
Types ¶
type AsyncAPIProvider ¶ added in v0.2.3
AsyncAPIProvider returns the raw AsyncAPI document that should be rendered by the AsyncAPI documentation endpoints. It is commonly backed by an embedded JSON or YAML file generated at build time.
type AsyncAPITemplateDataProvider ¶ added in v0.2.3
AsyncAPITemplateDataProvider allows callers to customise the data payload passed to the AsyncAPI HTML template at render time.
type InfoHandler ¶
InfoHandler wires the generated OpenAPI handlers with auxiliary endpoints that expose build information, status checks, and a pre-built HTML UI.
Example (AsyncAPI) ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"github.com/drblury/apiweaver/info"
)
func main() {
handler := info.NewInfoHandler(
info.WithBaseURL("https://events.example.com"),
info.WithAsyncAPIProvider(func() ([]byte, error) {
return []byte(`{"asyncapi":"3.0.0","info":{"title":"Events API","version":"1.0.0"}}`), nil
}),
)
// Test AsyncAPI JSON endpoint
jsonRec := httptest.NewRecorder()
handler.GetAsyncAPIJSON(jsonRec, httptest.NewRequest(http.MethodGet, "/info/asyncapi.json", nil))
fmt.Println("JSON:", jsonRec.Code)
fmt.Println(strings.TrimSpace(jsonRec.Body.String()))
// Test AsyncAPI HTML endpoint
htmlRec := httptest.NewRecorder()
handler.GetAsyncAPIHTML(htmlRec, httptest.NewRequest(http.MethodGet, "/info/asyncapi.html", nil))
fmt.Println("HTML:", htmlRec.Code, strings.Contains(htmlRec.Body.String(), "@asyncapi/react-component"))
// Use the helper function to get the spec URL
fmt.Println("Spec URL:", info.AsyncAPISpecURL("https://events.example.com"))
}
Output: JSON: 200 {"asyncapi":"3.0.0","info":{"title":"Events API","version":"1.0.0"}} HTML: 200 true Spec URL: https://events.example.com/info/asyncapi.json
Example (AsyncAPICustomTemplate) ¶
package main
import (
"fmt"
"html/template"
"net/http"
"net/http/httptest"
"strings"
"github.com/drblury/apiweaver/info"
)
func main() {
handler := info.NewInfoHandler(
info.WithBaseURL("https://events.example.com"),
info.WithAsyncAPITemplate(template.Must(template.New("events").Parse(`<div>{{.EventsURL}}</div>`))),
info.WithAsyncAPITemplateData(func(r *http.Request, baseURL string) any {
return map[string]string{
"EventsURL": baseURL + "/info/asyncapi.json",
}
}),
)
req := httptest.NewRequest(http.MethodGet, "/asyncapi", nil)
rr := httptest.NewRecorder()
handler.GetAsyncAPIHTML(rr, req)
fmt.Println(rr.Code)
fmt.Println(strings.TrimSpace(rr.Body.String()))
}
Output: 200 <div>https://events.example.com/info/asyncapi.json</div>
Example (CustomTemplate) ¶
package main
import (
"fmt"
"html/template"
"net/http"
"net/http/httptest"
"strings"
"github.com/drblury/apiweaver/info"
)
func main() {
handler := info.NewInfoHandler(
info.WithBaseURL("https://api.example.com"),
info.WithOpenAPITemplate(template.Must(template.New("docs").Parse(`<div>{{.DocsURL}}</div>`))),
info.WithOpenAPITemplateData(func(r *http.Request, baseURL string) any {
return map[string]string{
"DocsURL": baseURL + "/info/openapi.json",
}
}),
)
req := httptest.NewRequest(http.MethodGet, "/docs", nil)
rr := httptest.NewRecorder()
handler.GetOpenAPIHTML(rr, req)
fmt.Println(rr.Code)
fmt.Println(strings.TrimSpace(rr.Body.String()))
}
Output: 200 <div>https://api.example.com/info/openapi.json</div>
Example (DifferentUITypes) ¶
package main
import (
"fmt"
"net/http"
"net/http/httptest"
"strings"
"github.com/drblury/apiweaver/info"
)
func main() {
// Create handlers with different UI types
handlerScalar := info.NewInfoHandler(
info.WithBaseURL("https://api.example.com"),
info.WithUIType(info.UIScalar),
info.WithSwaggerProvider(func() ([]byte, error) {
return []byte(`{"openapi":"3.1.0"}`), nil
}),
)
handlerSwaggerUI := info.NewInfoHandler(
info.WithBaseURL("https://api.example.com"),
info.WithUIType(info.UISwaggerUI),
)
handlerRedoc := info.NewInfoHandler(
info.WithBaseURL("https://api.example.com"),
info.WithUIType(info.UIRedoc),
)
// Test Scalar UI
reqScalar := httptest.NewRequest(http.MethodGet, "/docs", nil)
rrScalar := httptest.NewRecorder()
handlerScalar.GetOpenAPIHTML(rrScalar, reqScalar)
fmt.Println("Scalar:", rrScalar.Code, strings.Contains(rrScalar.Body.String(), "@scalar/api-reference"))
// Test SwaggerUI
reqSwagger := httptest.NewRequest(http.MethodGet, "/docs", nil)
rrSwagger := httptest.NewRecorder()
handlerSwaggerUI.GetOpenAPIHTML(rrSwagger, reqSwagger)
fmt.Println("SwaggerUI:", rrSwagger.Code, strings.Contains(rrSwagger.Body.String(), "swagger-ui-dist"))
// Test Redoc
reqRedoc := httptest.NewRequest(http.MethodGet, "/docs", nil)
rrRedoc := httptest.NewRecorder()
handlerRedoc.GetOpenAPIHTML(rrRedoc, reqRedoc)
fmt.Println("Redoc:", rrRedoc.Code, strings.Contains(rrRedoc.Body.String(), "redoc"))
}
Output: Scalar: 200 true SwaggerUI: 200 true Redoc: 200 true
Example (Full) ¶
package main
import (
"context"
"fmt"
"net/http"
"net/http/httptest"
"strings"
"github.com/drblury/apiweaver/info"
"github.com/drblury/apiweaver/probe"
)
func main() {
handler := info.NewInfoHandler(
info.WithBaseURL("/docs"),
info.WithInfoProvider(func() any {
return map[string]string{"version": "1.2.3"}
}),
info.WithSwaggerProvider(func() ([]byte, error) {
return []byte(`{"openapi":"3.1.0","info":{"title":"Demo","version":"1.0.0"}}`), nil
}),
info.WithLivenessChecks(probe.NewPingProbe("noop", func(ctx context.Context) error {
return nil
})),
info.WithReadinessChecks(probe.NewPingProbe("db", func(ctx context.Context) error {
return nil
})),
)
healthRec := httptest.NewRecorder()
handler.GetHealthz(healthRec, httptest.NewRequest(http.MethodGet, "/healthz", nil))
fmt.Println(healthRec.Code)
fmt.Println(strings.TrimSpace(healthRec.Body.String()))
versionRec := httptest.NewRecorder()
handler.GetVersion(versionRec, httptest.NewRequest(http.MethodGet, "/version", nil))
fmt.Println(versionRec.Code)
fmt.Println(strings.TrimSpace(versionRec.Body.String()))
}
Output: 200 {"status":"ok"} 200 {"version":"1.2.3"}
func NewInfoHandler ¶
func NewInfoHandler(opts ...InfoOption) *InfoHandler
NewInfoHandler constructs an InfoHandler with sensible defaults. Callers can supply InfoOption values to plug in domain specific providers or override the base responder implementation.
func (*InfoHandler) GetAsyncAPIHTML ¶ added in v0.2.3
func (ih *InfoHandler) GetAsyncAPIHTML(w http.ResponseWriter, r *http.Request)
GetAsyncAPIHTML renders an embedded AsyncAPI React Component viewer that fetches the AsyncAPI document from the JSON endpoint.
func (*InfoHandler) GetAsyncAPIJSON ¶ added in v0.2.3
func (ih *InfoHandler) GetAsyncAPIJSON(w http.ResponseWriter, r *http.Request)
GetAsyncAPIJSON streams the configured AsyncAPI JSON document to the caller.
func (*InfoHandler) GetHealthz ¶
func (ih *InfoHandler) GetHealthz(w http.ResponseWriter, r *http.Request)
GetHealthz implements the liveness probe recommended for Kubernetes.
func (*InfoHandler) GetOpenAPIHTML ¶
func (ih *InfoHandler) GetOpenAPIHTML(w http.ResponseWriter, r *http.Request)
GetOpenAPIHTML renders an embedded Stoplight viewer that fetches the OpenAPI document from the JSON endpoint.
func (*InfoHandler) GetOpenAPIJSON ¶
func (ih *InfoHandler) GetOpenAPIJSON(w http.ResponseWriter, r *http.Request)
GetOpenAPIJSON streams the configured OpenAPI JSON document to the caller.
func (*InfoHandler) GetReadyz ¶
func (ih *InfoHandler) GetReadyz(w http.ResponseWriter, r *http.Request)
GetReadyz implements the readiness probe recommended for Kubernetes.
func (*InfoHandler) GetStatus ¶
func (ih *InfoHandler) GetStatus(w http.ResponseWriter, r *http.Request)
GetStatus returns a simple health payload that can be used for lightweight diagnostics.
func (*InfoHandler) GetVersion ¶
func (ih *InfoHandler) GetVersion(w http.ResponseWriter, r *http.Request)
GetVersion returns the structure provided by the configured InfoProvider.
type InfoOption ¶
type InfoOption func(*InfoHandler)
InfoOption follows the functional options pattern used by NewInfoHandler to configure optional collaborators such as the responder, base URL, and information providers.
func WithAsyncAPIProvider ¶ added in v0.2.3
func WithAsyncAPIProvider(provider AsyncAPIProvider) InfoOption
WithAsyncAPIProvider sets the source of the AsyncAPI JSON document that backs the AsyncAPI documentation endpoints.
func WithAsyncAPITemplate ¶ added in v0.2.3
func WithAsyncAPITemplate(tmpl *template.Template) InfoOption
WithAsyncAPITemplate injects a custom html/template instance used to render the AsyncAPI viewer page. Callers can parse templates from disk or embed them via go:embed before passing them in.
func WithAsyncAPITemplateData ¶ added in v0.2.3
func WithAsyncAPITemplateData(provider AsyncAPITemplateDataProvider) InfoOption
WithAsyncAPITemplateData overrides the template data provider that runs for each request to the AsyncAPI HTML endpoint.
func WithBaseURL ¶
func WithBaseURL(baseURL string) InfoOption
WithBaseURL sets the URL prefix that will be injected into the rendered documentation template.
func WithInfoProvider ¶
func WithInfoProvider(provider InfoProvider) InfoOption
WithInfoProvider swaps the default metadata provider with a user supplied implementation.
func WithInfoResponder ¶
func WithInfoResponder(responder *responder.Responder) InfoOption
WithInfoResponder replaces the responder used to craft JSON responses and handle error reporting.
func WithLivenessChecks ¶
func WithLivenessChecks(checks ...ProbeFunc) InfoOption
WithLivenessChecks replaces the default liveness checks with the supplied functions.
func WithOpenAPITemplate ¶
func WithOpenAPITemplate(tmpl *template.Template) InfoOption
WithOpenAPITemplate injects a custom html/template instance used to render the OpenAPI viewer page. Callers can parse templates from disk or embed them via go:embed before passing them in.
func WithOpenAPITemplateData ¶
func WithOpenAPITemplateData(provider TemplateDataProvider) InfoOption
WithOpenAPITemplateData overrides the template data provider that runs for each request to the HTML endpoint.
func WithProbeTimeout ¶
func WithProbeTimeout(timeout time.Duration) InfoOption
WithProbeTimeout adjusts the maximum duration allowed for probe checks.
func WithReadinessChecks ¶
func WithReadinessChecks(checks ...ProbeFunc) InfoOption
WithReadinessChecks replaces the default readiness checks with the supplied functions.
func WithSwaggerProvider ¶
func WithSwaggerProvider(provider SwaggerProvider) InfoOption
WithSwaggerProvider sets the source of the OpenAPI JSON document that backs the documentation endpoints.
func WithUIType ¶ added in v0.2.2
func WithUIType(uiType UIType) InfoOption
WithUIType sets the OpenAPI documentation UI to use. Supported values are UIStoplight (default), UIScalar, UISwaggerUI, and UIRedoc.
type InfoProvider ¶
type InfoProvider func() any
InfoProvider returns the payload that will be exposed by the version endpoint. The provider allows callers to inject their own source for build metadata or runtime diagnostics.
type ProbeFunc ¶
ProbeFunc is executed to determine the outcome of liveness or readiness probes. Returning a non-nil error marks the probe as failed.
type SwaggerProvider ¶
SwaggerProvider returns the raw OpenAPI document that should be rendered by the documentation endpoints. It is commonly backed by an embedded JSON file generated at build time.
type TemplateDataProvider ¶
TemplateDataProvider allows callers to customise the data payload passed to the OpenAPI HTML template at render time.
type UIType ¶ added in v0.2.2
type UIType string
UIType specifies which OpenAPI documentation UI to use.
const ( // UIStoplight uses Stoplight Elements for OpenAPI rendering (default). UIStoplight UIType = "stoplight" // UIScalar uses Scalar for OpenAPI rendering. UIScalar UIType = "scalar" // UISwaggerUI uses SwaggerUI for OpenAPI rendering. UISwaggerUI UIType = "swaggerui" // UIRedoc uses Redoc for OpenAPI rendering. UIRedoc UIType = "redoc" )