client

package
v0.0.0-...-5c66370 Latest Latest
Warning

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

Go to latest
Published: Oct 17, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

Documentation

Overview

Package client is the official HTTP client for gst backends, designed as the client-side pairing of the framework's DSL: every HTTP interface shape a model's Design() can declare has a first-class counterpart here; the Stream action is served over gRPC alone and has none.

DSL declaration                       client entry
-----------------------------------   ------------------------------------------
Create/Update/Patch/Delete/Get/List   verb methods (Post/Put/Patch/Delete/Get)
Payload[*XxxReq]()                    the verb method payload argument
Result[*XxxRsp]()                     the RSP type parameter, decoded from data
Route("xxx/:id/action")               method + path composition
batch actions (items/ids bodies)      verbs + BatchItems/BatchIDs on /batch
Export()                              Download
Import()                              Upload
SSE responses                         Stream
model.Pagination / Query / Cursor     WithPage/WithSortBy/WithExpand/WithCursor
envelope (msg/data/trace_id)          Envelope on success, *Error on rejection

Evolution rule: whenever the DSL grows a new HTTP action or protocol shape, this package must grow the matching entry in the same change; a DSL capability without a client counterpart is an incomplete feature.

API shape: every entry is a method on Client and takes the context of the call first — in a service, the service context itself — whose deadline and cancellation bound the request. The verbs whose result needs a type parameter (Get/Post/Put/Patch/Delete) are parameterized methods, so a call reads cli.Get[XxxRsp](ctx, path); entries that need no type parameter (Do, Download, Upload, Stream) are plain methods.

Index

Constants

This section is empty.

Variables

View Source
var ErrStopStream = errors.New("stop consuming the stream")

ErrStopStream stops consuming the stream without reporting a failure: a callback returns it once it has seen enough events, and Stream answers nil. Tests asserting on the first few events of an endless stream are the typical user.

Functions

This section is empty.

Types

type Attachment

type Attachment struct {
	Name        string // file name parsed from Content-Disposition
	ContentType string
	Content     []byte
}

Attachment is one downloaded file attachment.

type Client

type Client struct {
	// contains filtered or unexported fields
}

Client is a service-level HTTP client for one gst backend: it carries the base address, the connection with its cookie jar, credentials and shared headers. Per-request state — the context the call runs under, the path, the payload and the query parameters — is passed per call, so one client serves every endpoint of the service and can be reused across requests safely.

func New

func New(addr string, opts ...Option) (*Client, error)

New creates a new client instance with given service base address and options. The address must start with "http://" or "https://". The client owns an isolated http.Client with its own cookie jar, so a login response cookie is carried on every later request automatically.

func (*Client) Delete

func (c *Client) Delete[RSP any](ctx context.Context, path string, payload any, opts ...RequestOption) (*RSP, error)

Delete sends a DELETE request on ctx and decodes the envelope data into RSP. It pairs the DSL Delete action; the payload covers the standard batch delete body, deleting by id passes nil.

func (*Client) Do

func (c *Client) Do(ctx context.Context, method, path string, payload any, opts ...RequestOption) (*Envelope, error)

Do sends one request on ctx and parses the response envelope. It is the non-generic floor under the verb functions: use it when the caller needs envelope details such as TraceID or Cookies instead of a decoded payload.

ctx is the context of the call — in a service, the service context itself. Its deadline and its cancellation end the request, the reading of the response included, and the request then fails with the context's error. A nil ctx is refused.

The request carries the trace ctx belongs to: the W3C trace context of the span open on it, and the framework's own X-Trace-ID header with the trace id the work runs under — a request's, a cron round's, a leader tenure's. The upstream continues that trace, so its access log, its statement comments and the trace_id of its answer all name the caller's trace id. A context that belongs to no trace sends neither header.

func (*Client) Download

func (c *Client) Download(ctx context.Context, path string, opts ...RequestOption) (*Attachment, error)

Download sends a GET request on ctx and reads the response as a file attachment, pairing the framework's Export action. A rejection answers with the regular JSON envelope and surfaces as an *Error.

func (*Client) Get

func (c *Client) Get[RSP any](ctx context.Context, path string, opts ...RequestOption) (*RSP, error)

Get sends a GET request on ctx and decodes the envelope data into RSP. GET carries no request body, matching the framework contract that the List and Get actions declare no Payload.

func (*Client) Patch

func (c *Client) Patch[RSP any](ctx context.Context, path string, payload any, opts ...RequestOption) (*RSP, error)

Patch sends a PATCH request on ctx and decodes the envelope data into RSP. It pairs the DSL Patch action and the standard batch patch route.

func (*Client) Post

func (c *Client) Post[RSP any](ctx context.Context, path string, payload any, opts ...RequestOption) (*RSP, error)

Post sends a POST request on ctx and decodes the envelope data into RSP. It pairs the DSL Create action and the POST-shaped custom action routes.

func (*Client) Put

func (c *Client) Put[RSP any](ctx context.Context, path string, payload any, opts ...RequestOption) (*RSP, error)

Put sends a PUT request on ctx and decodes the envelope data into RSP. It pairs the DSL Update action and the standard batch update route.

func (*Client) Stream

func (c *Client) Stream(ctx context.Context, method, path string, payload any, callback StreamCallback) error

