client

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 8, 2026 License: Apache-2.0 Imports: 11 Imported by: 0

README

pk-client

Go Reference CI

pk-client is a small, dependency-free Go client for PlatformKit-style CRUD APIs. It pairs a generic, transport-agnostic Client[T] facade with a batteries-included standard-library HTTP transport, covering single-item CRUD, partial updates, bulk operations, export, and import over typed request and response envelopes. It is part of the OSS PlatformKit family and intentionally stays transport-focused and free of private upstream imports, so downstream SDKs can wrap it with auth providers, telemetry, or hosted defaults.

Install

go get github.com/septagon-oss/pk-client@v0.1.0

Usage

package main

import (
	"context"
	"fmt"

	client "github.com/septagon-oss/pk-client"
)

type Widget struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

func main() {
	c, err := client.NewHTTP[Widget](client.NewHTTPConfig(
		"https://api.example.com",
		"/api/widgets",
		client.WithBearerToken("token"),
	))
	if err != nil {
		panic(err)
	}

	created, err := c.Create(context.Background(), client.CreateInput[Widget]{
		Body: Widget{Name: "gadget"},
	})
	if err != nil {
		panic(err)
	}
	fmt.Println("created", created.Data.ID)
}

Current Surface

  • generic Client[T] facade over a pluggable CRUDTransport[T] (New, NewHTTP, WithTransport)
  • single-item operations: Create, GetByID, List, Update, PartialUpdate, Delete
  • bulk and data operations: BulkCreate, BulkUpdate, BulkDelete, Export, Import
  • standard-library HTTP transport with headers, static query params, bearer/API-key auth, timeouts, and a caller-supplied *http.Client
  • HTTPConfig builder plus composable Option values (WithHeader, WithQueryParam, WithTimeout, WithBearerToken, WithAPIKey)
  • typed request/response envelopes (CreateInput, ListParams, Filter, ItemResponse, ListResponse, BulkResponse, ImportResponse)
  • matchable errors: ErrNoTransport, config sentinels (ErrBaseURLRequired, …), and a structured *APIError recoverable with errors.As

Verify

make verify   # go test + go vet + staticcheck + race

License

Apache-2.0. See LICENSE.

Documentation

Overview

Package client provides typed clients for PlatformKit-style CRUD APIs.

Example

Example shows constructing a Client with New over a stub transport and creating an entity.

package main

import (
	"context"
	"fmt"

	client "github.com/septagon-oss/pk-client"
)

// Widget is a small entity type used by the examples.
type Widget struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

// stubTransport is an in-memory CRUDTransport that returns canned responses, so
// the examples run without a network. Only the methods the examples exercise
// return meaningful data; the rest satisfy the interface.
type stubTransport struct{}

func (stubTransport) Type() client.TransportType { return client.TransportTypeHTTP }
func (stubTransport) Name() string               { return "stub" }

func (stubTransport) Create(_ context.Context, input *client.CreateInput[Widget]) (*client.ItemResponse[Widget], error) {
	created := input.Body
	created.ID = "widget-1"
	return &client.ItemResponse[Widget]{Data: created}, nil
}

func (stubTransport) GetByID(_ context.Context, id string) (*client.ItemResponse[Widget], error) {
	return &client.ItemResponse[Widget]{Data: Widget{ID: id, Name: "gadget"}}, nil
}

func (stubTransport) List(_ context.Context, _ *client.ListParams) (*client.ListResponse[Widget], error) {
	return &client.ListResponse[Widget]{
		Data:     []Widget{{ID: "widget-1", Name: "gadget"}},
		Metadata: &client.ListMetadata{Page: 1, PageSize: 25, TotalCount: 1, TotalPages: 1},
	}, nil
}

func (stubTransport) Update(_ context.Context, _ string, input *client.UpdateInput[Widget]) (*client.ItemResponse[Widget], error) {
	return &client.ItemResponse[Widget]{Data: input.Body}, nil
}

func (stubTransport) PartialUpdate(_ context.Context, id string, _ *client.PartialUpdateInput) (*client.ItemResponse[Widget], error) {
	return &client.ItemResponse[Widget]{Data: Widget{ID: id}}, nil
}

func (stubTransport) Delete(_ context.Context, _ string) error { return nil }

