Class: ApiCatalogController

Inherits:
ActionController::Base
  • Object
show all
Defined in:
app/controllers/api_catalog_controller.rb

Overview

Serves the RFC 9727 API Catalog plus its companion machine description and
human documentation, enabling automated discovery of WarmlyYours' public
API by crawlers and AI agents.

Three sibling endpoints, all mounted at the top level (ahead of the
subdomain-scoped draws) so they answer on every WarmlyYours origin —
mirroring /up and /robots.txt. A scanner pointed at any host (typically
www) therefore finds the catalog, while the catalog's links themselves
always point at the canonical API host (api.warmlyyours.com):

  1. API Catalog (RFC 9727) — GET /.well-known/api-catalog
    An application/linkset+json linkset (RFC 9264) with one entry per API.
    Each entry carries the API anchor plus the service-desc (OpenAPI),
    service-doc (human docs), and status (health) link relations.

  2. OpenAPI description (service-desc) — GET /openapi.json
    A minimal OpenAPI 3.1 document. No public application endpoints are
    published yet — only service health — so it currently lists just /up.
    The internal/integration endpoints under /v1 (Google Merchant feeds,
    oEmbed, electricity-rate lookups, webhooks) are deliberately NOT
    advertised here: each exists for a specific consumer (Google Merchant,
    blog snippet rendering, our operating-cost calculator), not for public
    or agent use. Populate this as the planned public APIs (quote builder,
    operating cost, product catalog) actually ship.

  3. Human docs (service-doc) — GET /api-docs
    A short, self-contained HTML page summarizing the same surface and the
    planned public APIs.

Inherits from ActionController::Base (not ApplicationController) so no
auth/locale/session filters run — the catalog must be reachable
unauthenticated on crm.* and api.* exactly as on www.*. Each document
is regenerated cheaply per request and cached at the edge via expires_in.

See Also:

Constant Summary collapse

CACHE_TTL =

Edge/browser cache TTL shared by all three documents. They change only on
deploy and are cheap to regenerate, so a modest public TTL is plenty.

1.hour
[
  '</.well-known/api-catalog>; rel="api-catalog"',
  '</openapi.json>; rel="service-desc"; type="application/openapi+json"',
  '</api-docs>; rel="service-doc"; type="text/html"'
].join(', ').freeze

Instance Method Summary collapse

Instance Method Details

#docsvoid

This method returns an undefined value.

Human-readable API documentation referenced by the service-doc relation.

The page only exists as HTML — clients negotiating another format (bots
requesting /api-docs.json or sending a JSON-only Accept header) raised
ActionView::MissingTemplate (AppSignal #6177), so the format is pinned.



87
88
89
90
91
# File 'app/controllers/api_catalog_controller.rb', line 87

def docs
  expires_in CACHE_TTL, public: true
  @api_base = api_base
  render :docs, layout: false, formats: :html
end

#openapivoid

This method returns an undefined value.

OpenAPI 3.1 description referenced by the catalog's service-desc relation.



76
77
78
# File 'app/controllers/api_catalog_controller.rb', line 76

def openapi
  render_document openapi_document, 'application/openapi+json'
end

#showvoid

This method returns an undefined value.

RFC 9727 API Catalog, expressed as an RFC 9264 linkset.



69
70
71
# File 'app/controllers/api_catalog_controller.rb', line 69

def show
  render_document catalog_document, 'application/linkset+json'
end