Stream sends the request on ctx and consumes the response as a Server-Sent Events stream, pairing the framework's SSE responses. The stream ends when the server closes the connection, when ctx ends — the stream then fails with the context's error — or when the callback returns an error. A JSON answer on a stream endpoint is parsed as the regular envelope: a rejection surfaces as *Error, a success returns nil without events.

func (*Client) Upload

func (c *Client) Upload(ctx context.Context, path, filename string, content io.Reader, fields map[string]string) (*Envelope, error)

Upload sends content on ctx as the multipart "file" field, pairing the framework's Import action. fields are written as plain form fields next to the file.

type Envelope

type Envelope struct {
	Msg     string          `json:"msg,omitempty"`
	Data    json.RawMessage `json:"data,omitempty"`
	TraceID string          `json:"trace_id,omitempty"`
	Cookies []*http.Cookie  `json:"-"`
}

Envelope is the standard response envelope a gst backend answers with. The verb functions decode its Data field into the business RSP type; Envelope itself is returned by Do for callers that need the envelope details, such as TraceID or the response cookies.

func (*Envelope) Cookie

func (e *Envelope) Cookie(name string) *http.Cookie

Cookie returns the named response cookie, or nil when the response did not set it.

type Error

type Error struct {
	StatusCode int    // HTTP status code of the response
	Msg        string // message from the response envelope
	TraceID    string // trace id from the response envelope
	Body       []byte // raw response body, kept for debugging
}

Error is a structured server-side rejection: the HTTP layer answered with a non-2xx status. Transport failures (connection refused, timeout) stay ordinary errors and never become an *Error.

func (*Error) Error

func (e *Error) Error() string

Error renders the rejection as a single readable line.

type IDsPayload

type IDsPayload struct {
	IDs []string `json:"ids"`
}

IDsPayload is the request body of the standard batch delete route.

func BatchIDs

func BatchIDs(ids []string) IDsPayload

BatchIDs builds the ids body for the standard batch delete route.

type ItemsPayload

type ItemsPayload[T any] struct {
	Items []T `json:"items"`
}

ItemsPayload is the request body of the standard batch create, update and patch routes.

func BatchItems

func BatchItems[T any](items []T) ItemsPayload[T]

BatchItems builds the items body for the standard /batch routes.

type ListResult

type ListResult[T any] struct {
	Items []T `json:"items"`
	Total int `json:"total"`
}

ListResult is the response envelope of the framework's standard List action. Custom list responses with extra fields decode into their own RSP type instead; nothing forces this shape on them.

type Option

type Option func(*Client)

func WithBasicAuth

func WithBasicAuth(username, password string) Option

func WithCookie

func WithCookie(cookie *http.Cookie) Option

WithCookie adds a cookie to the client request headers.

func WithDebug

func WithDebug() Option

func WithHTTPClient

func WithHTTPClient(client *http.Client) Option

WithHTTPClient sends the requests through client instead of the http.Client New creates, whose cookie jar carries a login cookie over to later requests. The client is used as it is and never modified: a timeout set by WithTimeout applies to a copy.

func WithHeader

func WithHeader(header http.Header) Option

WithHeader merges the given headers into the client defaults. A key present in header replaces the default value of that key; other defaults stay.

func WithLogger

func WithLogger(logger types.Logger) Option

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout bounds each request of the client, the reading of the response included, by timeout (see http.Client.Timeout); a timeout of zero or less sets none. It applies alongside the deadline of the context a call passes: whichever ends first ends the request. New applies it last, to a copy of the http.Client, so the order of the options does not matter and a client handed to WithHTTPClient, such as a shared http.DefaultClient, keeps its own timeout.

func WithToken

func WithToken(token string) Option

func WithUserAgent

func WithUserAgent(userAgent string) Option

type RequestOption

type RequestOption func(*requestConfig)

RequestOption populates per-request state such as query parameters. Options are per call: the client instance itself stays free of request state.

func WithCursor

func WithCursor(field, value string, next bool) RequestOption

WithCursor sets the framework cursor pagination parameters (_cursor_field, _cursor_value, _cursor_next).

func WithExpand

func WithExpand(expand string, depth uint) RequestOption

WithExpand sets the framework association expansion parameters (_expand, _depth).

func WithPage

func WithPage(page, size int) RequestOption

WithPage sets the framework offset pagination parameters (_page, _size).

func WithQuery

func WithQuery(keyValues ...any) RequestOption

WithQuery adds free-form query parameters from alternating key/value pairs. Values may be strings, integers, floats or booleans; a trailing key without a value is dropped. Business filters, including the "field[op]=value" operator syntax, go through here.

func WithSortBy

func WithSortBy(sortBy string) RequestOption

WithSortBy sets the framework sorting parameter (_sort_by).

func WithTimeRange

func WithTimeRange(column string, from, to time.Time) RequestOption

WithTimeRange adds the framework's time-window filter on column, encoded in the "field[op]=value" operator syntax as column[gte] and column[lte]. Bounds are formatted as RFC3339, the only layout the framework accepts for URL time filtering. A zero time leaves that bound unset; a blank column adds nothing.

type StreamCallback

type StreamCallback func(event sse.Event) error

StreamCallback handles one SSE event; returning an error stops the stream. Returning ErrStopStream stops it without surfacing an error.

Jump to

Keyboard shortcuts

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