Skip to content

ADR 0009: REST and Typed Graph View Endpoints

ADR 0009: REST and Typed Graph View Endpoints

Status: Accepted for architectural direction.

Date: 2026-05-11.

Context

The backend must serve course lookup, credential lookup, student state, query evaluation, and graph-shaped frontend data.

The frontend will include a global interactive graph-like view.

That view needs efficient retrieval of neighborhoods, overlays, expansions, and target relevance.

The project discussed whether a proper graph API would be useful.

GraphQL is a mature option for client-driven entity graph fetching.

GraphQL’s own project materials emphasize precise data selection and retrieving related data in one request: graphql.org.

However, UWScrape’s hard backend problem is semantic correctness.

The backend must preserve requirement status, source references, unparsed requirements, catalog versions, and state-dependent uncertainty.

A general graph query surface could let each frontend screen assemble subtly different academic semantics.

The first backend needs stable query meanings before it needs arbitrary client-selected graph traversal.

Decision

UWScrape will use a versioned REST-style HTTP API for ordinary resources and operations.

UWScrape will also expose typed graph view endpoints for graph-heavy frontend screens.

The graph view endpoints are named projections.

They are not a generic graph query language.

They are not GraphQL in version 1.

They are not a graph database endpoint.

The API root is /api/v1.

Resource endpoints include courses, credentials, catalog versions, source references, and student state.

Query endpoints include course unlock, credential progress, what-if, course impact, and credential gap summary.

Graph view endpoints include course neighborhood, credential requirements, unlock overlay, target relevance, and node expansion.

Each graph view response must declare its view_type.

Each graph view response must declare its projection_version.

Each graph view response must declare server-enforced bounds.

Each graph view response must include source references and uncertainty when relevant.

Each graph view response must identify omitted nodes or edges when bounds truncate the result.

The backend remains the owner of requirement evaluation.

The frontend remains the owner of layout geometry and visual interaction.

Consequences

The frontend gets optimized graph data without becoming responsible for academic semantics.

The backend can tune each graph view endpoint around actual UI needs.

The backend can keep response sizes bounded.

The backend can expose source references consistently.

The backend can evolve graph views with projection versions.

The API remains easy to test with ordinary HTTP tools.

The project avoids the implementation and governance cost of a full GraphQL schema in version 1.

The project may add GraphQL later if stable frontend use cases justify it.

Adding GraphQL later should not replace the typed query semantics.

It should wrap or compose the same backend services.

Alternatives Considered

Alternative 1: Full GraphQL API in Version 1

The backend could expose a GraphQL schema.

This would let the frontend fetch nested related data with fine-grained field selection.

It could reduce over-fetching for some screens.

It could provide strong introspection tooling.

However, it would require careful schema governance before the semantic model has stabilized.

It could encourage screen-specific queries that bypass shared explanation and uncertainty patterns.

It would not, by itself, solve requirement evaluation.

This alternative is deferred.

Alternative 2: Generic Graph Traversal Endpoint

The backend could expose a generic endpoint such as /api/v1/graph/query.

The request could specify node filters, edge filters, depth, and traversal rules.

This would be flexible.

However, it would make academic meaning depend on request construction.

It would also make bounds, caching, and explanations harder to reason about.

This alternative is rejected for version 1.

Alternative 3: Frontend Loads the Whole Graph

The frontend could download a static graph projection and compute all views locally.

This would make interactions very fast after load.

It would reduce backend complexity.

However, state-dependent overlays, source-aware explanations, and conservative unknown handling are better centralized.

It may also produce large initial payloads.

This alternative may still be useful for a catalog-only offline demo.

It is not the main runtime architecture.

Follow-Up

Define graph view request and response schemas in a dedicated spec.

Define the first graph view bounds after measuring real index size.

Define graph node and edge type vocabularies.

Define cache policy for catalog-only graph views.

Define state-dependent overlay semantics.