Toto je opäť kombinácia môjho predchádzajúceho príspevku o oznámení feedu a príspevku pred ním o príkaze uuid. To, že tieto dva prišli jeden po druhom, nie je náhoda, hoci sa zdá, že majú veľmi málo spoločného. Aké je teda spojenie medzi Atom feedom a Universally Unique IDentifiers (UUID)?
Špecifikácia Atom ID #
V RFC4287, štandarde IETF opisujúcom špecifikáciu formátu Atom, je element atom:id definovaný takto:
Element „atom:id” nesie permanentný, celosvetovo jedinečný identifikátor pre záznam alebo feed. Jeho obsah MUSÍ byť IRI, ako je definované v RFC3987.
Čo znamená IRI? No, dá sa o tom veľa čítať, ale pre všetky praktické účely to znamená, že IRI je nadmnožinou Uniform Resource Identifier (URI), čo znamená, že každé URI je zároveň IRI, ale len niektoré IRI je zároveň URI. Rozdiel spočíva v sade kódovania znakov — IRI používa rozšírenú.
Teraz vieme, že ID použité v Atom feede môže byť čokoľvek, čo by sme nazvali URI. URI, pri použití v Atom feede, možno ďalej rozdeliť do dvoch skupín: Uniform Resource Locator (URL) a menej známy Uniform Resource Name (URN). URI je nadmnožinou pre obidva — každé URL je zároveň URI a rovnako každé URN je zároveň URI. URN a URL sú však disjunktné, čo znamená, že žiadne URL nie je zároveň URN a naopak. Alebo inak povedané, Atom ID môže byť buď URL, alebo URN.
URL vs URN: ktorý zvoliť? #
Hoci použitie URL pre Atom ID je v súlade so štandardom, má niektoré nevýhody. Konkrétne, URL sa niekedy mení, a deje sa to oveľa častejšie, ako by ste si mysleli, hoci zatiaľ neexistuje záverečné číslo.
Ako bolo citované vyššie, element Atom ID musí byť permanentný a na tento účel je URN oveľa vhodnejší. V praxi by použitie URN znamenalo, že klient RSS alebo Atom feedu by si príspevok ponechal prečítaný aj v obľúbených, aj keď blog presunie na inú doménu a zmení tak jeho URL. V skutočnosti je počet klientov obrovský a každý robí niečo trochu inak, ale to hovorí teória.
Musí byť URN registrované? #
Pri väčšine URN, napríklad pri odkazovaní na International Standard Book
Number (ISBN) vo forme urn:isbn:, musí byť URN zaregistrované centrálnou
autoritou. Existuje ale aspoň jedna taká skupina URN, ktorá registráciu
nevyžaduje — a to je skupina UUID, pod praktickým označením urn:uuid:. Tu
sa URN a UUID prelínajú a tvoria užitočné partnerstvo pre identifikáciu
zdrojov dlho po zániku ich pôvodného umiestnenia.
Na chvíľu si predstavte scenár, kde nejaký budúci archeológ nájde USB kľúč so súborom feedu obsahujúcim celý Atom feed vášho blogu. Technológia by vtedy mohla napríklad používať nejaký biologický mechanizmus na ukladanie dát namiesto kremíka, ale možno by stále chceli dáta preskúmať. Ak by boli príspevky identifikované pomocou URL, mohlo by byť ťažké ich prepojiť s dátami v nejakej globálnej databáze, pretože názvy domén každý rok expirujú. Zhodu by bolo možné nájsť porovnávaním obsahu so všetkým v databáze. Použitie definovaného identifikátora ako UUID by sa na druhej strane dalo ľahko porovnať so záznamami v databáze a dokonca aj UUID kolízie, dnes nepravdepodobné, ale v budúcnosti veľmi možné, by sa dali ľahko vyriešiť porovnaním obsahu záznamov so všetkými zodpovedajúcimi UUID. V takomto scenári by použitie URN drasticky zredukovalo priestor vyhľadávania — prinajmenšom z porovnávania celej databázy na porovnávanie iba UUID kolízií.
Ktorú verziu UUID použiť? #
V feede sú dve miesta, kde sa špecifikuje Atom ID. Jedno slúži na identifikáciu samotného feedu a druhé na identifikáciu jednotlivých záznamov. Obidve ID profitujú z použitia UUID URN. Už sme sa naučili v cheatsheetovi, že existuje 5 špecifikovaných verzií UUID, z ktorých 3 sú dostupné/odporúčané v nových riešeniach. Ktorú teda zvoliť a kde? Tu to začína byť trošku zamotané.
UUID verzia 4 pre záznamy? #
Špecifikácia spomína UUID iba v jednom príklade — UUID verzia 1 pre samotný feed a UUID verzia 4 pre záznamy. Všetky ostatné zdroje, ktoré som našiel, sú k tejto téme veľmi vágne, ale vo všeobecnosti je pre záznamy veľmi bežné používanie UUID verzie 4, ktorá má vlastnosť byť úplne náhodná. Tento prístup predpokladá, že takéto UUID sa vygeneruje pri prvom uložení záznamu do databázy, uloží sa spolu so záznamom a následne sa nemení.
Identický prístup sa používa inde, napríklad pre perzistentné pomenovanie blokových zariadení, čo znamená, že keď zapnete počítač, operačný systém vždy naštartuje z rovnakého disku. Jednorázové vygenerovanie UUID pre blokové zariadenia v systéme a ich následné odkazovanie pomocou tohto ID zabraňuje tzv. race condition chybe, ktorá by v tomto príklade nastala vtedy, keď by niektoré zariadenie nabootovalo skôr ako zvyčajne a získalo by tak nesprávny identifikátor, čo by viedlo k občasným zlyhaniam pri štarte systému.
UUID verzia 1 pre feed? #
Nepochopil som, prečo sa vo špecifikácii použila UUID verzia 1 pre feed. Čo je horšie, UUID verzia 1 má špecifické použitia a zdá sa mi, že jej použitie je z bezpečnostných dôvodov neodporúčané, pokiaľ nie je vyžadovaná jej presná vlastnosť predvídateľnosti a v menšej miere aj sekvenčnosti. Pri nesprávnej identifikácii feedu si neviem predstaviť žiadne bezpečnostné riziko, takže UUID verzia 1 tu môže fungovať perfektne. Nakoniec, tam možno dať aj URL blogu. Rozhodol som sa však pre iný prístup.
Prístupy ku generovaniu UUID pre feed #
Uvažoval som o viacerých spôsoboch generovania UUID pre feed:
- Použiť UUID verziu 1 a uložiť ju
- Použiť UUID verziu 4 a uložiť ju
- Použiť UUID verziu 5 s prefixom menného priestoru DNS alebo URL a doménou blogu ako názvom
- Použiť UUID verziu 5 s NIL UUID ako prefixom menného priestoru a URL blogu ako názvom
Keďže UUID verzia 5 má vlastnosť reprodukovateľnosti, prístupy 3 a 4 by slúžili, ak by som mal UUID generovať viackrát. S rovnakým vstupom UUID verzia 5 poskytuje rovnaký výstup. To by však nefungovalo, ak by sa doména (vstupné dáta) zmenila, čím by sa celý účel permanentnej identifikácie zmárnil. To znamená, že prístupy 1 a 2, kde sa UUID vygeneruje raz, uloží a následne používa, sú vhodnejšie. Vylúčiac prístup 1 mi ostalo použitie UUID verzie 4, jej uloženie v kóde a použitie ako ID feedu.
Menné priestory UUID verzie 5 #
Vlastnosť reprodukovateľnosti UUID verzie 5 je však veľmi užitočná pre staticky generované blogy, najmä tie, ktoré fungujú čisto na gite, teda bez databázy. Napríklad ja získavam dátumy publikovania a úprav z histórie git commitov a dokonca sledujem aj premenovania súborov. Zistil som tiež, že Hugo, ďalší generátor statických stránok populárny pre blogovanie, možno nakonfigurovať rovnako, takže tento prístup pravdepodobne nie je príliš výstredný.
Keďže nemám možnosť uložiť vygenerované UUID verzie 4 do databázy, pretože žiadna neexistuje, mohol by som ho uložiť iba do markdown súboru príspevku, najpohodlnejšie do sekcie Front Matter. Som lenivý človek — ručne tam neukladám ani dátumy, ako som uviedol vyššie. Automatizovanie všetkého je výzvou, ale vypláca sa s rastúcou frekvenciou automatizovaných udalostí (hľadajte aj geeks and repetitive tasks).
UUID verzia 5 pre záznamy #
S ohľadom na vyššie uvedené som dospel k generovaniu reprodukovateľného UUID verzie 5 pre ID záznamu. Ako sme sa naučili, UUID verzia 5 vyžaduje dve vstupné hodnoty — UUID prefix a názov. Za prefix som zvolil UUID verziu 4 pre samotný feed a za názov som zvolil hash commitu, ktorým bol príspevok zavedený.
UUID verzia 5 pre záznam Atom = konštantné UUID feedu Atom ako prefix + hash git commitu ako názov
Takto je zaručené, že ID záznamu bude vždy vygenerované rovnako, pokiaľ nezmením UUID feedu — na čo nemám dôvod a je navyše uložené v histórii verzií — alebo pokiaľ neprepisujem históriu git commitov, čomu by sa malo vždy za každých okolností vyhýbať.
To je všetko. Na záver, uvažoval som aj o použití slugu príspevku (čo je v
mojom nastavení názov súboru príspevku bez prípony .md, ďalšia vec, ktorú
neukladám do Front Matter), ale slugy sa niekedy menia pri SEO úpravách. V
mojom nastavení, ako bolo uvedené, sa premenovania sledujú, takže dátumy by
sa nenarušili, ale hash commitu, ktorý zaviedol súbor — ešte pred prípadným
premenovaním — sa nemení, pokiaľ git premenovanie sám rozpozná.
Toto je 58. príspevok #100daystooffload.
Odkazy #
- http://blevs.github.io/pollen-feed-tutorial/#%28part._.U.U.I.D_.U.R.N%29
- https://en.wikipedia.org/wiki/Uniform_Resource_Name
- https://fusion.cs.uni-jena.de/fusion/blog/2016/11/18/iri-uri-url-urn-and-their-differences/
- https://stackoverflow.com/questions/10867405/generating-v5-uuid-what-is-name-and-namespace
- https://stackoverflow.com/questions/7724903/where-do-uuid-namespaces-come-from