Documentation
¶
Overview ¶
Package serverfn is the runtime for GoWebComponents server functions — the //gwc:server keystone. A server function is an ordinary, type-safe Go function
func(context.Context, Req) (Resp, error)
that runs only on the server. `gwc server gen` generates a server registration (which wires the function into an HTTP mux via Handle) and a matching client stub (which calls it via Call). The two sides share one Go signature, so a server function is invoked from the browser with full compile-time type safety and no hand-written fetch/JSON glue.
Both Handle and Call use net/http + encoding/json with no build tags: on the server they use real sockets, and in the browser Go's net/http transport is backed by the Fetch API, so the exact same code path is exercised — and the whole package is unit-testable natively with httptest.
Index ¶
- Constants
- func Call[Req, Resp any](parseCtx context.Context, parseName string, parseReq Req) (Resp, error)
- func Configure(parseBaseURL string)
- func Endpoint(parseName string) string
- func Handle[Req, Resp any](parseMux *http.ServeMux, parseName string, ...)
- func SetCSRFProtection(parseEnabled bool)
- func SetClient(parseClient *http.Client)
- func SetErrorLogger(parseLogger func(parseName string, parseErr error))
- func SetMaxRequestBytes(parseLimit int64)
- type ServerError
- type StatusError
- func BadRequest(parseMessage string) *StatusError
- func Conflict(parseMessage string) *StatusError
- func Forbidden(parseMessage string) *StatusError
- func NewStatusError(parseStatus int, parseMessage string) *StatusError
- func NotFound(parseMessage string) *StatusError
- func Unauthorized(parseMessage string) *StatusError
- func UnprocessableEntity(parseMessage string) *StatusError
Constants ¶
const RoutePrefix = "/_gwc/fn/"
RoutePrefix is the URL path prefix every server function is served under.
Variables ¶
This section is empty.
Functions ¶
func Call ¶
Call invokes the named server function over HTTP and decodes its typed response. On failure it returns a *ServerError (when the server reported one) or the underlying transport/decoding error. Works identically on the server and in the browser.
func Configure ¶
func Configure(parseBaseURL string)
Configure sets the base URL the client uses to reach server functions (e.g. an httptest server URL in tests, or an absolute origin for a cross-origin API). An empty base URL — the default — targets the same origin, which is what a browser-hosted app wants.
func Handle ¶
func Handle[Req, Resp any](parseMux *http.ServeMux, parseName string, parseFn func(context.Context, Req) (Resp, error))
Handle registers fn as a JSON POST endpoint at Endpoint(name) on mux. It decodes the request body into Req, invokes fn with the request's context, and writes fn's Resp as JSON (200) or, on error, a {"error":...} body with a 4xx/5xx status. A non-POST method is rejected with 405 and a malformed body with 400.
func SetCSRFProtection ¶
func SetCSRFProtection(parseEnabled bool)
SetCSRFProtection toggles Handle's cross-site-request defenses (default on).
When enabled, Handle requires the request's Content-Type to be application/json and rejects any request a browser has flagged (via Sec-Fetch-Site) as cross-site. This is the package's CSRF defense:
- application/json is NOT a CORS-safelisted Content-Type, so a cross-origin browser request carrying it forces a CORS preflight, which an attacker's forged page cannot satisfy for a cookie-authenticated victim; and an HTML <form> — which can only send the three safelisted content types — cannot forge a call at all.
- Sec-Fetch-Site is a browser-set, JS-unspoofable request header; when it is present and reports "cross-site" the request is rejected outright. It is absent for non-browser clients, so this never rejects a legitimate server-to-server or curl caller.
The generated client always sends application/json, so this is transparent to generated code. Disable ONLY if you must accept raw non-JSON callers and have another CSRF defense in place.
func SetClient ¶
SetClient overrides the *http.Client used by Call (for custom timeouts, auth transports, or a test double). Passing nil restores http.DefaultClient.
func SetErrorLogger ¶
SetErrorLogger overrides the sink for the real server-side error behind a 5xx. Passing nil disables server-side error logging (the client still only sees a generic message). Enterprise deployments should route this into their logger.
func SetMaxRequestBytes ¶
func SetMaxRequestBytes(parseLimit int64)
SetMaxRequestBytes sets the maximum server-function request body size in bytes. A non-positive value restores the 10 MiB default. Applies to subsequently served requests.
Types ¶
type ServerError ¶
ServerError is returned by Call when the server function failed: it carries the HTTP status and the server-provided message, so the client sees a typed error with the real reason rather than a bare transport failure.
type StatusError ¶
StatusError is an error a server function returns to control the HTTP status of the failure. A plain error still maps to 500; returning a *StatusError (or wrapping one) makes Handle reply with the chosen status and message. The status round-trips to the caller as ServerError.Status, so the client can branch on 401/404/409/… instead of treating every failure as a 500.
func getUser(ctx context.Context, req Req) (User, error) {
u, ok := store.Find(req.ID)
if !ok { return User{}, serverfn.NotFound("no such user") }
return u, nil
}
func BadRequest ¶
func BadRequest(parseMessage string) *StatusError
Convenience constructors for the common client-error statuses.
func Conflict ¶
func Conflict(parseMessage string) *StatusError
func Forbidden ¶
func Forbidden(parseMessage string) *StatusError
func NewStatusError ¶
func NewStatusError(parseStatus int, parseMessage string) *StatusError
NewStatusError builds a StatusError with an explicit HTTP status code.
func NotFound ¶
func NotFound(parseMessage string) *StatusError
func Unauthorized ¶
func Unauthorized(parseMessage string) *StatusError
func UnprocessableEntity ¶
func UnprocessableEntity(parseMessage string) *StatusError
func (*StatusError) Error ¶
func (parseE *StatusError) Error() string
Error implements error. It is nil-safe so a mistakenly-returned nil *StatusError cannot panic.