Documentation
¶
Overview ¶
Package ginapi writes api envelopes, lists and objects through a gin.Context, binds list parameters from the query string, and carries the locale middleware. The envelope vocabulary itself lives in api, which depends on nothing.
Every writer here is byte-for-byte identical to the root net/http writer for the same error — gin_test.go asserts it off a real socket.
Index ¶
- Constants
- func BadGateway(c *gin.Context, message string)
- func BadRequest(c *gin.Context, message string)
- func BadRequestParam(c *gin.Context, param, message string)
- func BadRequestWithCode(c *gin.Context, code api.Code, message string)
- func Bind(c *gin.Context) api.ListParams
- func BindDefault(c *gin.Context) api.ListParams
- func BindWithDefaults(c *gin.Context, defaultLimit, maxLimit int) api.ListParams
- func BuildSupportedMap(languages []string) map[string]struct{}
- func Conflict(c *gin.Context, message string)
- func Created(c *gin.Context, obj any)
- func Deleted(c *gin.Context, objectType, id string)
- func DetectPreferredLanguage(c *gin.Context, supportedMap map[string]struct{}, defaultLang string) string
- func ExtractLanguageFromPath(path string) string
- func Fail(c *gin.Context, err error)
- func Forbidden(c *gin.Context)
- func ForbiddenWithMessage(c *gin.Context, message string)
- func GetLanguage(c *gin.Context) string
- func HandleLanguageRedirect(c *gin.Context, cfg LanguageRedirectConfig) bool
- func InternalError(c *gin.Context, message string)
- func Language(cfg LanguageConfig) gin.HandlerFunc
- func ListResponse[T any](c *gin.Context, data []T, total int64, limit, offset int)
- func ModerationRejected(c *gin.Context, reason string)
- func NoContent(c *gin.Context)
- func NotConfigured(c *gin.Context, message string)
- func NotFound(c *gin.Context, entity string)
- func NotFoundWithMessage(c *gin.Context, message string)
- func NotImplemented(c *gin.Context, message string)
- func Object(c *gin.Context, obj any)
- func ParseAcceptLanguage(header string, supported map[string]struct{}) string
- func Send(c *gin.Context, status int, t api.Type, code api.Code, message, param string)
- func ServiceUnavailable(c *gin.Context, message string)
- func SetLanguageCookie(c *gin.Context, lang string)
- func Success(c *gin.Context, message string)
- func TooManyRequests(c *gin.Context, message string)
- func Unauthorized(c *gin.Context)
- func UnauthorizedWithMessage(c *gin.Context, message string)
- func UnprocessableEntity(c *gin.Context, message string)
- func UnsupportedMediaType(c *gin.Context, message string)
- type LanguageConfig
- type LanguageRedirectConfig
Constants ¶
const ( // LanguageCookieName is the default cookie name for language preference LanguageCookieName = "lang" // LanguageCookieMaxAge is 1 year in seconds LanguageCookieMaxAge = 31536000 )
Variables ¶
This section is empty.
Functions ¶
func BadGateway ¶
BadGateway sends 502 api_error for an upstream failure.
func BadRequest ¶
BadRequest sends 400 invalid_request_error.
func BadRequestParam ¶
BadRequestParam sends 400 naming the offending request field.
func BadRequestWithCode ¶
BadRequestWithCode sends 400 with a machine-readable code.
func Bind ¶
func Bind(c *gin.Context) api.ListParams
Bind reads limit, offset and sort (or sort_by) from the query string, unnormalized.
func BindDefault ¶
func BindDefault(c *gin.Context) api.ListParams
BindDefault reads and normalizes against api's defaults (20, cap 100).
func BindWithDefaults ¶
func BindWithDefaults(c *gin.Context, defaultLimit, maxLimit int) api.ListParams
BindWithDefaults reads and normalizes list parameters against the caller's default and cap.
func BuildSupportedMap ¶
BuildSupportedMap creates a map of supported languages for fast lookup. Useful for redirect middleware that needs to check language validity.
func DetectPreferredLanguage ¶
func DetectPreferredLanguage(c *gin.Context, supportedMap map[string]struct{}, defaultLang string) string
DetectPreferredLanguage determines user's preferred language. Priority: cookie → Accept-Language → default
func ExtractLanguageFromPath ¶
ExtractLanguageFromPath extracts a 2-3 character language code from URL path prefix. e.g., "/ja/galleries" -> "ja", "/galleries" -> "" Exported for use by redirect middleware.
func Fail ¶
Fail writes err as the canonical envelope, deriving status and shape from it. It is api.WriteError against c.Writer — the same function, not a parallel implementation, which is how byte-for-byte equivalence is guaranteed rather than tested for.
func ForbiddenWithMessage ¶
ForbiddenWithMessage sends 403 with a custom message.
func GetLanguage ¶
GetLanguage retrieves the detected language from the gin context. Returns "en" as fallback if not set.
func HandleLanguageRedirect ¶
func HandleLanguageRedirect(c *gin.Context, cfg LanguageRedirectConfig) bool
HandleLanguageRedirect checks if a language redirect is needed and performs it. Returns true if a redirect was performed (caller should return early). Returns false if no redirect needed (caller should continue to serve the page).
This is designed to be called from a NoRoute handler:
r.NoRoute(func(c *gin.Context) {
if middleware.HandleLanguageRedirect(c, cfg) {
return // redirect was performed
}
// serve SPA
serveIndexHTML(c)
})
Behavior:
- If URL has a valid language prefix (e.g., /en/videos): set cookie, return false
- If URL has NO language prefix (e.g., /videos): redirect to prefixed URL, return true
func InternalError ¶
InternalError sends 500 api_error. The message is scrubbed: 500 is the one status that means "unexpected", so its text may carry an internal cause.
func Language ¶
func Language(cfg LanguageConfig) gin.HandlerFunc
Language returns middleware that detects user language from: 1. Query parameter (?lang=ja) - for API routes 2. URL path prefix (/ja/...) - for frontend routes 3. Cookie (user's saved preference) 4. Accept-Language header with q-value parsing 5. Default language
The detected language is stored in gin context and retrieved via GetLanguage(c). The Content-Language header is set on the response.
func ListResponse ¶
ListResponse sends a list body with has_more computed.
func ModerationRejected ¶
ModerationRejected sends 422 invalid_request_error with the stable code moderation_rejected: transport classification is unchanged, and the code is what tells a SPA to show the author a reason instead of retrying.
func NotConfigured ¶
NotConfigured sends 501 api_error for an optional capability the operator never wired — a deployment gap, distinguishable from a crash by its code.
func NotFound ¶
NotFound sends 404 for a named entity. The transport type stays invalid_request_error, as authkit and openrails deploy it; resource_not_found is the code a client branches on.
func NotFoundWithMessage ¶
NotFoundWithMessage sends 404 with a custom message.
func NotImplemented ¶
NotImplemented sends 501 api_error with the stable code not_implemented: this build lacks the capability. No new transport type — the code is the signal to hide the feature rather than retry.
func ParseAcceptLanguage ¶
ParseAcceptLanguage parses the Accept-Language header and returns the best supported language based on q-values. Exported for use by redirect middleware.
func Send ¶
Send writes an explicit envelope. Code may be empty: an absent code means "no machine reason beyond the status", and the writers never invent one. param is a plain string — the wire's pointer is api's problem.
func ServiceUnavailable ¶
ServiceUnavailable sends 503 api_error.
func SetLanguageCookie ¶
SetLanguageCookie sets the language preference cookie (1 year, SameSite=Lax).
func TooManyRequests ¶
TooManyRequests sends 429 rate_limit_error.
func UnauthorizedWithMessage ¶
UnauthorizedWithMessage sends 401 with a custom message.
func UnprocessableEntity ¶
UnprocessableEntity sends 422 invalid_request_error: well-formed syntax the server cannot act on. For a moderation refusal use ModerationRejected.
func UnsupportedMediaType ¶
UnsupportedMediaType sends 415 invalid_request_error.
Types ¶
type LanguageConfig ¶
type LanguageConfig struct {
// Supported languages (e.g., []string{"en", "ja", "ko", "zh"})
Supported []string
// Default language if none detected (defaults to "en")
Default string
// QueryParam to check for language override (defaults to "lang")
QueryParam string
// CookieName to check for language preference (defaults to "lang")
CookieName string
}
LanguageConfig configures the language detection middleware.
type LanguageRedirectConfig ¶
type LanguageRedirectConfig struct {
// Supported languages (e.g., []string{"en", "ja", "ko", "zh"})
Supported []string
// Default language if none detected (defaults to "en")
Default string
}
LanguageRedirectConfig configures language redirect behavior for NoRoute handlers.