Documentation
¶
Overview ¶
Package batchdata is the foundation of a small Go SDK for the BatchData V3 API.
It provides the Client, an authenticated and immutable connection, and the error surface every service shares. Typed access to each API lives in its own package, such as github.com/mrz1836/go-batchdata/skiptrace, so importing one service pulls in only that service, this package and the standard library.
Construct a client once and hand it to a service:
client, err := batchdata.NewClient(apiKey)
if err != nil {
return err
}
tracer := skiptrace.New(client)
res, err := tracer.Trace(ctx, req)
The SDK makes at most one HTTP attempt per call. It never retries, follows redirects, replays a request or reads the environment for credentials. Every call may be billed, and a failed call may already have been processed.
Index ¶
Examples ¶
Constants ¶
const ( // DefaultTimeout bounds one call unless WithTimeout says otherwise: dial, // send and the full body read. DefaultTimeout = 60 * time.Second // DefaultMaxResponseBytes is the default response body limit. DefaultMaxResponseBytes = 8 << 20 // MaxResponseBytesLimit is the largest limit WithMaxResponseBytes accepts. MaxResponseBytesLimit = 64 << 20 // MaxRequestBytes bounds an encoded request body. A larger request fails // locally with ErrInvalidRequest. MaxRequestBytes = 1 << 20 )
Client defaults and limits.
Variables ¶
var ( // ErrInvalidConfig reports an invalid NewClient argument or option, or a // service built from a nil or zero Client. ErrInvalidConfig = errors.New("batchdata: invalid configuration") // ErrInvalidRequest reports a nil context or a request that fails local // validation, including one whose encoded body exceeds MaxRequestBytes. ErrInvalidRequest = errors.New("batchdata: invalid request") // ErrRejected reports a call the provider refused: an HTTP status other // than 2xx (a redirect included, which is never followed), or an HTTP 200 // whose body reports a status code other than 200. ErrRejected = errors.New("batchdata: rejected by provider") // or revoked token. It also matches ErrRejected. ErrUnauthorized = errors.New("batchdata: unauthorized") // ErrForbidden reports a rejection with status 403. BatchData uses 403 for // both insufficient permissions and insufficient balance; the SDK does not // guess which. It also matches ErrRejected. ErrForbidden = errors.New("batchdata: forbidden") // ErrRateLimited reports a rejection with status 429. It also matches // ErrRejected. ErrRateLimited = errors.New("batchdata: rate limited") // ErrMalformedResponse reports a response the SDK cannot use: a 2xx status // other than 200, a body over the size limit, or an HTTP 200 body that is // not the documented envelope, carries a Content-Encoding nobody decoded, // or holds far more JSON objects, arrays or values than any real answer. // The call may already have been processed and billed. ErrMalformedResponse = errors.New("batchdata: malformed response") )
Sentinel errors. Match them with errors.Is.
ErrInvalidConfig and ErrInvalidRequest are local: an error matching either means no call was made. Every other sentinel is matched only by an *Error.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is an authenticated connection to the BatchData API, shared by the service packages such as skiptrace. It is immutable after NewClient and safe for concurrent use.
Both methods have value receivers, so printing a Client or a *Client with fmt goes through String or GoString. The API key, the URL and the HTTP client exist only inside a function the Client holds: fmt prints a func as an address with every verb, even through unexported fields, and reflection-based dumpers cannot see what a function captures.
The zero Client is unusable: a service built from it, or from a nil *Client, reports ErrInvalidConfig on every call and makes none.
func NewClient ¶
NewClient returns a Client that authenticates with apiKey, sent as a bearer token. apiKey must be 1 to 4096 bytes of visible ASCII (no spaces or control characters); the SDK never reads it from the environment.
NewClient performs no I/O. An invalid argument or option returns a *ValidationError matching ErrInvalidConfig; its message never repeats the rejected value.
Create one Client per token and share it. Without WithHTTPClient, each Client owns a connection pool that cannot be closed; idle connections close on their own after 90 seconds. An application that holds many tokens should pass the same *http.Client to every Client with WithHTTPClient, so that they share one pool.
Example ¶
The application decides where the key comes from; the SDK reads no environment. Printing a client never shows the key.
package main
import (
"fmt"
"time"
"github.com/mrz1836/go-batchdata"
)
func main() {
apiKey := "EXAMPLE-KEY-0000" // for example, from a secret manager
client, err := batchdata.NewClient(apiKey,
batchdata.WithTimeout(45*time.Second),
batchdata.WithUserAgent("example-app/1.0"),
)
if err != nil {
fmt.Println(err)
return
}
fmt.Println(client)
}
Output: batchdata.Client{timeout: 45s, maxResponseBytes: 8388608}
Example (InvalidOption) ¶
An invalid option fails before any call, and the error names the option without repeating its value.
package main
import (
"errors"
"fmt"
"github.com/mrz1836/go-batchdata"
)
func main() {
_, err := batchdata.NewClient("EXAMPLE-KEY-0000", batchdata.WithTimeout(0))
fmt.Println(errors.Is(err, batchdata.ErrInvalidConfig))
fmt.Println(err)
}
Output: true batchdata: invalid configuration: WithTimeout: must be positive
type Error ¶
type Error struct {
// Kind classifies the failure.
Kind Kind
// StatusCode is the HTTP status, or 0 when no response arrived.
StatusCode int
// ProviderCode is the status.code the response body reported, when the
// body could be decoded; otherwise 0.
ProviderCode int
// RetryAfter is the Retry-After hint, clamped to [0, 24h].
RetryAfter time.Duration
// HasRetryAfter reports whether the response carried a usable
// Retry-After header.
HasRetryAfter bool
// contains filtered or unexported fields
}
Error describes a call that passed local validation and then failed: the attempt failed, or it was never made because the context was already done. It is always returned as a *Error.
Its Error string is built from a fixed vocabulary: the kind and the status codes. It never contains the API key, URLs, request or response bodies, provider messages or network addresses, and neither do GoString, fmt verbs that print fields, or the chain Unwrap returns. Provider text is available only through ProviderMessage and Warnings.
RetryAfter is the provider's standard Retry-After hint, when it sent one. It is a hint, not proof that repeating the call is safe or free. HasRetryAfter distinguishes an explicit zero from an absent hint.
func (*Error) Error ¶
Error returns "batchdata: <kind>", with the HTTP status and the provider status when known, such as "batchdata: rejected (HTTP 429)".
func (*Error) GoString ¶
GoString prints the exported fields only, so %#v cannot reveal the provider's text.
func (*Error) Is ¶
Is reports whether target is a sentinel this error matches: ErrRejected for KindRejected, plus ErrUnauthorized, ErrForbidden or ErrRateLimited for status 401, 403 or 429, and ErrMalformedResponse for KindMalformedResponse and KindResponseTooLarge.
A rejection with an HTTP status other than 200 is matched by that HTTP status; an HTTP 200 whose body reports another status is matched by ProviderCode.
func (*Error) ProviderMessage ¶
ProviderMessage returns the status.message text of the provider's response body, or "" when there was none or it could not be decoded. It may echo request content, so treat it as sensitive: it is excluded from Error and GoString, and logging it is the caller's decision.
type Kind ¶
type Kind string
Kind classifies a failed call. The list is closed.
const ( // KindCanceled means the caller's context was canceled. It matches // context.Canceled. KindCanceled Kind = "canceled" // KindDeadlineExceeded means the caller's context deadline expired. It // matches context.DeadlineExceeded. KindDeadlineExceeded Kind = "deadline_exceeded" // KindTimeout means the call's own timeout expired: WithTimeout, or the // Timeout of an injected http.Client. It matches context.DeadlineExceeded. KindTimeout Kind = "timeout" // KindTransport means the call failed in transit (DNS, TLS, a reset // connection or an incomplete body). The provider may or may not have // processed it. KindTransport Kind = "transport" // KindRejected means the provider refused the call. It matches // ErrRejected, and ErrUnauthorized, ErrForbidden or ErrRateLimited by // status. KindRejected Kind = "rejected" // KindMalformedResponse means the response could not be used. It matches // ErrMalformedResponse. KindMalformedResponse Kind = "malformed_response" // KindResponseTooLarge means the response body exceeded the size limit. // It matches ErrMalformedResponse. KindResponseTooLarge Kind = "response_too_large" )
Failure kinds.
type Option ¶
type Option func(*config)
Option configures a Client in NewClient. Nil options are skipped, options apply in order, and the last option of each kind wins. Options only record their argument; NewClient validates the result and reports an invalid value as ErrInvalidConfig.
func WithHTTPClient ¶
WithHTTPClient sets the HTTP client that carries every call. NewClient copies it with redirects disabled and no cookie jar, and never modifies hc: its Transport is shared and never mutated, and its Timeout still applies. Changes to hc after NewClient have no effect. hc must not be nil.
The transport is trusted caller code. A transport that retries, follows redirects or replays requests on its own defeats the SDK's one-attempt guarantee. If hc.Transport is nil, Go uses http.DefaultTransport: changes to it then apply, and the SDK's 64 KiB response header limit does not.
Without this option the SDK builds its own transport with the settings of http.DefaultTransport, so later changes to http.DefaultTransport have no effect on it. Like http.DefaultTransport, it takes a proxy from the HTTPS_PROXY and NO_PROXY environment variables; every call is https, so HTTP_PROXY is never used.
func WithMaxResponseBytes ¶
WithMaxResponseBytes limits the response body size. A larger body fails the call with KindResponseTooLarge, which matches ErrMalformedResponse, after the provider may already have billed it. The default is DefaultMaxResponseBytes; n must be from 1 to MaxResponseBytesLimit.
func WithTestEndpoint ¶
WithTestEndpoint replaces https://api.batchdata.com with a loopback base URL, such as the URL of an httptest.NewTLSServer. It exists for tests: only https on 127.0.0.0/8 or [::1], with an optional port and no path, query, fragment or userinfo, is accepted. Host names, including "localhost", are rejected because they resolve through the system resolver. Requests go to <base>/api/v3/<endpoint path>.
func WithTimeout ¶
WithTimeout bounds each call, including sending the request and reading the whole response body. The caller's context deadline still applies when it is earlier. The default is DefaultTimeout; d must be positive.
func WithUserAgent ¶
WithUserAgent replaces the User-Agent header, "go-batchdata" by default. ua must be 1 to 256 bytes of visible ASCII or spaces, starting and ending with a visible character.
type ValidationError ¶
ValidationError describes a local validation failure. Err is the matching sentinel, ErrInvalidConfig or ErrInvalidRequest. Field names what failed: the "apiKey" argument, an option such as "WithTimeout", or a Go field path such as "Items[3].PropertyAddress.Street"; it holds indexes, never values. Reason never contains caller data.
func (*ValidationError) Error ¶
func (e *ValidationError) Error() string
Error returns the sentinel message followed by the field and the reason.
func (*ValidationError) Unwrap ¶
func (e *ValidationError) Unwrap() error
Unwrap returns the sentinel.
type Warning ¶
type Warning struct {
Code WarningCode `json:"code"`
Message string `json:"message,omitempty"`
}
Warning is a provider warning: a machine-readable code and a human-readable message. Unknown codes are kept as sent.
type WarningCode ¶
type WarningCode string
WarningCode identifies the type of a Warning. Values other than the documented constants are kept as sent.
const ( // WarningDatasetNotAllowed reports a requested dataset that does not exist // or is not available for the token. WarningDatasetNotAllowed WarningCode = "dataset_not_allowed" // WarningDeprecatedField reports the use of a deprecated field. WarningDeprecatedField WarningCode = "warning_deprecated_field" // WarningRateLimitApproaching reports that the account is close to its // rate limit. WarningRateLimitApproaching WarningCode = "warning_rate_limit_approaching" )
Documented warning codes.
Directories
¶
| Path | Synopsis |
|---|---|
|
Command examples shows the go-batchdata SDK end to end, offline: it serves a synthetic skip-trace response from a local TLS server, so it needs no API key, makes no network call and costs nothing.
|
Command examples shows the go-batchdata SDK end to end, offline: it serves a synthetic skip-trace response from a local TLS server, so it needs no API key, makes no network call and costs nothing. |
|
internal
|
|
|
call
Package call is the sealed bridge between the root batchdata package and the service packages, such as skiptrace.
|
Package call is the sealed bridge between the root batchdata package and the service packages, such as skiptrace. |
|
httpx
Package httpx is the SDK's single HTTP transport: one bounded POST attempt per call, no redirects, no retries, no replays, and failures that carry no URLs, headers of the request, credentials, causes or bodies.
|
Package httpx is the SDK's single HTTP transport: one bounded POST attempt per call, no redirects, no retries, no replays, and failures that carry no URLs, headers of the request, credentials, causes or bodies. |
|
jsonx
Package jsonx holds the byte-level JSON checks that the root batchdata package and the service packages share: the shape of a raw value, and a count of the containers and values in a document.
|
Package jsonx holds the byte-level JSON checks that the root batchdata package and the service packages share: the shape of a raw value, and a count of the containers and values in a document. |
|
testutil
Package testutil holds the test plumbing go-batchdata's packages share: in-memory and recording HTTP fakes over HTTP/1.1 and HTTP/2, fmt leak assertions, and checks of error types and JSON round trips.
|
Package testutil holds the test plumbing go-batchdata's packages share: in-memory and recording HTTP fakes over HTTP/1.1 and HTTP/2, fmt leak assertions, and checks of error types and JSON round trips. |
|
Package skiptrace provides synchronous forward property skip tracing on the BatchData V3 API: POST /api/v3/property/skip-trace.
|
Package skiptrace provides synchronous forward property skip tracing on the BatchData V3 API: POST /api/v3/property/skip-trace. |
