Documentation
¶
Index ¶
- Variables
- func Bind(r *http.Request, dst any) error
- func BindForm(r *http.Request, dst any) error
- func BindHeader(r *http.Request, dst any) error
- func BindJSON(r *http.Request, dst any) error
- func BindMultipart(r *http.Request, dst any) error
- func BindPath(r *http.Request, dst any) error
- func BindQuery(r *http.Request, dst any) error
- func DELETE(r chi.Router, pattern string, h Handler, opts ...Option)
- func GET(r chi.Router, pattern string, h Handler, opts ...Option)
- func HEAD(r chi.Router, pattern string, h Handler, opts ...Option)
- func JSON(w http.ResponseWriter, status int, v any) error
- func NoContent(w http.ResponseWriter) error
- func OPTIONS(r chi.Router, pattern string, h Handler, opts ...Option)
- func PATCH(r chi.Router, pattern string, h Handler, opts ...Option)
- func POST(r chi.Router, pattern string, h Handler, opts ...Option)
- func PUT(r chi.Router, pattern string, h Handler, opts ...Option)
- func RawJSON(w http.ResponseWriter, status int, data []byte) error
- func Redirect(w http.ResponseWriter, r *http.Request, status int, url string) error
- func SetErrorHandler(h ErrorHandler)
- func SetMaxBodyBytes(n int64)
- func SetMaxMultipartMemory(n int64)
- func Text(w http.ResponseWriter, status int, s string) error
- type ErrorHandler
- type HTTPError
- func BadRequest(msg string, details ...any) *HTTPError
- func Conflict(msg string, details ...any) *HTTPError
- func Forbidden(msg string, details ...any) *HTTPError
- func InternalServerError(msg string, details ...any) *HTTPError
- func NewError(status int, message string, details ...any) *HTTPError
- func NotFound(msg string, details ...any) *HTTPError
- func Unauthorized(msg string, details ...any) *HTTPError
- func UnprocessableEntity(msg string, details ...any) *HTTPError
- type Handler
- type Middleware
- type Option
- type RouteInfo
- type Router
- type SSEEvent
- type SSEWriter
- type ValidationDetail
Constants ¶
This section is empty.
Variables ¶
var ErrStreamingNotSupported = errors.New("kori: response writer does not support streaming (does not implement http.Flusher)")
ErrStreamingNotSupported is returned when the ResponseWriter does not implement http.Flusher and therefore cannot be used for SSE.
Functions ¶
func Bind ¶
Bind decodes path, query, and header params into dst and validates it. Convenience wrapper around BindPath + BindQuery + BindHeader.
func BindForm ¶ added in v0.4.0
BindForm decodes form values from r.PostForm into dst and validates it. dst must be a pointer to a struct with `form` tags.
func BindHeader ¶
BindHeader decodes HTTP headers into dst and validates it. dst must be a pointer to a struct with `header` tags.
func BindJSON ¶
BindJSON decodes the request body as JSON into dst and validates it. Body is limited to 4 MB by default; configure it with SetMaxBodyBytes. Returns a 413 HTTPError if the body exceeds the limit and a 422 HTTPError on validation failure.
func BindMultipart ¶ added in v0.4.0
BindMultipart decodes multipart form data (values and files) into dst and validates it. dst must be a pointer to a struct with `form` tags. File fields must be of type *multipart.FileHeader or []*multipart.FileHeader.
func BindPath ¶
BindPath decodes chi URL parameters into dst and validates it. dst must be a pointer to a struct with `path` tags.
var params UserParams kori.BindPath(r, ¶ms)
func BindQuery ¶
BindQuery decodes URL query parameters into dst and validates it. dst must be a pointer to a struct with `query` tags.
var params ListUsersParams kori.BindQuery(r, ¶ms)
func GET ¶
GET registers a handler for the GET method.
kori.GET(r, "/users", listUsers)
kori.GET(r, "/users/{id}", getUser, kori.Use(adminOnly))
func JSON ¶
func JSON(w http.ResponseWriter, status int, v any) error
JSON writes v as JSON with the given status code.
func NoContent ¶
func NoContent(w http.ResponseWriter) error
NoContent writes a 204 No Content response.
func RawJSON ¶
func RawJSON(w http.ResponseWriter, status int, data []byte) error
RawJSON writes pre-encoded JSON bytes with the given status code.
func Redirect ¶
Redirect sends an HTTP redirect response. status should be http.StatusMovedPermanently, http.StatusFound, etc.
func SetErrorHandler ¶
func SetErrorHandler(h ErrorHandler)
SetErrorHandler replaces the default error handler. The handler receives every error returned from a Handler.
SetErrorHandler(func(w http.ResponseWriter, r *http.Request, err error) {
w.Write([]byte("custom error: " + err.Error()))
})
func SetMaxBodyBytes ¶ added in v0.5.0
func SetMaxBodyBytes(n int64)
SetMaxBodyBytes sets the maximum size of a JSON request body. Default is 4 MB.
func SetMaxMultipartMemory ¶ added in v0.4.0
func SetMaxMultipartMemory(n int64)
SetMaxMultipartMemory sets the maximum memory size for multipart form parsing. Default is 32 MB.
Types ¶
type ErrorHandler ¶
type ErrorHandler func(w http.ResponseWriter, r *http.Request, err error)
ErrorHandler is a function that writes an error response. Replace the default with SetErrorHandler to customize error handling.
func GetErrorHandler ¶
func GetErrorHandler() ErrorHandler
GetErrorHandler returns the current error handler.
type HTTPError ¶
type HTTPError struct {
Status int `json:"-"`
Message string `json:"message"`
Details any `json:"details,omitempty"`
}
HTTPError is a structured HTTP error with status code and optional details. Return it from a Handler to let kori write the error response.
func BadRequest ¶
BadRequest returns a 400 HTTPError.
func InternalServerError ¶
InternalServerError returns a 500 HTTPError.
func NewError ¶
NewError creates an HTTPError with the given status and message. An optional details value is included in the JSON response.
func Unauthorized ¶
Unauthorized returns a 401 HTTPError.
func UnprocessableEntity ¶
UnprocessableEntity returns a 422 HTTPError.
type Handler ¶
type Handler func(w http.ResponseWriter, r *http.Request) error
Handler is an HTTP handler that returns an error. Errors are caught and handled by the configured ErrorHandler.
type Middleware ¶
Middleware is a standard HTTP middleware.
type Option ¶
type Option func(*RouteInfo)
Option configures a route at registration time.
func Use ¶
func Use(middlewares ...Middleware) Option
Use attaches middlewares to a specific route.
kori.GET(r, "/admin", adminHandler, kori.Use(authMiddleware, auditMiddleware))
type RouteInfo ¶
RouteInfo contains the parsed route metadata. Used internally by Option functions to configure routes.
type SSEWriter ¶ added in v0.3.0
type SSEWriter struct {
// contains filtered or unexported fields
}
SSEWriter writes Server-Sent Events to an http.ResponseWriter.
func NewSSEWriter ¶ added in v0.3.0
func NewSSEWriter(w http.ResponseWriter) (*SSEWriter, error)
NewSSEWriter creates an SSEWriter, sets the SSE headers, and flushes the initial response. Returns ErrStreamingNotSupported if the ResponseWriter does not support flushing.
func (*SSEWriter) Ping ¶ added in v0.3.0
Ping sends an SSE comment line to keep the connection alive.
Long-lived SSE connections can be silently dropped by proxies, load balancers, or firewalls that close idle TCP connections. Call Ping periodically (e.g. every 15–30 seconds) when no real events are being sent to prevent this.
ticker := time.NewTicker(15 * time.Second)
defer ticker.Stop()
for {
select {
case <-r.Context().Done():
return nil
case <-ticker.C:
stream.Ping()
case msg := <-messages:
stream.SendJSON(msg)
}
}
func (*SSEWriter) Send ¶ added in v0.3.0
Send writes event to the stream and flushes immediately.
Returns an error if the underlying write fails, which usually means the client has disconnected. Callers should treat a write error as a normal end-of-stream signal rather than an application error:
if err := stream.Send(event); err != nil {
return nil // client gone, stop the loop
}
func (*SSEWriter) SendData ¶ added in v0.3.0
SendData sends a data-only event. Shorthand for Send(SSEEvent{Data: data}).
stream.SendData("hello")
stream.SendData(`{"status":"processing"}`)
func (*SSEWriter) SendJSON ¶ added in v0.3.0
SendJSON encodes v as JSON and sends it as a data-only event. Ideal for structured streaming payloads (LLM tokens, progress updates, etc.).
stream.SendJSON(map[string]string{"text": token})
To set an event name alongside JSON data, encode manually and use Send:
data, _ := json.Marshal(payload)
stream.Send(kori.SSEEvent{Event: "token", Data: string(data)})