Vzhled
Veřejné REST API
Veřejné rozhraní Než zazvoní CMS slouží k poskytování publikovaného obsahu webovému frontendu v Next.js i případným externím čtecím integracím. Rozhraní staví na REST API systému Strapi 5 a je navrženo s důrazem na maximální bezpečnost a minimální plochu k útoku.
Veřejné API funguje výhradně v režimu pouze pro čtení. Běžní návštěvníci školního webu, žáci ani rodiče se do systému nepřihlašují a zápisové operace přes veřejné rozhraní vůbec neexistují.
Architektura a princip fungování
Rozhraní se od běžných instalací Strapi liší tím, že zcela postrádá výchozí plugin uživatelských účtů (users-permissions). Díky tomu v systému vůbec neexistují rizikové veřejné cesty pro registraci uživatelů, přihlašování návštěvníků, obnovu hesel ani OAuth konektory.
Anonymní přístup zajišťuje vlastní bezpečnostní strategie public-read registrovaná v jádře CMS. Tato strategie automaticky zpracovává každý anonymní požadavek na aplikační rozhraní a povoluje výhradně operace pro vyhledání a zobrazení (find a findOne) u čtyř vyjmenovaných typů obsahu. Všechny ostatní požadavky končí chybou.
Interní nástroje vyžadující zápis (například importní skripty nebo administrativní procesy) nepracují přes veřejné rozhraní: využívají interní aplikační rozhraní s administrátorskými tokeny nebo přímý přístup k databázové vrstvě v kontejneru.
Kde rozhraní najdete
Základní adresa aplikačního rozhraní má tvar:
https://cms.<doména>/apiPro laboratorní a demonstrační účely slouží adresa:
https://cms.lab.navit.cz/apiVšechny požadavky se odesílají protokolem HTTP metodou GET. Požadavky odesílané jinou metodou (POST, PUT, DELETE či PATCH) server okamžitě odmítne chybovým kódem 404 nebo 405, protože zápisové cesty v routerech vůbec nejsou zaregistrovány.
Veřejně dostupné endpointy
Veřejné rozhraní zpřístupňuje přesně čtyři typy obsahu:
| Endpoint | Typ obsahu v CMS | Povolené operace | Popis dat |
|---|---|---|---|
/api/schools | api::school.school | find, findOne | Základní nastavení školy, identita, doména, vizuální styl, menu a kontakty |
/api/pages | api::page.page | find, findOne | Stránky webu včetně struktury sekcí, textů a odkazů |
/api/posts | api::post.post | find, findOne | Články a aktuality, jejich datum, kategorie, obsah a přílohy |
/api/categories | api::category.category | find, findOne | Kategorie aktualit sloužící k filtrování článků na webu |
Každý z těchto endpointů podporuje získání seznamu záznamů (GET /api/<typ>) i získání konkrétního záznamu podle jeho systémového identifikátoru (GET /api/<typ>/:documentId).
Co ve veřejném API nenajdete
Z bezpečnostních a architektonických důvodů jsou následující oblasti před veřejností zcela uzavřeny:
- Přiřazení redaktorů (
/api/editors): Záznamy propojující uživatele administrace se školami jsou čistě interní a veřejný endpoint pro ně neexistuje. - Historie změn a audit log (
/api/audit-logs): Záznamy o úpravách v administraci jsou přístupné pouze superadminovi v rozhraní administrace. - Koncepty a rozpracovaný obsah: Parametr
status=draftveřejný čtenář použít nemůže. Bezpečnostní mechanismus CMS (Document Service guard) pro anonymní požadavky vždy vynucuje stavstatus=published. Neveřejný koncept se přes veřejné rozhraní nikdy nevrátí. - Uživatelské účty a registrace: Cesty jako
/api/auth/local/register,/api/usersnebo/api/users/meneexistují a vracejí kód 404. - Správa souborů a složek: Rozhraní
/uploadvyžaduje platné přihlášení do administrace a podléhá přísnému oddělení složek jednotlivých škol.
Parametry dotazů a práce s daty
Dotazování probíhá pomocí standardních parametrů URL v zápisu formátu qs. CMS má zapnutou přísnou kontrolu parametrů (strictParams: true), proto neznámé nebo chybné parametry vedou k chybové odpovědi 400.
Filtrování záznamů (filters)
Filtrování umožňuje vybrat data jedné konkrétní školy nebo zúžit výběr stránek a článků.
Výběr obsahu konkrétní školy podle její zkratky:
/api/pages?filters[school][slug][$eq]=oapvVýběr konkrétní stránky podle její celé cesty:
/api/pages?filters[school][slug][$eq]=oapv&filters[path][$eq]=pro-uchazece/oboryZískání podstránek pro sestavení rozcestníku (cesta začínající určitým prefixem):
/api/pages?filters[school][slug][$eq]=oapv&filters[path][$startsWith]=pro-uchazece/Filtrování článků podle kategorie:
/api/posts?filters[school][slug][$eq]=oapv&filters[category][slug][$eq]=ze-zivota-skolyJednoduché textové vyhledávání v nadpisech a perexech:
/api/pages?filters[school][slug][$eq]=oapv&filters[$or][0][title][$containsi]=přijímačky&filters[$or][1][excerpt][$containsi]=přijímačkyVýběr polí (fields)
Při načítání navigace nebo odkazů není nutné přenášet celé tělo stránky. Výběrem konkrétních polí výrazně snížíte objem přenášených dat:
/api/pages?filters[school][slug][$eq]=oapv&fields[0]=title&fields[1]=path&fields[2]=orderNačítání vazeb a sekcí (populate)
Pro načtení navázaných obrázků, kategorií nebo dynamických sekcí stránek slouží parametr populate.
Načtení loga a hlavičky školy:
/api/schools?filters[slug][$eq]=oapv&populate[logo]=true&populate[headerImage]=trueNačtení položek menu včetně jejich podpoložek:
/api/schools?filters[slug][$eq]=oapv&populate[menu][populate][children]=trueNačtení sekcí stránky v dynamické zóně vyžaduje zápis se selektorem [on]:
/api/pages?filters[school][slug][$eq]=oapv&filters[path][$eq]=&populate[sections][on][section.hero][populate][image]=true&populate[sections][on][section.hero][populate][buttons]=true&populate[sections][on][section.cards][populate][items][populate][image]=trueŘazení výsledků (sort)
Řazení se definuje polem parametrů:
/api/pages?filters[school][slug][$eq]=oapv&sort[0]=order:asc&sort[1]=title:asc
/api/posts?filters[school][slug][$eq]=oapv&sort[0]=date:descStránkování (pagination)
Systém vrací data po stránkách. Výchozí velikost stránky je 25 záznamů, maximální povolená hodnota je 100:
/api/posts?filters[school][slug][$eq]=oapv&pagination[page]=1&pagination[pageSize]=12Odpověď obsahuje metadata s celkovým počtem položek a stránek:
json
{
"data": [ ... ],
"meta": {
"pagination": {
"page": 1,
"pageSize": 12,
"pageCount": 4,
"total": 42
}
}
}Bezpečnost a limity provozu
Na veřejné rozhraní dohlíží několik bezpečnostních mechanismů:
- Omezení počtu požadavků (Rate Limiting): Pro veřejnou adresu
/apiplatí výchozí limit 300 požadavků za minutu z jedné IP adresy. Počet hlídá interní middleware. Přímé požadavky mezi kontejnery v dockerové síti (bez klientské hlavičkyX-Forwarded-For) se do tohoto limitu nepočítají, aby generování stránek na serveru nebylo blokováno. - CORS ochrana: Povoluje volání pouze z domén uvedených v konfiguraci platformy (výchozí hodnota odpovídá systémové adrese CMS). Prohlížeče návštěvníků navíc API nevolají přímo: veškerá data získává webový server v Next.js.
- Bezpečnostní hlavičky: Server neposílá hlavičku
X-Powered-By, která by prozrazovala použitou technologii. Odpovědi obsahují bezpečnostní hlavičky včetněX-Content-Type-Options: nosniffa odpovídající direktivy Content Security Policy.
Na následujícím snímku vidíte, jak web školy prezentuje data získaná z veřejného rozhraní pro výpis aktualit:

Tipy pro vývojáře
Vždy filtrujte podle školy
Protože jedna instalace CMS obsluhuje více škol, každý dotaz na stránky, články nebo kategorie musí obsahovat filtr na školu (filters[school][documentId][$eq]=... nebo filters[school][slug][$eq]=...). Zabráníte tím nechtěnému smíchání obsahu různých škol.
Mezipaměť na straně webu
Webový frontend v Next.js ukládá odpovědi z rozhraní CMS do serverové mezipaměti na dobu 60 sekund. Změna publikovaná redaktorem v administraci se proto na veřejném webu projeví nejdéle do jedné minuty.
Pozor na velikost odpovědí
Při načítání stránek se sekcemi nepoužívejte zástupný zápis populate=*. U složitých stránek může takový dotaz způsobit přenos zbytečných dat a zpomalit odezvu databáze. Vždy specifikujte přesný seznam požadovaných komponent a polí.

