Skip to content

Feeds

A feed is a URL that answers with one page of items as JSON. The wall asks for the first page, and for the next page when the visitor gets close to the end. The schema is feed.schema.json.

{
"items": [
{ "id": "12345", "link": "/listing/12345", "title": "A title", "subtitle": "Author",
"image": "https://cdn.example.com/12345/512.jpg",
"image_focus": "https://cdn.example.com/12345/1024.jpg",
"image_full": "https://cdn.example.com/12345/full.jpg",
"aspect": 1.5, "badges": ["video"],
"video": "https://cdn.example.com/12345/720.mp4", "projection": "flat", "stereo": "mono",
"meta": { "price": "1 250 EUR", "location": "Plovdiv" } }
],
"next": "eyJzIjpbMTY5"
}

The core fields of an item are id, link, image and aspect. The page has items, and next when there is more. The other fields are listed in Item fields.

next is an opaque string. The program passes it back untouched as cursor=<next> and never parses it. A missing or empty next ends the feed.

Use cursors, not page numbers or offsets. A wall paginates as the visitor looks around, and an offset that shifts when the list changes repeats or skips items. A cursor that carries the sort key and the last id does not.

50 items per page are recommended. At most 100 are allowed.

  • A feed of type search has {query} in its URL. The query is URL-encoded.
  • A filter appends param=value to the feed URL. The value all means no filter, and then the parameter is left out.
  • title is strongly recommended on every item, because a card whose picture fails to load shows the title.
{ "id": "search", "type": "search", "url": "/wall/feed?q={query}" }

Cache-Control is your choice. Programs do not cache feeds across sessions.

A site that only has a feed can say so in the page:

<link rel="wall-feed" href="/wall/feed.json" title="Latest">

That is Level 2 without a manifest. With a manifest you also get filters, media rules, actions and brand. See the manifest.

import { JsonFeedAdapter } from '@diazoma/adapters';
const adapter = new JsonFeedAdapter({ url: '/wall/feed', search: '/wall/feed?q={query}' });
const first = await adapter.page({});
const second = await adapter.page({ cursor: first.next });

Invalid items are dropped and reported through the onWarning option. See the Adapters API.