📖 4 min read (~ 700 words).

Transport

client.Runtime wraps a *http.Client plus the wire-format codecs needed to call an OpenAPI-described API. This page covers the knobs that shape the underlying HTTP behaviour; auth, tracing and request submission live on their own pages.

Constructors

func New(host, basePath string, schemes []string) *Runtime
func NewWithClient(host, basePath string, schemes []string, client *http.Client) *Runtime

See client.New and client.NewWithClient for the authoritative signatures.

New builds a runtime against http.DefaultTransport. NewWithClient takes an explicit *http.Client — use it when you need a non-default transport (custom TLS, a proxy, an instrumented round-tripper, etc.) or want to share a client across runtimes.

schemes lists allowed URL schemes ("https", "http"); the runtime picks one when building a request, preferring HTTPS.

What New sets up for you

FieldDefault
DefaultMediaTypeapplication/json (runtime.JSONMime)
Consumers / ProducersJSON, XML, YAML, plain text, HTML, CSV and application/octet-stream byte stream codecs.
Transporthttp.DefaultTransport
Contextcontext.Background() (legacy field — see requests)
Debugenabled if SWAGGER_DEBUG or DEBUG env var is set

You can replace any of these after construction. Example: register a custom codec for a vendor JSON content type that the client will encounter on responses.

rt := client.New("api.example.com", "/v1", []string{"https"})
rt.Consumers["application/vnd.acme.v1+json"] = runtime.JSONConsumer()
rt.Producers["application/vnd.acme.v1+json"] = runtime.JSONProducer()

Full source: docs/examples/client/transport/main.go

TLS — TLSClientAuth and TLSClientOptions

For mutual TLS, custom CAs or certificate pinning, build a *tls.Config via TLSClientAuth:

tlsCfg, err := client.TLSClientAuth(client.TLSClientOptions{
	Certificate: "/etc/ssl/client.pem",
	Key:         "/etc/ssl/client-key.pem",
	CA:          "/etc/ssl/ca.pem",
	ServerName:  "api.internal",
})
if err != nil {
	return nil, err
}

httpClient := &http.Client{
	Transport: &http.Transport{TLSClientConfig: tlsCfg},
}
rt := client.NewWithClient("api.internal", "/v1", []string{"https"}, httpClient)

Full source: docs/examples/client/transport/main.go

Option highlights (the full struct is in the godoc):

GroupFields
Client cert (paths)Certificate, Key
Client cert (loaded)LoadedCertificate, LoadedKey
Server CAsCA, LoadedCA, LoadedCAPool (combined with each other; otherwise the system pool is used)
Hostname / verifyServerName, InsecureSkipVerify (ignored when ServerName is set), VerifyPeerCertificate, VerifyConnection
ResumptionSessionTicketsDisabled, ClientSessionCache

TLSClientAuth always returns a config with MinVersion = TLS 1.2.

Timeouts

Two layers of timeout apply:

  1. Per-request timeout — set via the operation’s Params.SetTimeout(d) (any generated parameter type implements this). This becomes the deadline of the request context.Context derived inside BuildHTTPContext (see requests).
  2. HTTP client timeout — set on the *http.Client you pass to NewWithClient. This is the standard Client.Timeout field; it applies regardless of the per-request value.

There is also a package-level DefaultTimeout = 30 * time.Second. It is not wired up automatically; it exists for callers building their own *http.Client that want to use the same default the runtime advertises.

httpClient := &http.Client{Timeout: client.DefaultTimeout}
rt := client.NewWithClient(host, base, schemes, httpClient)

Full source: docs/examples/client/transport/main.go

Proxy

Proxy configuration lives on the underlying *http.Transport, not on Runtime. Two common patterns:

  1. Honour HTTPS_PROXY / HTTP_PROXY (default behaviour anyway):
// Honour HTTPS_PROXY / HTTP_PROXY (default behaviour anyway).
tr := &http.Transport{Proxy: http.ProxyFromEnvironment}

httpClient := &http.Client{Transport: tr}
rt := client.NewWithClient(host, base, schemes, httpClient)

Full source: docs/examples/client/transport/main.go

  1. Force a specific proxy:
// Force a specific proxy.
proxyURL, _ := url.Parse("http://proxy.internal:3128")
tr := &http.Transport{Proxy: http.ProxyURL(proxyURL)}

httpClient := &http.Client{Transport: tr}
rt := client.NewWithClient(host, base, schemes, httpClient)

Full source: docs/examples/client/transport/main.go

Keepalive — EnableConnectionReuse

Some servers never close the response body, which prevents Go from reusing the underlying TCP connection. EnableConnectionReuse installs a transport middleware that drains the unread body on Close() so the connection can return to the pool:

rt := client.New("api.example.com", "/v1", []string{"https"})
rt.EnableConnectionReuse()

Full source: docs/examples/client/transport/main.go

This is not enabled by default because for some servers the response stream never completes and draining would block forever. Turn it on when you’ve confirmed the server you’re talking to does the right thing.

Debug logging

Two ways to enable wire-level dumps of requests and responses (both go through httputil.DumpRequest / DumpResponse):

  • Set the SWAGGER_DEBUG (or DEBUG) environment variable before the process starts. client.New picks this up.
  • Call rt.SetDebug(true) at runtime.

rt.SetLogger(myLogger) swaps the destination away from the default standard-library logger.

For most production debugging you’ll get more value out of the OpenTelemetry tracing than from raw dumps.