func (stubTransport) BulkCreate(_ context.Context, input *client.BulkCreateInput[Widget]) (*client.BulkResponse[Widget], error) {
	return &client.BulkResponse[Widget]{Succeeded: input.Items}, nil
}

func (stubTransport) BulkUpdate(_ context.Context, input *client.BulkUpdateInput[Widget]) (*client.BulkResponse[Widget], error) {
	return &client.BulkResponse[Widget]{Succeeded: input.Items}, nil
}

func (stubTransport) BulkDelete(_ context.Context, _ []string) error { return nil }

func (stubTransport) Export(_ context.Context, _ client.ExportParams) ([]byte, error) {
	return []byte("id,name\nwidget-1,gadget\n"), nil
}

func (stubTransport) Import(_ context.Context, _ []byte, _ string) (*client.ImportResponse, error) {
	return &client.ImportResponse{Imported: 1}, nil
}

func main() {
	c := client.New[Widget](stubTransport{})

	created, err := c.Create(context.Background(), client.CreateInput[Widget]{
		Body: Widget{Name: "gadget"},
	})
	if err != nil {
		fmt.Println("create failed:", err)
		return
	}
	fmt.Printf("created %s named %s\n", created.Data.ID, created.Data.Name)
}
Output:
created widget-1 named gadget

Index

Examples

Constants

This section is empty.

Variables

View Source
var (
	// ErrNilConfig indicates that a nil *HTTPConfig was supplied where a
	// configuration value was required.
	ErrNilConfig = errors.New("client: http config is required")
	// ErrBaseURLRequired indicates that HTTPConfig.BaseURL was empty after
	// trimming.
	ErrBaseURLRequired = errors.New("client: base URL is required")
	// ErrBaseURLInvalid indicates that HTTPConfig.BaseURL was not a valid
	// absolute URL (it must include both a scheme and a host).
	ErrBaseURLInvalid = errors.New("client: base URL must be an absolute URL")
	// ErrEntityPathRequired indicates that HTTPConfig.EntityPath was empty
	// after trimming.
	ErrEntityPathRequired = errors.New("client: entity path is required")
	// ErrEntityPathInvalid indicates that HTTPConfig.EntityPath contained a
	// query ('?') or fragment ('#') marker.
	ErrEntityPathInvalid = errors.New("client: entity path must not include query or fragment")
	// ErrHeaderKeyRequired indicates that a header or query-parameter map
	// contained an empty key after trimming.
	ErrHeaderKeyRequired = errors.New("client: header or query parameter key is required")
)

Errors returned by HTTPConfig.Normalize (and therefore by NewHTTPConfig consumers such as NewHTTP and NewHTTPTransport) when configuration is invalid. Match them with errors.Is to distinguish validation failures:

if errors.Is(err, client.ErrBaseURLRequired) {
	// the caller forgot to set BaseURL
}
View Source
var ErrNoTransport = errors.New("client: transport not configured")

ErrNoTransport is returned by Client methods invoked before a transport has been configured. A zero-value Client[T] (for example one declared with var rather than constructed via New or NewHTTP) has no transport, so every operation fails with this sentinel. Match it with errors.Is:

if errors.Is(err, client.ErrNoTransport) {
	// the client was never given a transport
}

Functions

This section is empty.

Types

type APIError

type APIError struct {
	StatusCode int    `json:"status_code"`
	Message    string `json:"message"`
	ErrorMsg   string `json:"error,omitempty"`
	Body       []byte `json:"-"`
}

APIError is returned for any HTTP response with a status code of 400 or higher. StatusCode holds the HTTP status code, Message and ErrorMsg carry the server-supplied detail (parsed from the JSON body when present), and Body holds the raw response body for callers that need the unparsed payload. The transport returns it as an error value, so recover the typed form with errors.As:

var apiErr *client.APIError
if errors.As(err, &apiErr) {
	log.Printf("status %d: %s", apiErr.StatusCode, apiErr.Body)
}

func (*APIError) Error

func (e *APIError) Error() string

Error implements the error interface, preferring the server-supplied error message, then the message field, then the standard text for the status code.

type BulkCreateInput

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

BulkCreateInput carries the entities to create in a single bulk request.

type BulkDeleteInput

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

BulkDeleteInput carries the ids to delete in a single bulk request.

type BulkError

type BulkError struct {
	ID    string `json:"id"`
	Error string `json:"error"`
}

