httpjson

package
v1.125.5 Latest Latest
Warning

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

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

Documentation

Overview

Package httpjson holds the JSON and RFC 9457 Problem Details responders shared by the admin and portal REST decomposition seams, and the request-side JSON field types (see OptionalInt) that the REST routes and the MCP tools accepting the same field decode through.

pkg/admin and pkg/portal each carry their own unexported copy of this responder, and the first seam extracted out of pkg/admin (internal/admin/settingsapi) copied it a third time. Every additional seam would have added another byte-identical copy, and — because swag resolves a schema per package — another duplicate `problemDetail` definition in the published OpenAPI document. The seams point here instead, so the seam family contributes exactly one responder and one schema.

The parents' own copies are deliberately left in place: their ~500 `@Failure ... {object} problemDetail` annotations resolve against the package-local type, and rewriting those is a documentation change rather than a decomposition one.

Index

Constants

View Source
const ProblemTypePrefix = "urn:mcp-data-platform:problem:"

ProblemTypePrefix namespaces the platform's own problem types. It is a URN rather than a URL because nothing is served at the other end: the value exists to be compared, and a URL would promise a page that does not exist.

Variables

This section is empty.

Functions

func ParseLimit

func ParseLimit(q url.Values) int

ParseLimit parses the `per_page` parameter into a limit. Zero means the caller expressed no preference and its own default applies.

func ParsePageOffset

func ParsePageOffset(q url.Values, effectiveLimit int) int

ParsePageOffset parses the 1-based `page` parameter and converts it to a row offset against effectiveLimit. Anything absent, non-numeric, or below 1 yields the first page.

func ParseTimeParam

func ParseTimeParam(q url.Values, key string) *time.Time

ParseTimeParam parses an RFC3339 time from a query parameter. A missing or unparseable value yields nil, which callers treat as "no bound" — a bad timestamp widens the query rather than failing it.

func WriteError

func WriteError(w http.ResponseWriter, status int, msg string)

WriteError writes an RFC 9457 Problem Details error response. Title is derived from the status text; msg becomes the detail and must already be safe to return to the caller.

func WriteErrorCode added in v1.125.3

func WriteErrorCode(w http.ResponseWriter, status int, code, msg string)

WriteErrorCode writes a Problem Details response whose type names the problem rather than leaving it "about:blank".

It is for the refusals a caller can do something specific about. The detail is the sentence a person reads; a surface offering the next step cannot key a control off prose, and the type is the half it can match on.

func WriteJSON

func WriteJSON(w http.ResponseWriter, status int, v any)

WriteJSON writes v as a JSON response with the given status. A Content-Type the caller already set is preserved, which is what lets WriteError layer its problem+json type on top of this.

Types

type OptionalInt added in v1.124.1

type OptionalInt struct {
	// Present reports that the field appeared in the payload at all.
	Present bool
	// Value is the number sent, or nil when the field was sent as null.
	Value *int
}

OptionalInt is a JSON integer field that distinguishes the three states a PATCH-shaped request body can put it in: absent (leave the stored value alone), explicitly null (clear the stored value), and present with a number (write that number).

A plain *int cannot carry this. encoding/json decodes both an absent field and an explicit null into a nil pointer, so a request that means "go back to the default" is indistinguishable from a request that never mentioned the field. Reaching for a sentinel number instead would spend a value the caller is entitled to send: the fields this guards -- an asset's version-retention cap first among them -- treat 0 and every positive number as meaningful.

Marshaling is not implemented because this is a request-side type: it names what a caller asked for, and responses carry the stored value itself. It serves the MCP tool surfaces as well as the REST ones -- a tool argument is the same JSON with the same three states.

func (OptionalInt) Resolve added in v1.124.1

func (o OptionalInt) Resolve() (value *int, reset bool)

Resolve renders the field as the pair an update struct carries: the value to write, and whether to reset the stored value instead. An absent field returns (nil, false), which leaves both untouched.

func (*OptionalInt) UnmarshalJSON added in v1.124.1

func (o *OptionalInt) UnmarshalJSON(b []byte) error

UnmarshalJSON records that the field was present and captures its value.

type ProblemDetail

type ProblemDetail struct {
	Type   string `json:"type" example:"about:blank"`
	Title  string `json:"title" example:"Not Found"`
	Status int    `json:"status" example:"404"`
	Detail string `json:"detail,omitempty" example:"resource not found"`
}

ProblemDetail is an RFC 9457 Problem Details response body. It mirrors the admin and portal packages' unexported equivalents field for field, so a seam's errors are indistinguishable on the wire from the routes that stayed behind in the parent.

type StatusResponse

type StatusResponse struct {
	Status string `json:"status" example:"ok"`
}

StatusResponse is the generic acknowledgement body ("status": "ok") that admin and portal write routes return when there is nothing else to say. It mirrors the parents' unexported equivalents.

Jump to

Keyboard shortcuts

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