Skip to content

Echo the rite in the /calendar response #760

Description

@JohnRDOrazio

Summary

A /calendar response carries no indication of the rite it was computed under. Clients that need to
label or branch on the rite have to track it themselves, out of band, and can get it wrong.

Why it matters

The rite-level Ambrosian calendar is indistinguishable from the General Roman calendar by payload
alone:

  • settings has neither national_calendar nor diocesan_calendar (correctly — it is neither)
  • metadata carries no rite field
$ curl -s 'http://localhost:8000/calendar/ambrosian' | jq '.settings | keys'
["ascension","corpus_christi","epiphany","eternal_high_priest","holydays_of_obligation","locale","return_type","year","year_type"]

A diocesan or national calendar is self-describing — the response names the calendar — but
/calendar/ambrosian and /calendar differ only in their contents.

Found while making WebCalendar in liturgy-components-js caption an Ambrosian calendar correctly
(Liturgical-Calendar/liturgy-components-js#5). Because the payload could not answer "which rite is this?",
the component had to take the rite from the ApiClient that issued the request and thread it through to
render time. That works, but it means:

  • every consumer that renders a calendar has to plumb the rite alongside the data
  • the pairing is only as reliable as the client's own bookkeeping. With two requests in flight after a
    rite change, a response can be paired with the wrong rite unless the client pins the rite per request
  • a consumer that receives calendar data from anywhere other than its own request — a cache, a message,
    a server-rendered payload — has no way to recover the rite at all

Suggestion

Echo the rite in the response, in whichever of the two places fits the existing conventions better:

// in settings, alongside the other request parameters that were applied
"settings": { "year": 2026, "locale": "la", "rite": "roman", ... }

// or in metadata, alongside the other descriptive fields
"metadata": { "version": "...", "rite": "ambrosian", ... }

settings seems the closer match: the rite is a request parameter (a path segment) that the API resolves
and applies, like year_type and locale, both of which are already echoed there.

Emitting it for every rite, including roman, would make it usable without a presence check. Since
Router::extractRiteSegment() already accepts roman explicitly and defaults to it, the value is always
known.

Compatibility

Additive. Existing consumers ignore unknown fields, and no current response shape changes meaning — the
absence of a rite today is not information anyone can be relying on, since it is absent for every rite.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions