openapi-nexus 0.1.3

OpenAPI 3.x multi-language code generator
Documentation
package runtime

import (
	"context"
	"fmt"
	"io"
	"net/http"
	"net/url"
	"strings"
)

// Client is the transport-layer HTTP client shared by all APIs.
type Client struct {
	baseURL        string
	httpClient     *http.Client
	authenticator  Authenticator
	defaultHeaders http.Header
}

// Option configures a Client.
type Option func(*Client)

// NewClient builds a Client rooted at baseURL. Options override defaults.
func NewClient(baseURL string, opts ...Option) *Client {
	c := &Client{
		baseURL:        strings.TrimRight(baseURL, "/"),
		httpClient:     http.DefaultClient,
		defaultHeaders: make(http.Header),
	}
	for _, opt := range opts {
		opt(c)
	}
	return c
}

// WithHTTPClient swaps the underlying *http.Client.
func WithHTTPClient(hc *http.Client) Option {
	return func(c *Client) {
		if hc != nil {
			c.httpClient = hc
		}
	}
}

// WithAuth installs an Authenticator applied to every request.
func WithAuth(a Authenticator) Option {
	return func(c *Client) { c.authenticator = a }
}

// WithDefaultHeader sets a header applied to every request. Per-request
// headers take precedence.
func WithDefaultHeader(key, value string) Option {
	return func(c *Client) { c.defaultHeaders.Set(key, value) }
}

// BaseURL returns the base URL configured on the client.
func (c *Client) BaseURL() string { return c.baseURL }

// HTTPClient returns the underlying *http.Client.
func (c *Client) HTTPClient() *http.Client { return c.httpClient }

// NewRequest builds an *http.Request joined to the client's base URL. Query
// pairs (flat key=value list) are appended when non-empty.
func (c *Client) NewRequest(
	ctx context.Context,
	method, path string,
	query url.Values,
	body io.Reader,
) (*http.Request, error) {
	full := c.baseURL + path
	if len(query) > 0 {
		full += "?" + query.Encode()
	}
	req, err := http.NewRequestWithContext(ctx, method, full, body)
	if err != nil {
		return nil, fmt.Errorf("build request: %w", err)
	}
	for k, vals := range c.defaultHeaders {
		for _, v := range vals {
			req.Header.Add(k, v)
		}
	}
	return req, nil
}

// Do authenticates and executes a request.
func (c *Client) Do(req *http.Request) (*http.Response, error) {
	if c.authenticator != nil {
		if err := c.authenticator.AuthenticateRequest(req); err != nil {
			return nil, fmt.Errorf("authenticate: %w", err)
		}
	}
	return c.httpClient.Do(req)
}