Weź odpowiedzialność za swój stos technologiczny i przestań się męczyć
Ukryty koszt integracji, czyli dlaczego frameworki czasem więcej komplikują niż pomagają
Pewnie znasz to uczucie. Wybierasz swój ulubiony framework do backendu, ORM, bibliotekę do walidacji, frontend, narzędzie do budowania. Na papierze wszystko wygląda idealnie. A potem zaczynasz budować prawdziwe funkcje i nagle okazuje się, że Twoja biblioteka do walidacji nie do końca rozumie strukturę danych, którą zwraca Twój ORM. Framework frontendowy nie chce współpracować z middleware'em serwera. Obsługa sesji robi założenia, które psują się przy deploymencie na edge.
Każde narzędzie z osobna jest świetne. Szwy między nimi to koszmar.
Skąd się to wzięło
Ekosystem JavaScript zawsze stawiał na kompozycyjność zamiast na spójność. To nie jest inherentnie złe — filozofia UNIX-a służyła nam przez dekady. Problem polega na tym, że aplikacje webowe to nie rurociągi izolowanych transformacji danych. To splątane sieci współdzielonych założeń: kształty requestów, granice walidacji, przepływy autoryzacji, konteksty renderowania, cele wdrożeń.
Kiedy w 2005 roku pojawił się Django, postawił na inne podejście: programiści chętnie oddadzą część elastyczności w zamian za spójny system. Można było wychodzić poza stack, gdy było trzeba, ale w środku wszystko było zaprojektowane tak, żeby działało razem. Ta odpowiedzialność oznaczała mniej niespodzianek.
Frameworki PHP też to zrozumiały. Laravel, Symfony, Yii — wszystkie dawały to uczucie „jednego spójnego systemu". Wiedziałeś, co należy do oficjalnego terytorium, a co wymaga wyprawy w dzicz.
A potem JavaScript zjadł serwer i w większości to straciliśmy.
Pułapka meta-frameworków
Nowoczesne meta-frameworki poprawiły sytuację w niektórych aspektach. Next.js, Nuxt, SvelteKit — dały nam znów spójny stack. Ale zrobiły to przez zawężenie wyborów, nie przez ich rozszerzenie.
Chodzi o to: Next.js to świetny stack dla Reacta. Ale jeśli zakochasz się w charakterystyce wydajnościowej Solid lub w prostocie Svelte, nie możesz po prostu wymienić warstwy widoku. Musisz przyjąć inny meta-framework z innymi konwencjami, innymi wzorcami routingu, innymi założeniami co do backendu. Uczysz się tych samych problemów, które już rozwiązałeś, tylko z inną składnią.
To tworzy absurdalną sytuację. Ekosystem frontendowy ciągle się rozwija, ale przełączanie się między podejściami wymaga niemal rozpoczynania od zera. Programiści React i programiści Svelte rozwiązują te same problemy backendowe niezależnie, w nieco inny sposób, w nieskończoność.
Loteria runtime'ów
A potem mamy jeszcze fragmentację runtime'ów. Node.js, Deno, Bun — to wszystko zdolne platformy, ale większość frameworków jest de facto runtime-specific. Kiedy framework deklaruje wsparcie dla Deno, często oznacza to tylko tyle, że „Deno może uruchomić nasz kod Node". To nie to samo, co framework zaprojektowany wokół natywnych API i modelu wykonawczego Deno.
To ma większe znaczenie, niż mogłoby się wydawać. Wybrany runtime wpływa na charakterystyki wydajności, cele wdrożeń i modele bezpieczeństwa. Zamykanie się w frameworku, który naprawdę działa tylko na jednym runtime'cie, ogranicza Twoje opcje w miarę ewolucji ekosystemu.
Czego naprawdę potrzebujemy
Oto sedno: aplikacje webowe mają naturalne warstwy, które nie muszą być ze sobą sprzężone.
Frontend opisuje interfejs w przeglądarce. Backend obsługuje requesty, dane i logikę aplikacji. Runtimy to cele wykonawcze. Te关注点 powinny móc się zmieniać niezależnie.
Wyobraź sobie, że budujesz jedną trasę z React, bo potrzebujesz jego ekosystemu komponentów. Inna trasa w Svelte, bo tam wydajność jest ważniejsza. Twoje trasy w Node.js działają dziś, ale inne trasy w TypeScript wdrażasz na Bun, kiedy potrzebujesz szybkości. Wszystko w tej samej aplikacji, z tym samym modelem backendu, tą samą walidacją, tymi samymi sesjami.
To nie jest magične myślenie. To traktowanie关注点 jako oddzielnych关注点 — tak budowało się zawsze dobrze działające oprogramowanie.
Framework powinien zarządzać szwami
Nie argumentuję za jednym frameworkiem, który zapanuje nad wszystkim. Argumentuję za tym, żeby framework brał odpowiedzialność za to, żeby jego części działały razem. Powinieneś nadal móc wychodzić poza oficjalny stack, kiedy potrzebujesz — nikt nie dostarcza idealnych domyślnych rozwiązań dla każdego przypadku użycia. Ale kiedy zostajesz w ramach frameworka, szwy powinny być jego problemem do rozwiązania, nie Twoim.
Framework, który zmusza Cię do myślenia o routingu, walidacji, dostępie do danych i renderowaniu jako oddzielnych problemach, które musisz skleić — to nie framework. To sugestia.
Najlepsze frameworki dają Ci własność logiki biznesowej, jednocześnie przejmując odpowiedzialność za wszystko inne.
W NameOcean widzieliśmy, jak złożoność hostingu może się mnożyć, gdy Twój stack jest rozdrobniony. Wybór frameworka, który szanuje separację关注点 — który pozwala Ci zmieniać części bez przepisywania wszystkiego — sprawia, że deployment, skalowanie i utrzymanie stają się dramatycznie prostsze.
Pytanie nie brzmi, czy używać frameworka. Pytanie brzmi, czy Twój framework pracuje dla Ciebie, czy dodaje kolejną warstwę decyzji, których nie musiałeś podejmować.
Co by to znaczyło zbudować Twoją następną aplikację narzędziem, которое zarządza szwami? To warto przemyśleć, zanim zaczniesz szkieletować kolejny projekt.