Spring til indhold

Feed

en sides opdateringer i et format, man abonnerer på

Hvad det er

Et feed er en fil på en fast adresse, der lister et sites nyeste indlæg i en form, software kan læse: hvert indlæg med titel, dato, et id der aldrig skifter, og som regel selve teksten. Et program henter filen med faste mellemrum og viser kun det, der er kommet til siden sidst. Det kaldes også webfeed eller syndikeringsfeed, og mange siger »RSS-feed« om dem alle, uanset hvilket format der ligger nedenunder.

Det, der skiller det ud, er retningen. Et nyhedsbrev bliver skubbet ud: afsenderen har en liste over adresser og sender til hver enkelt. Et feed bliver hentet: udgiveren lægger én fil på serveren, og hver abonnents feedlæser henter den, sammenligner den med den kopi, den så sidst, og beholder de indlæg, den ikke kender i forvejen. Udgiveren får aldrig at vide, hvem der abonnerer, abonnenten afleverer aldrig en mailadresse, og at stoppe kræver kun, at man sletter én linje i sin læser.

Tre formater bærer næsten alle feeds på nettet. RSS 2.0 er XML, daterer sine indlæg i stilen fra RFC 822 (Sat, 07 Sep 2002 00:00:01 GMT) og erklæres frosset af sin egen specifikation. Atom, som IETF udgav som RFC 4287 i december 2005, er også XML og strengere: hvert feed og hvert indlæg har et permanent id og et updated-tidsstempel i formen fra RFC 3339, og en forfatter skal være angivet et sted. JSON Feed, i version 1.1 siden august 2020, siger det samme i JSON til udviklere, der helst er fri for at parse XML.

En side fortæller software, hvor dens feeds ligger, med <link rel="alternate">-elementer i sit head, hvert med sin medietype: application/rss+xml, application/atom+xml eller application/feed+json. Sådan finder en læser feedet ud fra intet andet end sitets almindelige adresse.

Hvorfor det betyder noget

Den første beslutning er, om der overhovedet skal være et. Et feed er et output mere, der skal have en skabelon, valideres og holdes stabilt i årevis, for et publikum, der er mindre end et socialt netværks. Til gengæld er det den eneste abonnementskanal, der hverken kræver platform, konto eller mailingliste, og der sidder ingen rangeringsalgoritme mellem et indlæg og de mennesker, der bad om at se det.

Den anden beslutning er formaterne. Nogle læsere tager kun RSS og andre kun Atom, og man kan ikke på forhånd vide, hvilket en given abonnents læser vil have. At udgive begge dækker hullet for prisen af en skabelon mere, og JSON Feed lægger et tredje oveni til software skrevet af folk, der hellere vil arbejde med JSON. Hvert ekstra format er en fil mere, der skal holdes i takt: samme indlæg, samme id’er, samme datoer.

Den tredje er, hvor meget tekst hvert indlæg skal have. Et feed med den fulde tekst lader folk læse hele stykket i deres læser, hvilket er meget af pointen med en læser, og det koster udgiveren sidevisninger. Et feed med kun resuméer sender læseren hen på sitet for hvert eneste indlæg. Begge dele er legitime; valget står mellem, hvor langt teksten rejser, og hvor tit selve siden bliver besøgt.

Uanset svarene er adressen et løfte. Læsere henter den URL, de fik, efter en plan, hver læser selv vælger (RSS lader et feed foreslå et interval i minutter med ttl, og læseren må gerne se bort fra det), og mange bliver ved i årevis. Når en feedadresse først er sendt ud, bliver den der.

Sådan ser det ud i praksis

Dette site udgiver alle tre formater fra sin danske forside, på /da/index.xml (RSS), /da/atom.xml (Atom) og /da/feed.json (JSON Feed). Kolofonen lister dem og de tjenester, der tjekker dem: alle tre har den fulde tekst, og der er to XML-feeds og ikke ét, fordi nogle læsere kun tager det ene af de to, og det er ikke til at forudsige hvilket. W3C’s feed-validator tjekker Atom- og RSS-feedet, og JSON Feed-validatoren tjekker det tredje, som W3C’s tjeneste ikke dækker, fordi den er ældre end formatet. W3C’s tjeneste advarer om, at de fleste indlæg deler ændringsdato. Siden lader advarslen stå i stedet for at skjule den: datoerne kommer fra git-historikken, og de fleste af siderne blev skrevet i de samme få commits.

