Skip to content

/gog/id/:_id expand endpoint for GoG Data#280

Open
thehabes wants to merge 4 commits into
mainfrom
backend-expand
Open

/gog/id/:_id expand endpoint for GoG Data#280
thehabes wants to merge 4 commits into
mainfrom
backend-expand

Conversation

@thehabes

@thehabes thehabes commented Jul 15, 2026

Copy link
Copy Markdown
Member

Summary

Adds a server-side expansion endpoint so clients can fetch an object with its describing Annotations already merged, instead of expanding on the client. This is the back-end half of the coordinated fix for glossing-entries CenterForDigitalHumanities/glossing-entries#310 ("Too Many Glosses for localStorage").

Paired front-end PR: CenterForDigitalHumanities/glossing-entries#319.

Problem

The Gallery of Glosses list expands every Gloss on the client: fetch the object, query every Annotation targeting it, then merge the Annotation bodies onto it. To avoid paying that 6–10 minute cost on every visit, expanded objects were cached in the browser's localStorage, which overflowed the ~5 MB quota and broke the page. The chosen fix (option 2 in the issue) is to expand on the server behind a stable, browser-cacheable URL.

Changes

  • New route GET /gog/id/:_id (routes/_gog_id.js, mounted in app.js) → controller.expandedId. Namespaced under /gog rather than overloading the generic GET /v1/id/:_id object route.
  • expandedId handler (controllers/gog.js): looks the object up by _id/slug (same lookup as GET /v1/id/:_id), runs expand(), and responds with the same caching headers as the id route — Cache-Control: max-age=86400, must-revalidate and Last-Modified — so the stable URL is cached by the browser for 24h.
  • Wired up the existing (previously dead) expand() and exported expandedId through db-controller.js.
  • Value-shape parity: each merged value is wrapped as { value, source, evidence } to match DEER's client-side buildValueObject, and repeated keys collect into an Array — so the front end reads the server-expanded object exactly as it read the old client-expanded one (e.g. gloss.text.value.textValue).

The endpoint accepts any RERUM id. It merges every current Annotation of type Annotation/oa:Annotation targeting the object (matching both http/https targets), with no GENERATOR/CREATOR filter, matching the client's historical expand() behavior.

Notes and follow-ups

  • Now namespaced under /gog/id/:_id (was /v1/id/:_id/expanded) so it does not overload the generic object route. This still doesn't stop anyone from using /gog/id/:_id to expand their own data — restricting it to GoG data would need an additional guard (e.g. gating on __rerum.generatedBy / GENERATOR).
  • Requests to /gog/id/:_id do not include a Bearer agent, so they can't pull Annotations for just the app making the request (it isn't provided). It pulls from all existing Annotations targeting the entity no matter which app made the Annotations. We could design an optional way for an app agent to be provided.

@thehabes thehabes changed the title /id/:_id/expand for GoG Data /id/:_id/expanded for GoG Data Jul 15, 2026
habesoftware-claude-connector[bot]

This comment was marked as resolved.

habesoftware-claude-connector[bot]

This comment was marked as outdated.

@thehabes thehabes changed the title /id/:_id/expanded for GoG Data /gog/id/:_id expand endpoint for GoG Data Jul 17, 2026
@thehabes
thehabes marked this pull request as ready for review July 17, 2026 16:51
@thehabes
thehabes requested a review from cubap as a code owner July 17, 2026 16:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant