REST API recipe
Source: RestApiSample/ · cursor-paginated REST API with bearer-token auth. Falls back to local JSON pages when no API URL is configured.
Owns in the academic graph: courses, terms, instructors.
What it teaches
- Cursor pagination (
{ items: [...], nextCursor: "..." | null }envelope) — preferred over offset. - Bearer-token auth via the
Authorization: Bearer <token>header. - Rate-limit handling — honors
429 Too Many RequestswithRetry-After, exponential backoff on5xx. - A single
IRestApiSourceinterface implemented by bothHttpRestApiSourceandLocalRestApiSource, so the ingestion code doesn't care where pages come from.
Driving the source
IRestApiSource source = string.IsNullOrWhiteSpace(apiBaseUrl)
? new LocalRestApiSource(localRoot)
: new HttpRestApiSource(apiBaseUrl, apiBearer);
await foreach (var course in source.StreamAsync<CoursesIngest.CourseDoc>("courses"))
{
CoursesIngest.Ingest(graph, course);
}
Under the hood HttpRestApiSource:
- Honors
Retry-After: <seconds>andRetry-After: <HTTP-date>. - Backs off exponentially (cap 60 s) on
429and5xx. - Threads
nextCursorinto the?cursor=…query param across pages.
Configuration
| Variable | Purpose | Default |
|---|---|---|
RECIPE_API_BASE_URL |
API root (blank → local mode) | (blank) |
RECIPE_API_TOKEN |
Bearer token | (blank) |
RECIPE_LOCAL_ROOT |
Local fallback root | data/ |
Reuse notes
- Same
IRestApiSourcecontract works with offset paging, link-header paging, page numbers — change only the source class. LocalRestApiSourceuses thepage-1.json,page-2.jsonnaming convention — handy for unit-style testing of the ingest logic without hitting the network.