Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions dev-docs/api/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
# ChannelFinder API design docs

Internal design notes for the ChannelFinder REST API — not user-facing reference
(that is the live [Swagger UI](http://localhost:8080/swagger-ui/index.html) and
the [ReadTheDocs site](https://channelfinder.readthedocs.io/en/latest/)).

## Contents

| File | What it is |
| ----------------- | ------------------------------------------------------------------------------------------ |
| `migrations.md` | Why today's API (v0) is being reshaped into v1, the consolidation targets, and the rationale per decision. |
| `conventions.md` | The REST rules v1 follows — HTTP semantics, status codes, naming, errors, pagination. |

Read migrations.md first for the direction and reasoning, then conventions.md for
the binding rules.

## The domain in one paragraph

ChannelFinder is a directory of **channels**. A channel has a unique `name`, an
`owner`, a set of **properties** (name-value pairs), and a set of **tags**
(names). Properties and tags are defined independently and then attached to
channels. Clients query for channels matching property/tag/name expressions.
Alongside the three domain resources are two operational resources — jobs
(handles on async work) and processors (channel post-processors) — plus the
out-of-band Actuator surface for service info, health, and metrics. See the
top-level [README](../../README.md) for what ChannelFinder is and how to run it.

## Use cases

Who uses ChannelFinder and how — what the design is answerable to:

| Actor | Access | Auth | Cadence / scale |
| -------------------------------------------- | -------------------- | ----------------------------- | ------------------------------------------------ |
| RecCeiver / channel producer | write | `channel` (+`property`/`tag`) | Bursty: thousands of channels per IOC start/stop |
| Phoebus & other read clients | read | none | Interactive and frequent |
| Metadata curator / admin | write | `tag`, `property`, `admin` | Occasional, deliberate |
| Bundled admin web UI (`static/`) | read + write | `channel`, `tag`, `property` | Ad-hoc, browser, same-origin |
| Channel processors (e.g. Archiver Appliance) | internal side effect | n/a (server-side) | Automatic on every create/update |
| Operators / monitoring | read | none | Continuous scrape |

How those patterns shape the API:

- **Bulk-first writes.** Producers reconcile thousands of channels per IOC, so a whole reconcile is one `POST /channels:batch` command, and an oversized one can run as an async job.
- **Open, search-centric reads.** Discovery is unauthenticated and query-dominated, so v0's three paging/count surfaces collapse into one `GET /channels`, with richer filtering deferred to RSQL.
- **Definitions gate attachments.** Properties and tags are defined independently and then attached, so they are both top-level resources and channel sub-resources, and attaching an undefined one is a `422`.
- **Metadata drives side effects.** Channel properties (`archive`, `archiver`, `pvStatus`) trigger processors, so a run is an explicit `POST /channels:process` command and processors are inspectable via `/processors`.
- **Some work outlives a request.** A directory-wide processor run or an oversized bulk write returns a job the client polls.

## Status

These docs describe a target, not a frozen contract. The codebase is structured
for versioned controllers (`web/v0/...`), leaving room to add `v1` alongside
without breaking existing clients.
Loading
Loading