BulkError identifies a single item that failed in a bulk operation by its ID and the associated Error message.

type BulkMetadata

type BulkMetadata struct {
	TotalCount     int `json:"total_count"`
	SucceededCount int `json:"succeeded_count"`
	FailedCount    int `json:"failed_count"`
}

BulkMetadata summarizes a bulk operation with the TotalCount of items submitted and the SucceededCount and FailedCount outcomes.

type BulkResponse

type BulkResponse[T any] struct {
	Succeeded []T           `json:"succeeded"`
	Failed    []BulkError   `json:"failed"`
	Metadata  *BulkMetadata `json:"metadata,omitempty"`
}

BulkResponse reports the outcome of a bulk operation. Succeeded holds the entities that were processed, Failed holds the per-item errors, and Metadata carries optional aggregate counts.

type BulkUpdateInput

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

BulkUpdateInput carries the entities to update in a single bulk request.

type CRUDTransport

type CRUDTransport[T any] interface {
	Transport

	Create(ctx context.Context, input *CreateInput[T]) (*ItemResponse[T], error)
	GetByID(ctx context.Context, id string) (*ItemResponse[T], error)
	List(ctx context.Context, params *ListParams) (*ListResponse[T], error)
	Update(ctx context.Context, id string, input *UpdateInput[T]) (*ItemResponse[T], error)
	PartialUpdate(ctx context.Context, id string, input *PartialUpdateInput) (*ItemResponse[T], error)
	Delete(ctx context.Context, id string) error

	BulkCreate(ctx context.Context, input *BulkCreateInput[T]) (*BulkResponse[T], error)
	BulkUpdate(ctx context.Context, input *BulkUpdateInput[T]) (*BulkResponse[T], error)
	BulkDelete(ctx context.Context, ids []string) error

	Export(ctx context.Context, params ExportParams) ([]byte, error)
	Import(ctx context.Context, data []byte, format string) (*ImportResponse, error)
}

CRUDTransport defines the transport-safe CRUD surface exposed by PlatformKit.

type Client

type Client[T any] struct {
	// contains filtered or unexported fields
}

Client provides transport-agnostic CRUD operations for PlatformKit APIs.

The type parameter T is the entity type carried by request and response bodies. A Client delegates every operation to its CRUDTransport, so the same facade works over HTTP today and other transports in the future. Construct one with New (any transport) or NewHTTP (the bundled HTTP transport); a zero-value Client has no transport and returns ErrNoTransport from every method.

func New

func New[T any](transport CRUDTransport[T]) *Client[T]

New returns a Client backed by the supplied transport. It performs no validation: callers that need configuration checks should build their transport (for example via NewHTTPTransport) before passing it in. Use NewHTTP for the common case of an HTTP client built from an HTTPConfig.

func NewHTTP

func NewHTTP[T any](config *HTTPConfig) (*Client[T], error)

NewHTTP builds a Client backed by an HTTP transport derived from config. The config is normalized and validated (see HTTPConfig.Normalize); NewHTTP returns the resulting error and a nil Client if the config is invalid.

func (*Client[T]) BulkCreate

func (c *Client[T]) BulkCreate(ctx context.Context, input BulkCreateInput[T]) (*BulkResponse[T], error)

BulkCreate creates multiple entities in a single request and returns the per-item outcomes. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) BulkDelete

func (c *Client[T]) BulkDelete(ctx context.Context, ids []string) error

BulkDelete removes multiple entities identified by ids in a single request. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) BulkUpdate

func (c *Client[T]) BulkUpdate(ctx context.Context, input BulkUpdateInput[T]) (*BulkResponse[T], error)

BulkUpdate updates multiple entities in a single request and returns the per-item outcomes. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) Create

func (c *Client[T]) Create(ctx context.Context, input CreateInput[T]) (*ItemResponse[T], error)

Create sends input to the transport to create a single entity and returns the created item. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) Delete

func (c *Client[T]) Delete(ctx context.Context, id string) error

Delete removes the entity identified by id. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) Export

func (c *Client[T]) Export(ctx context.Context, params ExportParams) ([]byte, error)

Export retrieves a serialized export of the collection described by params (for example as CSV or JSON) and returns the raw bytes. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) GetByID

func (c *Client[T]) GetByID(ctx context.Context, id string) (*ItemResponse[T], error)

