Module: Edi::RequestIdentifiable

Included in:
Amazon::Retriever, BaseEdiService
Defined in:
app/services/edi/request_identifiable.rb

Overview

Pulls the partner's own request identifier off an HTTP response so it can be
recorded on the EdiCommunicationLog.

Amazon SP-API returns x-amzn-RequestId on every response and their
developer support asks for it by name — it is a REQUIRED field on the
Solution Provider Portal case form. We had never captured it, so case
21547787961 had to be filed quoting submissionId instead, which only
exists for Listings submissions and not for reads.

A module rather than a method on BaseEdiService: Amazon::Retriever
descends from BaseService, not from the EDI base, so a method defined
there raises NoMethodError inside the retriever's transaction and rolls back
the communication log it was about to write. Changing the superclass is not
an option — BaseEdiService requires an orchestrator the retriever's
call sites do not pass.

Constant Summary collapse

REQUEST_ID_HEADERS =

Response headers carrying the partner's request identifier, most specific
first. Amazon SP-API is x-amzn-RequestId; Walmart uses a correlation id;
the last two are the common generic spellings.

%w[
  x-amzn-requestid
  wm_qos.correlation_id
  x-request-id
  request-id
].freeze

Instance Method Summary collapse

Instance Method Details

#partner_request_id(http_result) ⇒ String?

Parameters:

  • http_result (Faraday::Response, nil)

Returns:

  • (String, nil)


32
33
34
35
36
37
38
39
# File 'app/services/edi/request_identifiable.rb', line 32

def partner_request_id(http_result)
  headers = http_result.try(:headers) or return nil

  # Faraday::Utils::Headers is case-insensitive; a plain Hash from another
  # transport is not. Normalise once so one lookup covers both.
  lookup = (headers.respond_to?(:to_hash) ? headers.to_hash : headers).transform_keys { |k| k.to_s.downcase }
  REQUEST_ID_HEADERS.filter_map { |name| lookup[name].presence }.first
end