Documentation
¶
Overview ¶
Package client provides a small, dependency-free HTTP client for talking to JSON REST APIs. It is the single transport layer shared by every Azure DevOps service wrapper and by the 7pace Timetracker integration.
The client is intentionally generic: callers describe a request (method, path, query, body) and supply a destination for the decoded JSON response. Authentication is pluggable via the Authorizer interface so the same code serves both Azure DevOps (PAT Basic auth) and 7pace (bearer token).
Index ¶
- type APIError
- type Authorizer
- type BearerAuthorizer
- type Client
- func (c *Client) Delete(ctx context.Context, path string, query url.Values, out any) error
- func (c *Client) Do(ctx context.Context, req Request) (*Response, error)
- func (c *Client) GetJSON(ctx context.Context, path string, query url.Values, out any) error
- func (c *Client) GetJSONVersion(ctx context.Context, path string, query url.Values, out any, apiVersion string) error
- func (c *Client) PatchJSON(ctx context.Context, path string, query url.Values, body, out any, ...) error
- func (c *Client) PostJSON(ctx context.Context, path string, query url.Values, body, out any) error
- func (c *Client) PostJSONPatch(ctx context.Context, path string, body, out any) error
- func (c *Client) PostJSONVersion(ctx context.Context, path string, body, out any, apiVersion string) error
- func (c *Client) PutJSON(ctx context.Context, path string, query url.Values, body, out any) error
- type List
- type Option
- type PATAuthorizer
- type RawBody
- type Request
- type Response
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
Method string // HTTP method of the failed request
URL string // request URL (path + query)
StatusCode int // HTTP status code
Message string // human-readable message extracted from the body
TypeKey string // Azure DevOps "typeKey", when present
Body string // raw response body (truncated)
// RetryAfter is the raw "Retry-After" response header value (seconds, or
// an HTTP-date), when present. Azure DevOps sets this on HTTP 429
// responses once a caller exceeds its TSTU rate-limit budget; surfacing
// it lets a caller (or the LLM driving this MCP server) know to wait
// before retrying instead of treating the failure as opaque.
RetryAfter string
}
APIError is a structured error returned for any non-2xx HTTP response. It preserves the HTTP status and, when available, the service-provided message so callers (and ultimately the LLM) get an actionable explanation rather than an opaque status code.
type Authorizer ¶
type Authorizer interface {
// Authorize mutates the request to carry authentication.
Authorize(*http.Request)
}
Authorizer applies authentication credentials to an outgoing request.
type BearerAuthorizer ¶
type BearerAuthorizer struct {
// contains filtered or unexported fields
}
BearerAuthorizer authenticates using an OAuth-style bearer token. It is used for 7pace Timetracker.
func NewBearerAuthorizer ¶
func NewBearerAuthorizer(token string) *BearerAuthorizer
NewBearerAuthorizer builds a BearerAuthorizer for the given token.
func (*BearerAuthorizer) Authorize ¶
func (a *BearerAuthorizer) Authorize(r *http.Request)
Authorize sets the Authorization header for bearer auth.
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a reusable JSON REST client bound to a base URL and an Authorizer. A Client is safe for concurrent use by multiple goroutines.
func New ¶
func New(baseURL string, auth Authorizer, opts ...Option) (*Client, error)
New creates a Client for the given base URL and Authorizer.
func (*Client) Do ¶
Do executes a request, decoding a successful JSON response into req.Out (when set) and returning a typed *APIError for non-2xx responses.
If Azure DevOps rejects the requested api-version (HTTP 400, "version not supported"), Do negotiates a supported version from the server's response and retries the request once. This transparently handles endpoints that require a "-preview" api-version without each caller having to know the exact suffix.
func (*Client) GetJSONVersion ¶
func (c *Client) GetJSONVersion(ctx context.Context, path string, query url.Values, out any, apiVersion string) error
GetJSONVersion is like GetJSON but pins a specific api-version (e.g. for "-preview" endpoints).
func (*Client) PatchJSON ¶
func (c *Client) PatchJSON(ctx context.Context, path string, query url.Values, body, out any, contentType string) error
PatchJSON performs a PATCH request with a JSON body and decodes the response. contentType may be empty to use "application/json"; Azure DevOps work-item updates require "application/json-patch+json".
func (*Client) PostJSON ¶
PostJSON performs a POST request with a JSON body and decodes the response.
func (*Client) PostJSONPatch ¶
PostJSONPatch performs a POST with the "application/json-patch+json" content type required by Azure DevOps work item create operations.
type List ¶
List is the standard Azure DevOps collection envelope: most list endpoints return {"count": N, "value": [...]}. Decode into List[T] to access the items.
type Option ¶
type Option func(*Client)
Option configures a Client.
func WithAPIVersion ¶
WithAPIVersion sets a default "api-version" query parameter applied to every request that does not specify its own. Azure DevOps requires this; 7pace encodes the version in the path and should leave it empty.
func WithCacheTTL ¶ added in v0.1.2
WithCacheTTL enables an in-memory cache for GET responses, valid for the given duration. A zero duration (the default) disables caching. The cache is invalidated in full whenever a write request through this Client succeeds, so cached data is never older than the client's own last write.
func WithHTTPClient ¶
WithHTTPClient sets a custom *http.Client (e.g. for testing or proxies).
func WithUserAgent ¶
WithUserAgent sets the User-Agent header sent on every request.
type PATAuthorizer ¶
type PATAuthorizer struct {
// contains filtered or unexported fields
}
PATAuthorizer authenticates to Azure DevOps using a Personal Access Token.
Azure DevOps accepts a PAT via HTTP Basic auth with an empty username and the token as the password.
func NewPATAuthorizer ¶
func NewPATAuthorizer(pat string) *PATAuthorizer
NewPATAuthorizer builds a PATAuthorizer for the given token.
func (*PATAuthorizer) Authorize ¶
func (a *PATAuthorizer) Authorize(r *http.Request)
Authorize sets the Authorization header for Basic PAT auth.
type RawBody ¶
RawBody captures an undecoded response body. Pass a *RawBody as Request.Out to receive the raw bytes (and content type) instead of JSON decoding, for endpoints that return plain text such as build/pipeline logs.
type Request ¶
type Request struct {
// Method is the HTTP method (GET, POST, PATCH, PUT, DELETE).
Method string
// Path is appended to the client's base URL. A leading slash is optional.
Path string
// Query holds URL query parameters. The "api-version" parameter, if not
// present here, is added from the client default when set.
Query url.Values
// Body, when non-nil, is JSON-encoded and sent as the request body.
// If Body already implements io.Reader it is sent verbatim.
Body any
// ContentType overrides the request Content-Type. Defaults to
// "application/json" when a body is present.
ContentType string
// APIVersion overrides the client's default api-version for this request.
APIVersion string
// Header holds extra request headers (e.g. "If-Match" for conditional
// updates). These are applied after defaults, so they take precedence.
Header http.Header
// Out, when non-nil, receives the JSON-decoded response body.
Out any
}
Request describes a single REST call.
type Response ¶
type Response struct {
StatusCode int
Header http.Header
// ContinuationToken is the value of the x-ms-continuationtoken header used
// by Azure DevOps to page through large result sets. Empty when absent.
ContinuationToken string
}
Response carries metadata about a completed request. The decoded body, if requested, is written to Request.Out.