Module: Smplkit::Transport Private

Defined in:
lib/smplkit/transport.rb

Overview

This module is part of a private API. You should avoid using this module if possible, as it may be removed or be changed in the future.

Internal per-service HTTP transport construction.

The top-level Smplkit::Client needs one authenticated transport per backend service (app, config, flags, logging, jobs) plus a context-registration buffer that client.platform owns. This module builds them in one place so the construction is side-effect-free (transports connect lazily on first call) and shared by the top-level client.

There is no audit transport here — client.audit owns its own.

Defined Under Namespace

Classes: ServiceTransports

Constant Summary collapse

SDK_OWNED_HEADERS =

This constant is part of a private API. You should avoid using this constant if possible, as it may be removed or be changed in the future.

Headers the SDK always owns — extra_headers cannot override these (authorization carries the credential; content-type is set per request by the generated client). User-Agent is deliberately NOT in this list: a caller-supplied User-Agent wins over the SDK default.

%w[authorization content-type].freeze

Class Method Summary collapse

Class Method Details

.apply_headers(client, extra_headers) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Stamp the default headers onto a generated ApiClient.

User-Agent precedence: caller-supplied via extra_headers (any casing or symbol representation) > the SDK default (+Smplkit.user_agent+, smplkit-sdk-ruby/<version>) > the generated stack's own default (+OpenAPI-Generator/x.y.z/ruby+, removed here so exactly one User-Agent representation remains). Other extra_headers entries are applied as-is unless SDK-owned.



41
42
43
44
45
46
47
# File 'lib/smplkit/transport.rb', line 41

def apply_headers(client, extra_headers)
  client.default_headers.delete("User-Agent")
  client.default_headers["User-Agent"] = Smplkit.user_agent unless user_agent_supplied?(extra_headers)
  (extra_headers || {}).each do |k, v|
    client.default_headers[k] = v unless SDK_OWNED_HEADERS.include?(k.to_s.downcase)
  end
end

.build_api_client(generated_module, subdomain, cfg, accept: nil, base_url: nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Build a generated ApiClient for one service from a resolved config.

base_url, when supplied, overrides the +scheme+/+host+ derived from +subdomain+/+base_domain+ (the path a standalone product client takes when handed a fully-resolved app URL).



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/smplkit/transport.rb', line 106

def build_api_client(generated_module, subdomain, cfg, accept: nil, base_url: nil)
  configuration = generated_module::Configuration.new
  if base_url.nil?
    configuration.scheme = cfg.scheme
    configuration.host = "#{subdomain}.#{cfg.base_domain}"
  else
    uri = URI.parse(base_url)
    configuration.scheme = uri.scheme
    port_suffix = uri.port && ![80, 443].include?(uri.port) ? ":#{uri.port}" : ""
    configuration.host = "#{uri.host}#{port_suffix}"
  end
  configuration.base_path = ""
  configuration.access_token = cfg.api_key
  configuration.debugging = cfg.debug
  HttpPool.configure(configuration)
  generated_module::ApiClient.new(configuration).tap do |client|
    client.default_headers["Accept"] = accept if accept
    apply_headers(client, cfg.extra_headers)
  end
end

.build_service_transports(cfg) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Build the five per-service transports from a resolved transport config.

Side-effect-free — the underlying Faraday clients are created lazily on the first request. Smpl Jobs is JSON:API, so its transport carries the +application/vnd.api+json+ Accept header.



87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/smplkit/transport.rb', line 87

def build_service_transports(cfg)
  app_url = ConfigResolution.service_url(cfg.scheme, "app", cfg.base_domain)
  ServiceTransports.new(
    app_url: app_url,
    api_key: cfg.api_key,
    app_http: build_api_client(SmplkitGeneratedClient::App, "app", cfg),
    config_http: build_api_client(SmplkitGeneratedClient::Config, "config", cfg),
    flags_http: build_api_client(SmplkitGeneratedClient::Flags, "flags", cfg),
    logging_http: build_api_client(SmplkitGeneratedClient::Logging, "logging", cfg),
    jobs_http: build_api_client(SmplkitGeneratedClient::Jobs, "jobs", cfg,
                                accept: "application/vnd.api+json")
  )
end

.to_transport_config(cfg, extra_headers = nil) ⇒ Object

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Project the runtime ResolvedConfig down to the transport subset.

The top-level client's resolved config is a superset of what the transports need; this drops the runtime-only fields (environment, service, telemetry).



54
55
56
57
58
59
60
61
62
# File 'lib/smplkit/transport.rb', line 54

def to_transport_config(cfg, extra_headers = nil)
  ConfigResolution::ResolvedClientConfig.new(
    api_key: cfg.api_key,
    base_domain: cfg.base_domain,
    scheme: cfg.scheme,
    debug: cfg.debug,
    extra_headers: extra_headers
  )
end

.user_agent_supplied?(extra_headers) ⇒ Boolean

This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.

Whether an extra-headers hash carries a caller-supplied User-Agent, under any representation the surface accepts — string keys in any casing ("User-Agent", "user-agent", …) and symbol keys (:"user-agent").

Returns:

  • (Boolean)


29
30
31
# File 'lib/smplkit/transport.rb', line 29

def user_agent_supplied?(extra_headers)
  (extra_headers || {}).keys.any? { |k| k.to_s.casecmp("user-agent").zero? }
end