Class: Compass::Breadcrumb::Strategies::Http

Inherits:
Object
  • Object
show all
Defined in:
lib/compass/breadcrumb/strategies/http.rb

Overview

Stores and retrieves the breadcrumb trail over HTTP from a remote backend, using only Ruby's stdlib Net::HTTP.

Backend contract (implemented by the remote app, not by this gem). The backend URL is used verbatim as the breadcrumbs endpoint:

GET  {backend}?max=N -> 200 with JSON [{ "url":, "label": }]
POST {backend}       -> any 2xx is success; body ignored

Auth is taken from the context's auth_token and sent as a bearer token.

The strategy is stateless and thread-safe: it holds only configuration (backend URL, timeouts, optional transport). The per-request #for cache lives on context.request.env, never on the instance.

I.e.:

config.breadcrumb.strategy = Compass::Breadcrumb::Strategies::Http.new(
backend: "https://my-app.example.com/compass"
)

Constant Summary collapse

DEFAULT_OPEN_TIMEOUT =
1
DEFAULT_READ_TIMEOUT =
2
MEMO_KEY =
"compass.breadcrumb.http.for".freeze

Instance Method Summary collapse

Constructor Details

#initialize(backend:, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT, transport: nil) ⇒ Http

Returns a new instance of Http.

Parameters:

  • backend (String)

    the breadcrumbs endpoint URL, used verbatim.

  • open_timeout (Numeric) (defaults to: DEFAULT_OPEN_TIMEOUT)

    connection open timeout, in seconds.

  • read_timeout (Numeric) (defaults to: DEFAULT_READ_TIMEOUT)

    response read timeout, in seconds.

  • transport (#call, nil) (defaults to: nil)

    injectable executor for specs; receives (uri, net_http_request) and returns a response responding to #code and #body. Defaults to a Net::HTTP-backed transport.



40
41
42
43
44
45
# File 'lib/compass/breadcrumb/strategies/http.rb', line 40

def initialize(backend:, open_timeout: DEFAULT_OPEN_TIMEOUT, read_timeout: DEFAULT_READ_TIMEOUT, transport: nil)
  @backend = backend.to_s
  @open_timeout = open_timeout
  @read_timeout = read_timeout
  @transport = transport || method(:net_http_transport)
end

Instance Method Details

#for(context:, max: 10) ⇒ Array<Hash>

Fetches the trail, memoized per request so repeated renders on the same request only hit the backend once.

Parameters:

  • context (Compass::Context, nil)

    the request-scoped context.

  • max (Integer) (defaults to: 10)

    maximum number of crumbs to request.

Returns:

  • (Array<Hash>)

    the crumbs, or [] on any failure.



53
54
55
56
57
58
59
60
# File 'lib/compass/breadcrumb/strategies/http.rb', line 53

def for(context:, max: 10)
  env = context&.request&.env
  return fetch(context, max) unless env

  return env[MEMO_KEY] if env.key?(MEMO_KEY)

  env[MEMO_KEY] = fetch(context, max)
end

#push(context:, url:, label:) ⇒ nil

Posts a crumb to the backend. The response body is ignored.

Parameters:

  • context (Compass::Context, nil)

    the request-scoped context.

  • url (String)

    the crumb URL.

  • label (String)

    the crumb label.

Returns:

  • (nil)


68
69
70
71
72
73
74
75
76
# File 'lib/compass/breadcrumb/strategies/http.rb', line 68

def push(context:, url:, label:)
  uri = build_uri
  response = @transport.call(uri, post_request(uri, context, url: url, label: label))
  log_failure(response) unless success?(response)
  nil
rescue => e
  log(e)
  nil
end