httputil

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Aug 4, 2026 License: Apache-2.0 Imports: 5 Imported by: 0

README

httputil

Shared HTTP response helpers for writing JSON payloads and standardized, correlation-ID-tagged API error bodies. It has no dependencies — correlation ID extraction is an optional hook a consumer wires in, not a hard-coded package.

Usage

Writing JSON responses
import (
    "net/http"

    "github.com/OpenNSW/core/httputil"
)

func handleGet(w http.ResponseWriter, r *http.Request) {
    httputil.JSON(w, http.StatusOK, map[string]string{"id": "c-1"})
}
Client-facing errors

Error writes a fixed, safe message alongside the request's correlation ID (see "Correlation IDs" below), so the client can report the ID back for support without ever seeing internal error details:

func handleGet(w http.ResponseWriter, r *http.Request) {
    item, ok := repo.Find(r.Context(), id)
    if !ok {
        httputil.Error(w, r, http.StatusNotFound, "item not found")
        return
    }
    httputil.JSON(w, http.StatusOK, item)
}
Server-side errors

InternalServerError logs the real error server-side (via slog) and responds with a generic, safe message to the client:

func handleGet(w http.ResponseWriter, r *http.Request) {
    item, err := repo.Find(r.Context(), id)
    if err != nil {
        httputil.InternalServerError(w, r, "failed to load item", err, "itemId", id)
        return
    }
    httputil.JSON(w, http.StatusOK, item)
}
Correlation IDs (optional)

CorrelationIDFunc is an optional func(context.Context) string hook, unset (nil) by default. When unset, Error/InternalServerError simply omit correlationId from the response body. To populate it, wire in whatever correlation mechanism your service already uses — for example, github.com/OpenNSW/core/trace:

import (
    "github.com/OpenNSW/core/httputil"
    "github.com/OpenNSW/core/trace"
)

func main() {
    httputil.CorrelationIDFunc = trace.GetTraceID
    // ...
}

Combine it with trace/logging.NewHandler so the same ID that's returned to the client as correlationId also shows up on server-side log lines as traceId:

import (
    "log/slog"
    "os"

    "github.com/OpenNSW/core/httputil"
    "github.com/OpenNSW/core/trace"
    "github.com/OpenNSW/core/trace/logging"
)

func main() {
    httputil.CorrelationIDFunc = trace.GetTraceID
    slog.SetDefault(slog.New(logging.NewHandler(slog.NewJSONHandler(os.Stdout, nil))))
    // InternalServerError's slog.ErrorContext calls now get "traceId" attached automatically.
}

You can also read the correlation ID directly:

func handleGet(w http.ResponseWriter, r *http.Request) {
    correlationID := httputil.CorrelationID(r)
    // ...
}

Testing

Run the package tests using (from within the httputil directory):

go test ./...

Documentation

Overview

Package httputil provides shared HTTP response helpers for writing JSON payloads and standardized, correlation-ID-tagged API error bodies.

Index

Constants

This section is empty.

Variables

View Source
var CorrelationIDFunc func(context.Context) string

CorrelationIDFunc optionally extracts a correlation ID from a request context for inclusion in Error/InternalServerError responses. It is nil by default, in which case CorrelationID returns "". A consumer that wants correlation IDs wires in an extractor of its choosing, e.g.:

httputil.CorrelationIDFunc = trace.GetTraceID

Functions

func CorrelationID

func CorrelationID(r *http.Request) string

CorrelationID returns the request's correlation ID via CorrelationIDFunc, or "" if CorrelationIDFunc is unset. This is the same value included in the correlationId field of Error/InternalServerError responses.

func Error

func Error(w http.ResponseWriter, r *http.Request, status int, message string)

Error responds with a fixed, safe message for an expected client-facing condition.

func InternalServerError

func InternalServerError(w http.ResponseWriter, r *http.Request, logMessage string, err error, attrs ...any)

InternalServerError logs err server-side and responds with a generic, safe message to the client.

func JSON

func JSON(w http.ResponseWriter, status int, payload any)

JSON writes payload as the JSON response body with the given status. If payload fails to encode, it responds with 500 instead of a partial body under the originally requested status.

Types

type ErrorResponse

type ErrorResponse struct {
	Error         string `json:"error"`
	CorrelationID string `json:"correlationId,omitempty"`
}

ErrorResponse is the standard JSON shape for API error bodies.

Jump to

Keyboard shortcuts

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