GetByID fetches a single entity by its id. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) Import

func (c *Client[T]) Import(ctx context.Context, data []byte, format string) (*ImportResponse, error)

Import uploads data in the named format (for example "json" or "csv") and returns a summary of how many records were imported or failed. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) List

func (c *Client[T]) List(ctx context.Context, params ListParams) (*ListResponse[T], error)

List fetches a page of entities matching params and returns the items together with pagination metadata. It returns ErrNoTransport if the Client has no transport.

Example

ExampleClient_List shows listing entities and reading pagination metadata.

package main

import (
	"context"
	"fmt"

	client "github.com/septagon-oss/pk-client"
)

// Widget is a small entity type used by the examples.
type Widget struct {
	ID   string `json:"id"`
	Name string `json:"name"`
}

// stubTransport is an in-memory CRUDTransport that returns canned responses, so
// the examples run without a network. Only the methods the examples exercise
// return meaningful data; the rest satisfy the interface.
type stubTransport struct{}

func (stubTransport) Type() client.TransportType { return client.TransportTypeHTTP }
func (stubTransport) Name() string               { return "stub" }

func (stubTransport) Create(_ context.Context, input *client.CreateInput[Widget]) (*client.ItemResponse[Widget], error) {
	created := input.Body
	created.ID = "widget-1"
	return &client.ItemResponse[Widget]{Data: created}, nil
}

func (stubTransport) GetByID(_ context.Context, id string) (*client.ItemResponse[Widget], error) {
	return &client.ItemResponse[Widget]{Data: Widget{ID: id, Name: "gadget"}}, nil
}

func (stubTransport) List(_ context.Context, _ *client.ListParams) (*client.ListResponse[Widget], error) {
	return &client.ListResponse[Widget]{
		Data:     []Widget{{ID: "widget-1", Name: "gadget"}},
		Metadata: &client.ListMetadata{Page: 1, PageSize: 25, TotalCount: 1, TotalPages: 1},
	}, nil
}

func (stubTransport) Update(_ context.Context, _ string, input *client.UpdateInput[Widget]) (*client.ItemResponse[Widget], error) {
	return &client.ItemResponse[Widget]{Data: input.Body}, nil
}

func (stubTransport) PartialUpdate(_ context.Context, id string, _ *client.PartialUpdateInput) (*client.ItemResponse[Widget], error) {
	return &client.ItemResponse[Widget]{Data: Widget{ID: id}}, nil
}

func (stubTransport) Delete(_ context.Context, _ string) error { return nil }

func (stubTransport) BulkCreate(_ context.Context, input *client.BulkCreateInput[Widget]) (*client.BulkResponse[Widget], error) {
	return &client.BulkResponse[Widget]{Succeeded: input.Items}, nil
}

func (stubTransport) BulkUpdate(_ context.Context, input *client.BulkUpdateInput[Widget]) (*client.BulkResponse[Widget], error) {
	return &client.BulkResponse[Widget]{Succeeded: input.Items}, nil
}

func (stubTransport) BulkDelete(_ context.Context, _ []string) error { return nil }

func (stubTransport) Export(_ context.Context, _ client.ExportParams) ([]byte, error) {
	return []byte("id,name\nwidget-1,gadget\n"), nil
}

func (stubTransport) Import(_ context.Context, _ []byte, _ string) (*client.ImportResponse, error) {
	return &client.ImportResponse{Imported: 1}, nil
}

func main() {
	c := client.New[Widget](stubTransport{})

	page, err := c.List(context.Background(), client.ListParams{Page: 1, PageSize: 25})
	if err != nil {
		fmt.Println("list failed:", err)
		return
	}
	fmt.Printf("%d of %d items\n", len(page.Data), page.Metadata.TotalCount)
}
Output:
1 of 1 items

func (*Client[T]) PartialUpdate

func (c *Client[T]) PartialUpdate(ctx context.Context, id string, input PartialUpdateInput) (*ItemResponse[T], error)

PartialUpdate applies a partial set of field updates to the entity identified by id and returns the updated item. If input.ID is empty it is set to id before the call. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) Transport

func (c *Client[T]) Transport() CRUDTransport[T]

Transport returns the CRUDTransport currently backing the Client, or nil if none has been configured.

func (*Client[T]) Update

