package api // Video is the catalogue's copy of a video, as GET /api/videos/{id} serves it. // It is deliberately not cms's video record of the same name: the catalogue // publishes what a reader needs to show and play a video, and none of the // ingestion detail — no storage key, no transcoding job id, no status, since // a video that is not ready never reaches the catalogue at all. type Video struct { ID string `json:"id" example:"0f8fad5b-d9cb-469f-a165-70867728950e"` Title string `json:"title" example:"The Evening Bulletin"` PlaybackURL string `json:"playbackUrl" example:"https://d111111abcdef8.cloudfront.net/videos/abc123/index.m3u8"` Categories []string `json:"categories" example:"documentary,news"` } // SearchRequest is the body of QUERY /api/videos: what a reader is looking // for. Every member is optional — an empty body browses the whole catalogue. type SearchRequest struct { // Title is matched lexically against video titles: the words are all // required, and the last is treated as a prefix so a part-typed word still // finds something. Title string `json:"title" example:"desert fal"` // Categories narrows the search to videos filed under any one of these // names — not all of them, so it widens the choice of category while // narrowing the results. Empty means every category. Categories []string `json:"categories" example:"documentary,news"` // Limit is how many videos to return. Absent or zero takes the default of // 20; anything above the maximum of 100 is capped to it rather than // refused, and the cursor still reaches the rest. Limit int `json:"limit" example:"20"` // Cursor asks for the page after the one a previous search ended at. Send // back the nextCursor from that search, unchanged; it is opaque, and the // only thing to do with it is return it. Cursor string `json:"cursor"` } // SearchResults is one page of search results. type SearchResults struct { // Videos are the matches, most relevant first. Never null: a search that // matches nothing is an empty list. Videos []Video `json:"videos"` // NextCursor reaches the page after this one. Empty on the last page, // which is how a reader knows there is no more to ask for. NextCursor string `json:"nextCursor"` }