Skip to content

std/connect

import "github.com/eugenioenko/goalchemy/std/connect"

Package connect is a Connect protocol client for unary calls with the JSON codec, the transport behind services generated by protoc-gen-goalchemy. It follows connectrpc.com/connect: requests are POSTed as application/json with Connect-Protocol-Version 1, and error responses become *Error with the codes, messages and details connect-go reports. Calls suspend on the host HTTP client, so programs use the cooperative gate.

const DefaultMaxResponseBytes = 16 << 20

DefaultMaxResponseBytes bounds responses of a client whose MaxResponseBytes is zero.

const DefaultTimeoutMillis = 30000

DefaultTimeoutMillis bounds calls of a client whose TimeoutMillis is zero.

type Client struct {
BaseURL string
Headers []string
TimeoutMillis int64
MaxResponseBytes int
// SendTimeout sends the call's timeout as Connect-Timeout-Ms so the
// server can bound its work. It is off by default: connect-go sends the
// header only for a context with a deadline, and browsers fail the CORS
// preflight of servers that do not allow it.
SendTimeout bool
// Transport holds lib/http.DoWith options, such as a client certificate
// or extra root CAs. It is ignored when HTTPClient is set.
Transport []string
// HTTPClient, when set, sends every call instead of lib/http.DoWith.
HTTPClient HTTPClient
}

Client calls one Connect server. Headers are sent with every call as alternating names and values.

func NewClient(baseURL string) *Client

NewClient returns a client for the server at baseURL, such as “https://platform.example.com”.

func (c *Client) CallUnary(ctx context.Context, procedure string, req, resp protojson.Message, headers []string) ([]string, error)

CallUnary sends req to procedure, such as “/policy.attributes.AttributesService/GetAttribute”, and decodes the reply into resp. headers are added to the client’s for this call. It returns the response headers.

type Code uint32

Code is a Connect error code.

const (
CodeCanceled Code = 1
CodeUnknown Code = 2
CodeInvalidArgument Code = 3
CodeDeadlineExceeded Code = 4
CodeNotFound Code = 5
CodeAlreadyExists Code = 6
CodePermissionDenied Code = 7
CodeResourceExhausted Code = 8
CodeFailedPrecondition Code = 9
CodeAborted Code = 10
CodeOutOfRange Code = 11
CodeUnimplemented Code = 12
CodeInternal Code = 13
CodeUnavailable Code = 14
CodeDataLoss Code = 15
CodeUnauthenticated Code = 16
)
func CodeOf(err error) Code

CodeOf returns the code of a *Error in err’s chain, CodeUnknown for other errors and 0 for nil.

func (c Code) String() string

String returns the code’s wire name, such as “not_found”.

type Error struct {
Code Code
Message string
Details []*ErrorDetail
Meta []string
}

Error is a failed call. Meta holds the response headers as alternating names and values.

func (e *Error) Error() string
type ErrorDetail struct {
TypeURL string
Value []byte
Debug jsonvalue.Value
}

ErrorDetail is one entry of an error’s details: a protobuf message packed as its type URL and binary encoding, with an optional JSON debug form.

type HTTPClient interface {
Do(ctx context.Context, method, url string, headers []string, body []byte, maxResponseBytes int, timeoutMillis int64) (int, []string, []byte, error)
}

HTTPClient sends one bounded HTTP exchange with the arguments and results of lib/http.Do: headers alternate names and values, and a non-2xx status is a result, not an error. It is connect-go’s HTTPClient, the place to add authentication, DPoP proofs or an allowlist.