func (c *Client[T]) Update(ctx context.Context, id string, input UpdateInput[T]) (*ItemResponse[T], error)

Update replaces the entity identified by id with input and returns the updated item. If input.ID is empty it is set to id before the call. It returns ErrNoTransport if the Client has no transport.

func (*Client[T]) WithTransport

func (c *Client[T]) WithTransport(transport CRUDTransport[T]) *Client[T]

WithTransport returns a copy of the Client that uses the supplied transport, leaving the receiver unchanged. It is a convenience for swapping transports (for example a test stub) without mutating a shared client.

type Config

type Config interface {
	Validate() error
	GetType() TransportType
}

Config validates transport-specific configuration.

type CreateInput

type CreateInput[T any] struct {
	Body T `json:"body"`
}

CreateInput wraps the entity body for a create request.

type ExportParams

type ExportParams struct {
	Format string   `json:"format,omitempty"`
	Filter *Filter  `json:"filter,omitempty"`
	Fields []string `json:"fields,omitempty"`
}

ExportParams selects the serialization Format, an optional Filter to restrict the exported rows, and the optional Fields to include in the export.

type Filter

type Filter struct {
	Field    string   `json:"field,omitempty"`
	Operator string   `json:"operator,omitempty"`
	Value    any      `json:"value,omitempty"`
	All      []Filter `json:"all,omitempty"`
	Any      []Filter `json:"any,omitempty"`
	Not      *Filter  `json:"not,omitempty"`
}

Filter expresses a query predicate. A leaf filter uses Field, Operator, and Value; a composite filter combines sub-filters with All (logical AND) or Any (logical OR), and Not negates a single sub-filter. The forms are mutually exclusive in practice — set either the leaf fields or one of the boolean combinators.

type HTTPConfig

type HTTPConfig struct {
	BaseURL     string            `json:"base_url"`
	EntityPath  string            `json:"entity_path"`
	APIKey      string            `json:"api_key,omitempty"`
	Timeout     time.Duration     `json:"timeout"`
	Headers     map[string]string `json:"headers,omitempty"`
	QueryParams map[string]string `json:"query_params,omitempty"`
	HTTPClient  *http.Client      `json:"-"`
}

HTTPConfig describes how an HTTP CRUD transport reaches a PlatformKit API. BaseURL and EntityPath together locate the collection endpoint (for example "https://api.example.com" + "/api/widgets"); the remaining fields are optional. APIKey, Headers, QueryParams, and Timeout customize every request, and HTTPClient supplies a caller-owned *http.Client when the default is not suitable. Build one with NewHTTPConfig and refine it with the With* helpers or Option values.

func NewHTTPConfig

func NewHTTPConfig(baseURL, entityPath string, options ...Option) *HTTPConfig

NewHTTPConfig returns an HTTPConfig for the given base URL and entity path with a 30-second default timeout and empty header and query-parameter maps. Each non-nil Option is applied in order, so later options override earlier ones. The returned config is not yet normalized; NewHTTP and NewHTTPTransport call Normalize for you.

func (*HTTPConfig) GetType

func (c *HTTPConfig) GetType() TransportType

GetType reports the transport this config configures, always TransportTypeHTTP. It satisfies the Config interface.

func (*HTTPConfig) Normalize added in v0.1.0

func (c *HTTPConfig) Normalize() error

Normalize validates the config and rewrites the receiver in place with defaults applied (trimmed base URL, default timeout, copied header/query maps). It returns one of the package's sentinel errors (ErrBaseURLRequired, ErrBaseURLInvalid, ErrEntityPathRequired, ErrEntityPathInvalid, or ErrHeaderKeyRequired) if the config is invalid, matchable with errors.Is. The name makes the mutation explicit — unlike a plain Validate, calling this changes c.

func (*HTTPConfig) WithBearerToken

func (c *HTTPConfig) WithBearerToken(token string) *HTTPConfig

WithBearerToken sets an "Authorization: Bearer <token>" header and returns the receiver for chaining. The token is trimmed; an empty token is ignored.

func (*HTTPConfig) WithHTTPClient

func (c *HTTPConfig) WithHTTPClient(client *http.Client) *HTTPConfig

WithHTTPClient sets a caller-owned *http.Client to use for requests and returns the receiver for chaining. When set, the config Timeout is not applied automatically; configure the timeout on the supplied client instead.

func (*HTTPConfig) WithHeader

