Documentation
¶
Overview ¶
Package astarteapi implements the JSON envelope conventions shared by every Astarte-compatible REST surface: success bodies are wrapped as {"data": ...}, error bodies as {"errors": {"detail": "..."}} (or the field-keyed changeset shape used by 422 validation failures), and request bodies arrive wrapped as {"data": ...}.
These exact bytes are parsed by astartectl and the official device SDKs, so the golden fixtures under testdata/ are wire-frozen: changing any envelope produced here is a compatibility break, not a refactor.
Index ¶
- Constants
- Variables
- func DecodeData(r io.Reader, maxBytes int64, dst any) error
- func WriteBadRequest(w http.ResponseWriter) error
- func WriteData(w http.ResponseWriter, status int, v any) error
- func WriteDeviceNotFound(w http.ResponseWriter) error
- func WriteError(w http.ResponseWriter, status int, detail string) error
- func WriteFieldErrors(w http.ResponseWriter, status int, fields map[string][]string) error
- func WriteForbidden(w http.ResponseWriter) error
- func WriteInternalServerError(w http.ResponseWriter) error
- func WriteNotFound(w http.ResponseWriter) error
- func WriteUnauthorized(w http.ResponseWriter) error
Constants ¶
const ( // DetailBadRequest is the canonical 400 detail. DetailBadRequest = "Bad Request" DetailUnauthorized = "Unauthorized" // DetailForbidden is the canonical 403 detail. DetailForbidden = "Forbidden" // DetailNotFound is the canonical generic 404 detail. DetailNotFound = "Not Found" // DetailDeviceNotFound is the canonical 404 detail for unknown devices // (upstream AppEngine/Pairing shape). DetailDeviceNotFound = "Device not found" // DetailInternalServerError is the canonical 500 detail. DetailInternalServerError = "Internal Server Error" )
Canonical upstream error detail strings. These are frozen: SDK and astartectl error paths match on them.
const ContentType = "application/json; charset=utf-8"
ContentType is the Content-Type header value set on every envelope, matching what upstream Astarte's Phoenix endpoints emit.
const DefaultMaxBodyBytes int64 = 1 << 20 // 1 MiB
DefaultMaxBodyBytes is the request body size cap callers are expected to pass to DecodeData unless an endpoint has a documented reason to differ (interface uploads, for example, may need more than a pairing request).
Variables ¶
var ErrBodyTooLarge = errors.New("request body too large")
ErrBodyTooLarge is wrapped by DecodeData when the request body exceeds the caller-supplied size cap.
var ErrMissingData = errors.New(`missing "data" key in request body`)
ErrMissingData is wrapped by DecodeData when the request body has no "data" key (or it is JSON null) — upstream rejects such bodies uniformly.
Functions ¶
func DecodeData ¶
DecodeData reads at most maxBytes bytes from r, unwraps the mandatory {"data": ...} request envelope, and unmarshals the "data" value into dst.
It fails with an error wrapping ErrBodyTooLarge when the body exceeds maxBytes, with one wrapping ErrMissingData when the "data" key is absent or null, and with the underlying JSON error for malformed bodies (including trailing garbage after the top-level value). Sibling keys next to "data" are ignored, matching upstream parameter handling.
func WriteBadRequest ¶
func WriteBadRequest(w http.ResponseWriter) error
WriteBadRequest writes the canonical 400 envelope.
func WriteData ¶
func WriteData(w http.ResponseWriter, status int, v any) error
WriteData writes {"data": v} with the given status code.
func WriteDeviceNotFound ¶
func WriteDeviceNotFound(w http.ResponseWriter) error
WriteDeviceNotFound writes the canonical 404 "Device not found" envelope.
func WriteError ¶
func WriteError(w http.ResponseWriter, status int, detail string) error
WriteError writes {"errors": {"detail": detail}} with the given status code. Use the canonical constructors below for the frozen upstream shapes; use WriteError directly for endpoint-specific details.
func WriteFieldErrors ¶
WriteFieldErrors writes the Phoenix-changeset-shaped error envelope {"errors": {"<field>": ["<message>", ...]}} used by upstream 422 validation failures (for example {"errors": {"hw_id": ["is invalid"]}}). Keys are emitted in sorted order (Go map marshalling), which matches the deterministic bodies upstream produces for single-field failures.
func WriteForbidden ¶
func WriteForbidden(w http.ResponseWriter) error
WriteForbidden writes the canonical 403 envelope.
func WriteInternalServerError ¶
func WriteInternalServerError(w http.ResponseWriter) error
WriteInternalServerError writes the canonical 500 envelope.
func WriteNotFound ¶
func WriteNotFound(w http.ResponseWriter) error
WriteNotFound writes the canonical generic 404 envelope.
func WriteUnauthorized ¶
func WriteUnauthorized(w http.ResponseWriter) error
WriteUnauthorized writes the canonical 401 envelope.
Types ¶
This section is empty.