apic

package module
v0.0.0-...-45d8c98 Latest Latest
Warning

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

Go to latest
Published: Nov 28, 2025 License: MIT Imports: 15 Imported by: 0

README

apic

api clients, because who has time for that? this is a little library to gsd

http

fire up an http client real easy like:

package main

import(
    "fmt"
    "log/slog"

    "https://github.com/rileyr/apic"
)

func main() {
    client := apic.NewHTTPClient("my-cool-api-root",
        apic.WithLogger(slog.Default()),
        apic.WithBefore(addAuthSignature),
    )

    type request struct{
        Foo string
        Bar struct {
            Biz int
        }
    }

    type response struct {
        Id   int
        Whiz string
    }

    // blah blah imagine these are filled in:
    var (
        req request
        rsp response
    )

    if err := client.Post("/some/path", req, &rsp); err != nil{
        panic("OH MY GOSH " + err.Error())
    }

    fmt.Printf("Got a response!:\n%#v\n", rsp)
}

func addAuthSignature(req *http.Request) error {
    req.Header.Add("AUTH", os.Getenv("SUPER_SECURE_SECRETS"))
    return nil
}

ws

get that ws goin like nothing:

package main

import(
    "context"
    "log/slog"
    "sync/errgroup"

    "golang.org/x/sync/errgroup"
    "github.com/rileyr/apic"
)

func main() {
    ws := apic.NewWSClient("ws://so-cool-ws-endpoint",
        apic.WithWSLoger(slog.Default()),
        apic.WithWSOnOpen(func(c *WSClient) error {
            slog.Default().Info("we are connected!")
            return nil
        }),
        apic.WithWSHandler(func(bts []byte) error {
            slog.Default().Info("we have something!", "message", string(bts))
            return nil
        }),
        apic.WithReconnectBackoff(time.Minute*5),
    }

    if err := ws.Start(context.Background()); err != nil {
        log.Printf("fatal err: %s\n", err.Error())
        os.Exit(1)
    }

    // or maybe the connection is feeding into a larger app,
    // the client can be run in an errgroup easily:
    wg, ctx := errgroup.WithContext(context.Background()) 
    wg.Go(func() error { return ws.Start(ctx) })
}

Documentation

Index

Constants

This section is empty.

Variables

View Source
var ErrNotConnected = errors.New("websocket not connected")
View Source
var (
	MaxAttemptsError = errors.New("max connection attempts")
)

Functions

func GetResponseErrorCode

func GetResponseErrorCode(err error) int

func WithHeader

func WithHeader(key, value string) func(http.Header)

Types

type DecodeError

type DecodeError struct {
	Body []byte
	Err  error
}

func (DecodeError) Error

func (e DecodeError) Error() string

type Decoder

type Decoder func([]byte, any) error

type DialOptions

type DialOptions = websocket.DialOptions

type Encoder

type Encoder func(any) ([]byte, error)

type HTTPClient

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

func NewHTTPClient

func NewHTTPClient(root string, opts ...HTTPOption) *HTTPClient

func (*HTTPClient) Delete

func (c *HTTPClient) Delete(path string, data any, dest any) error

func (*HTTPClient) Do

func (c *HTTPClient) Do(method, path string, body io.Reader, dest any, hdrs ...HeaderFunc) error

func (*HTTPClient) DoHeader

func (c *HTTPClient) DoHeader(method, path string, body io.Reader, dest any, hdrs ...HeaderFunc) (http.Header, error)

func (*HTTPClient) Get

func (c *HTTPClient) Get(path string, params url.Values, dest any) error

func (*HTTPClient) Patch

func (c *HTTPClient) Patch(path string, data any, dest any) error

func (*HTTPClient) Post

func (c *HTTPClient) Post(path string, data any, dest any, hdrs ...HeaderFunc) error

func (*HTTPClient) Put

func (c *HTTPClient) Put(path string, data any, dest any) error

type HTTPOption

type HTTPOption func(*HTTPClient)