func (c *HTTPConfig) WithHeader(key, value string) *HTTPConfig

WithHeader sets a request header to send on every request and returns the receiver for chaining. The key is trimmed; an empty key is ignored.

func (*HTTPConfig) WithQueryParam

func (c *HTTPConfig) WithQueryParam(key, value string) *HTTPConfig

WithQueryParam sets a static query parameter to append to every request URL and returns the receiver for chaining. The key is trimmed; an empty key is ignored.

type HTTPTransport

type HTTPTransport[T any] struct {
	// contains filtered or unexported fields
}

HTTPTransport is the standard-library CRUDTransport that talks to a PlatformKit HTTP API. The type parameter T is the entity type carried by request and response bodies. It owns a normalized copy of its HTTPConfig, so mutating the original config after construction does not affect the transport. Construct one with NewHTTPTransport, or use NewHTTP to wrap one in a Client.

func NewHTTPTransport

func NewHTTPTransport[T any](config *HTTPConfig) (*HTTPTransport[T], error)

NewHTTPTransport builds an HTTPTransport from config. The config is normalized and validated (see HTTPConfig.Normalize), and a copy is retained so later mutation of the caller's config has no effect. If config.HTTPClient is nil, a default *http.Client using config.Timeout is created. It returns the normalization error and a nil transport when config is invalid.

func (*HTTPTransport[T]) BulkCreate

func (t *HTTPTransport[T]) BulkCreate(ctx context.Context, input *BulkCreateInput[T]) (*BulkResponse[T], error)

BulkCreate issues a POST to the collection's "bulk" endpoint to create many entities at once and decodes the per-item outcomes. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) BulkDelete

func (t *HTTPTransport[T]) BulkDelete(ctx context.Context, ids []string) error

BulkDelete issues a DELETE to the collection's "bulk" endpoint with the supplied ids in the request body. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) BulkUpdate

func (t *HTTPTransport[T]) BulkUpdate(ctx context.Context, input *BulkUpdateInput[T]) (*BulkResponse[T], error)

BulkUpdate issues a PUT to the collection's "bulk" endpoint to update many entities at once and decodes the per-item outcomes. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) Create

func (t *HTTPTransport[T]) Create(ctx context.Context, input *CreateInput[T]) (*ItemResponse[T], error)

Create issues a POST to the collection endpoint to create a single entity and decodes the created item. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) Delete

func (t *HTTPTransport[T]) Delete(ctx context.Context, id string) error

Delete issues a DELETE to the entity endpoint for id. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) Export

func (t *HTTPTransport[T]) Export(ctx context.Context, params ExportParams) ([]byte, error)

Export issues a GET to the collection's "export" endpoint with params encoded as query parameters and returns the raw response body unparsed. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) GetByID

func (t *HTTPTransport[T]) GetByID(ctx context.Context, id string) (*ItemResponse[T], error)

GetByID issues a GET to the entity endpoint for id and decodes the item. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) Import

func (t *HTTPTransport[T]) Import(ctx context.Context, data []byte, format string) (*ImportResponse, error)

Import issues a POST to the collection's "import" endpoint, sending data as the raw request body with a Content-Type derived from format (for example "json" or "csv") and a matching format query parameter. It decodes and returns the import summary, and returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) List

func (t *HTTPTransport[T]) List(ctx context.Context, params *ListParams) (*ListResponse[T], error)

List issues a GET to the collection endpoint with params encoded as query parameters and decodes the page of items and metadata. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) Name

func (t *HTTPTransport[T]) Name() string

Name returns the human-readable transport name, "http". It satisfies the Transport interface.

func (*HTTPTransport[T]) PartialUpdate

func (t *HTTPTransport[T]) PartialUpdate(ctx context.Context, id string, input *PartialUpdateInput) (*ItemResponse[T], error)

PartialUpdate issues a PATCH to the entity endpoint for id to apply a partial set of field updates and decodes the updated item. It returns an *APIError for non-2xx responses.

func (*HTTPTransport[T]) Type

func (t *HTTPTransport[T]) Type() TransportType

Type reports the transport kind, always TransportTypeHTTP. It satisfies the Transport interface.

func (*HTTPTransport[T]) Update

func (t *HTTPTransport[T]) Update(ctx context.Context, id string, input *UpdateInput[T]) (*ItemResponse[T], error)