Kontaktsiden tilbyder feedsene som en måde at følge virksomheden på uden en konto, ved siden af de sociale profiler, og gentager, at alle tre har den fulde tekst af alt, der udgives.

Ingen af de tre er skrevet i hånden eller laves, når nogen spørger efter dem. I projektet, der byggede sitet, genereres sitet udelukkende ved bygningstid uden en backend, der kører, hver side udgives i fire repræsentationer fra ét indholdstræ, og forsiden lægger tre syndikeringsfeeds og et manifest for en installerbar applikation oveni.

Hvor det går galt

Alle gamle indlæg dukker op igen som nye. Efter et redesign, et domæneskifte eller en ny skabelon ser abonnenterne snesevis af indlæg, de læste for måneder siden. Læsere genkender et indlæg på dets id, Atoms id, RSS’ guid eller JSON Feeds id, og når den streng skifter, er indlægget nyt for dem. RFC 4287 siger udtrykkeligt, at et indlægs id skal overleve flytning, migrering og genudgivelse. Et permalink er kun et godt id, så længe sitet lover at beholde den gamle streng efter en flytning. I RSS bør man også sige, hvad guid er: specifikationen sætter isPermaLink til true som standard, og dette sites RSS-skabelon skriver alligevel isPermaLink="true", fordi en læser, der gætter den anden vej, importerer hvert indlæg igen som en dublet.

Feedet påstår at være ændret ved hvert build. Datoen på feedniveau flytter sig, hver gang sitet bygges, uanset om der er udgivet noget, så software, der holder øje med den dato, slår alarm over ingenting. Årsagen er en skabelon, der stempler klokkeslættet ved bygningstid. RSS definerer lastBuildDate som sidste gang, kanalens indhold ændrede sig, og Atoms updated på feedniveau betyder stort set det samme, så datoen bør komme fra det nyeste indlæg. Dette sites Atom-skabelon tager den fra det nyeste indlæg af netop den grund.

Feedet holder op med at lade sig parse efter en typografisk ændring. Læsere melder feedet i stykker, og en validator peger på en udefineret entitet i den første artikel med et typografisk anførselstegn. XML har fem foruddefinerede navngivne entiteter, lt, gt, amp, apos og quot, mens HTML definerer hundredvis flere. En Markdown-renderer, der skriver anførselstegn og tankestreger som HTML’s navngivne entiteter, laver markup, der er fin på en side og fatal inde i et XML-element. Escape HTML’en, før den sættes ind, sådan som Atoms indhold med type="html" forventer, eller pak den ind i en CDATA-sektion, som RSS Best Practices Profile tillader til content:encoded. Dette sites Atom-skabelon escaper sit indhold, og kommentaren ved siden af noterer, at feedet slet ikke lod sig parse, da det blev skrevet råt.

Abonnenterne glider væk efter en flytning, og udgiveren hører intet. Et feed har ingen afmeldingsknap og ingen liste, der skrumper, så det eneste tegn er stilhed. Feedets adresse er ændret, eller filen er fjernet, og hver læser, der henter den gamle URL, får nu en fejl. Hold den gamle adresse i live, enten med selve feedet eller med en permanent omdirigering. Dette site beholder sine RSS-feeds på index.xml, standardnavnet i den generator, det er bygget med, fordi det er den adresse, eksisterende læsere henter; og på et sprog, sitet ikke annoncerer, skriver det stadig velformede feeds med nul indlæg, så en læser får et gyldigt dokument frem for en 404.

To feeds smelter sammen til ét i en abonnementsdialog. En browserudvidelse eller en læser tilbyder ét feed, hvor siden erklærer to. To alternative links med samme type og samme titel ligner ét feed for sådan et værktøj, og det viser det, det så sidst. Giv hvert sin egen titel; dette sites sider navngiver deres med sitets navn efterfulgt af »(RSS)«, »(Atom)« eller »(JSON Feed)«.

Læs mere

Ordliste