func WithBefore

func WithBefore(fn func(*http.Request) error) HTTPOption

func WithClient

func WithClient(c *http.Client) HTTPOption

func WithDecoder

func WithDecoder(fn func([]byte, any) error) HTTPOption

func WithEncoder

func WithEncoder(fn func(obj any) ([]byte, error)) HTTPOption

func WithLoggedBodies

func WithLoggedBodies() HTTPOption

func WithLogger

func WithLogger(lg Logger) HTTPOption

func WithMaxStatus

func WithMaxStatus(code int) HTTPOption

func WithRateLimit

func WithRateLimit(r rate.Limit, b int) HTTPOption

func WithSensitiveHeader

func WithSensitiveHeader(keys ...string) HTTPOption

type HeaderFunc

type HeaderFunc func(http.Header)

type Logger

type Logger interface {
	Info(msg string, args ...any)
	Debug(msg string, args ...any)
}

type PingHandler

type PingHandler func(context.Context, *WSClient) error

type ResponseError

type ResponseError struct {
	Code int
	Body []byte
}

func (ResponseError) Error

func (e ResponseError) Error() string

type WSClient

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

func NewWSClient

func NewWSClient(endpoint string, opts ...WSOption) *WSClient

func (*WSClient) Close

func (c *WSClient) Close() error

Close gracefully closes the WebSocket connection.

func (*WSClient) IsConnected

func (c *WSClient) IsConnected() bool

IsConnected returns true if the WebSocket is currently connected.

func (*WSClient) Send

func (c *WSClient) Send(ctx context.Context, bts []byte) error

func (*WSClient) Start

func (c *WSClient) Start(ctx context.Context) error

Start runs the client until either: - the context is canceled - the reconnect policy returns false - Stop() is called

func (*WSClient) Stop

func (c *WSClient) Stop(reason string) error

func (*WSClient) Write

func (c *WSClient) Write(ctx context.Context, obj any) error

Write encodes and writes an object to the current connection.

type WSOption

type WSOption func(*WSClient)

func WithDialOptions

func WithDialOptions(fn func() (*DialOptions, error)) WSOption

WithDialOptions allows callers to inject dial options in to the underlying lib.

func WithEndpointFunc

func WithEndpointFunc(fn func() (string, error)) WSOption

func WithMaxAttempts

func WithMaxAttempts(n int) WSOption

func WithPingHandler

func WithPingHandler(ph PingHandler) WSOption

func WithPingInterval

func WithPingInterval(i time.Duration) WSOption

WithPingInterval sets the ping interval

func WithReconnectBackoff

func WithReconnectBackoff(maxBackoff time.Duration) WSOption

WithReconnect enables exponential backoff behavior on reconnect.

func WithStaleDetection

func WithStaleDetection(timeout time.Duration) WSOption

WithStaleDetection, if configured, will create a goroutine that asserts on the websocket having received some message within some recent time interval. If the assertion fails, the connection is closed, and whatever reconnect behavior has been configured will take over.

func WithWSEncoder

func WithWSEncoder(fn func(any) ([]byte, error)) WSOption

WithWSEncoder sets the encoder for objects written to the client

func WithWSHandler

func WithWSHandler(fn func([]byte) error) WSOption

WithWSHandler sets the global message handler for the client.

func WithWSLogger

func WithWSLogger(l Logger) WSOption

WithWSLogger sets the logger for the websocket client.

func WithWSOnClose

func WithWSOnClose(fn func(*WSClient) error) WSOption

WithWSOnOpen sets the callback called whenver a connection is closed.

func WithWSOnOpen

func WithWSOnOpen(fn func(*WSClient) error) WSOption

WithWSOnOpen sets the callback called whenver a new connection is opened.

func WithWriteLimiter

func WithWriteLimiter(r rate.Limit, b int) WSOption

WithWriteLimiter adds rate limiting behavior to Write() calls

Jump to

Keyboard shortcuts

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