Update issues a PUT to the entity endpoint for id to replace the entity and decodes the updated item. It returns an *APIError for non-2xx responses.

type ImportResponse

type ImportResponse struct {
	Imported int      `json:"imported"`
	Failed   int      `json:"failed"`
	Errors   []string `json:"errors,omitempty"`
}

ImportResponse summarizes an import: the number of records Imported, the number that Failed, and any per-record Errors.

type ItemResponse

type ItemResponse[T any] struct {
	Data     T              `json:"data"`
	Metadata map[string]any `json:"metadata,omitempty"`
}

ItemResponse is the envelope for a single entity. Data holds the entity and Metadata carries optional server-supplied annotations.

type ListMetadata

type ListMetadata struct {
	Page       int   `json:"page"`
	PageSize   int   `json:"page_size"`
	TotalCount int64 `json:"total_count"`
	TotalPages int   `json:"total_pages"`
}

ListMetadata describes the pagination state of a ListResponse: the current Page, the PageSize, the TotalCount of matching rows, and the TotalPages available.

type ListParams

type ListParams struct {
	Page           int      `json:"page,omitempty"`
	PageSize       int      `json:"page_size,omitempty"`
	Offset         int      `json:"offset,omitempty"`
	Search         string   `json:"search,omitempty"`
	Sort           string   `json:"sort,omitempty"`
	Order          string   `json:"order,omitempty"`
	Filter         *Filter  `json:"filter,omitempty"`
	Fields         []string `json:"fields,omitempty"`
	Embed          []string `json:"embed,omitempty"`
	IncludeDeleted bool     `json:"include_deleted,omitempty"`
}

ListParams describes pagination, ordering, filtering, and projection for a List request. All fields are optional; zero values are omitted from the request. Page/PageSize and Offset are alternative pagination styles, Sort and Order set ordering, Filter restricts results, Fields and Embed project the response, and IncludeDeleted opts in to soft-deleted rows.

type ListResponse

type ListResponse[T any] struct {
	Data     []T           `json:"data"`
	Metadata *ListMetadata `json:"metadata,omitempty"`
}

ListResponse is the envelope for a page of entities. Data holds the items and Metadata carries optional pagination details.

type Option

type Option func(*HTTPConfig)

Option configures an HTTPConfig during construction. Options are applied in order by NewHTTPConfig, so a later Option overrides an earlier one. The With* constructors in this package return ready-to-use Option values.

func WithAPIKey

func WithAPIKey(apiKey string) Option

WithAPIKey returns an Option that sets the API key sent as a bearer token in the Authorization header when no explicit Authorization header is present.

func WithBearerToken

func WithBearerToken(token string) Option

WithBearerToken returns an Option that sets an "Authorization: Bearer <token>" header. An empty token is ignored.

func WithHeader

func WithHeader(key, value string) Option

WithHeader returns an Option that sets a request header sent on every request. An empty key is ignored.

func WithQueryParam

func WithQueryParam(key, value string) Option

WithQueryParam returns an Option that sets a static query parameter appended to every request URL. An empty key is ignored.

func WithTimeout

func WithTimeout(timeout time.Duration) Option

WithTimeout returns an Option that sets the request timeout. A non-positive timeout is replaced with the 30-second default during normalization. The timeout is ignored when a custom *http.Client is supplied via HTTPConfig.WithHTTPClient.

type PartialUpdateInput

type PartialUpdateInput struct {
	ID      string         `json:"id,omitempty"`
	Updates map[string]any `json:"updates"`
}

PartialUpdateInput carries a sparse set of field updates for a partial (PATCH) update. ID is optional and is populated from the request path id when empty. Updates maps field names to their new values.

type Transport

type Transport interface {
	Type() TransportType
	Name() string
}

Transport is the base contract shared by all client transports.

type TransportType

type TransportType string

TransportType identifies a client transport implementation.

const (
	// TransportTypeHTTP identifies the bundled standard-library HTTP transport.
	TransportTypeHTTP TransportType = "http"
)

type UpdateInput

type UpdateInput[T any] struct {
	ID   string `json:"id,omitempty"`
	Body T      `json:"body"`
}

UpdateInput wraps the entity body for a full replacement (PUT) update. ID is optional and is populated from the request path id when empty.

Jump to

Keyboard shortcuts

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