Zpět na domů

Frontend jako REST server: architektura a vzory

Článek zkoumá architektonické paralely mezi klientskou a serverovou vývojí. Autor demonstruje, jak použití vzorů REST, DTO a vrstvené architektury ve frontendu snižuje propojenost kódu a usnadňuje podporu SPA.

Klientní REST: navozujeme pořádek ve frontendové architektuře
Advertisement 728x90

# Frontend jako klientský REST server: architektonická disciplína místo chaosu manažerů stavu

Moderní frontendový vývoj už dávno překročil fázi manipulací s DOM a jednoduché sazby. Z architektonického hlediska SPA a SSR aplikace plní stejný úkol jako klasické serverové systémy: přijímají vstupní signály, zpracovávají data podle pravidel business logiky a vracejí hotové zobrazení. Rozdíl spočívá jen v prostředí provádění a protokolu interakce. Místo nekonečného vymýšlení nových abstrakcí pro každý release frameworku je efektivnější aplikovat osvědčené serverové vzory přímo na klientský kód.

Evoluce role: od hypermédií k klientskému renderingu

Původně web fungoval podle průhledného schématu: prohlížeč požadoval URL, server generoval HTML, klient zobrazoval výsledek. Překvapivé, ale standardní HTML je nativní realizací principu HATEOAS. Server nevrací jen data, ale stav rozhraní společně s dostupnými přechody: odkazy, formuláři s uvedenými metodami, tlačítky akcí. Klient neukládá mapu tras předem – reaguje na to, co je povoleno v aktuálním kontextu.

Moderní přístup s JSON API změnil jen formát přenosu stavu, ne jeho podstatu. Stejný princip lze vyjádřit prostřednictvím HAL formátu:

Google AdInline article slot
{
  "id": 42,
  "status": "pending",
  "_links": {
    "self":   { "href": "/orders/42" },
    "cancel": { "href": "/orders/42/cancel", "method": "POST" },
    "detail": { "href": "/orders/42/detail" }
  }
}

Formule UI = f(state) existovala dlouho před vznikem virtuálního DOM. Dříve se stav přenášel z vzdáleného serveru celý, dnes se počítá lokálně a aktualizuje inkrementálně. Problém nevznikl změnou paradigmatu, ale ztrátou architektonické disciplíny při přesunu logiky na klient.

Události jako požadavky: mapování architektonických vrstev

V backendovém vývoji je interakce přísně regulována. Controller přijímá HTTP požadavek, validuje vstupní data, převede je na DTO a deleguje zpracování na servisní vrstvu. Servis pracuje s doménovým modelem, repository odpovídá za perzistenci. Hranice odpovědností jsou jasné a nezávisí na konkrétním jazyce nebo frameworku.

Na frontendu uživatelské akce (kliky, vstupy, scrollování, zprávy z WebSocket) fungují jako plný analog HTTP požadavků. Event = Request. Místo unifikovaných controllerů však ekosystém zplodil zoologickou zahradu termínů: store, composables, hooks, atoms, runes, view-model. Každý nástroj vnucuje svou filozofii řízení stavu a maže architektonické hranice. Logičtější je přizpůsobit klientskou architekturu serverovému standardu:

Google AdInline article slot
Frontend
  
  웃  →  Event   → Controller → Service → Repository  → → → → → → Rest API
  │     │         │            ↑         │                               │
  │     │         │            │         └─ Builds HTTP Request          │
  │     │         │            │                                         │
  │     │         │            └─ Business logic                         │
  │     │         │                                                      │
  │     │         └─ Extracts, validates & maps to DTO                   │
  │     │                                                                │
  │     └─ Environment detail - Browser Event                            │
  │                                                                      │
  │                                                                      │
  │                                                                      │
  └─  ← Response ← Controller ← Service ← Repository  ← ← ← ← ← ← Rest API
        │          │                      │
        │          │                      └─ Maps to Domain Model
        │          │                             
        │          └─ Maps to framework format: JSX/Vue template
        │
        └─ Automatically mapped to HTML chunk from JSX by framework

Stateful controllery a infrastrukturní detaily

Hlavní námitka proti přímému přenosu serverových vzorů se týká stavu. Klasické REST controllery jsou navrženy jako stateless pro horizontální škálování. Frontend však podle definice pracuje v stateful kontextu: relace uživatele, lokální cache, stavy formulářů a UI prvků žijí v paměti prohlížeče. To není rozpor, ale vlastnost prostředí. V backendu se podobné stateful vzory používají v gamedevu, IoT bránách a streamovacích službách na bázi gRPC nebo WebSockets.

Hooks, signály a reaktivní atoms je třeba chápat výhradně jako infrastrukturní detaily. Jde o mechanismy, které framework používá pro efektivní aktualizaci DOM a sledování závislostí. Chyba spočívá v tom, že vývojáři ukládají business pravidla a validaci přímo do těchto primitivů. State manažeři často maskují prosáchnuté abstrakce a umožňují UI komponentám přímou závislost na struktuře úložiště. Vytvoření vrstvy controllerů a servisů tento problém řeší tím, že izoluje business logiku od reaktivního systému frameworku.

Praktické uplatnění serverové disciplíny

Zavedení backendových přístupů nevyžaduje odmítnutí React, Vue nebo Solid. Jde o strukturování kódu v rámci ekosystému. Pro dosažení předvídatelnosti a snížení kognitivní zátěže při nasazování nových vývojářů stačí dodržovat několik principů:

Google AdInline article slot
  • Přísná validace vstupních událostí a dat z API na hranici aplikace (použití Zod, Yup nebo TypeScript guardů).
  • Převod syrových odpovědí serveru a uživatelských vstupů na DTO před předáním do business vrstvy.
  • Izolace doménové logiky v čistých servisech, které neimportují hooks frameworku a nevědí o existenci DOM.
  • Použití repository pro abstrakci nad zdroji dat (LocalStorage, IndexedDB, REST, GraphQL).
  • Controllery slouží jako jediný spojovací bod: mapují události na volání servisů a výsledky na props pro prezentační komponenty.

Takový přístup činí kód agnostickým vůči frameworkům. Business logika se snadno pokrývá unit testy bez mocků renderovacího enginu a migrace mezi různými UI řešeními ovlivní jen tenkou vrstvu adaptérů.

Co je důležité

  • Frontendová aplikace je architektonicky ekvivalentní REST serveru nasazenému v prohlížeči: události nahrazují HTTP požadavky a rendering tvoří odpověď.
  • HTML historicky realizuje principy HATEOAS tím, že klientovi předává stav a dostupné akce současně.
  • Rozmanitost termínů (store, composables, atoms) vytváří iluzi novosti, ale často maže hranice odpovědností a ztěžuje údržbu kódu.
  • Hooks a signály jsou infrastrukturní primitivy frameworku, ne místo pro business pravidla nebo složitou validaci.
  • Použití serverové disciplíny (DTO, controllery, servisy, repositoria) snižuje propojenost kódu, usnadňuje testování a činí architekturu nezávislou na konkrétním UI frameworku.

— Editorial Team

Advertisement 728x90

Číst dál