Używamy cookies, żeby zwiększyć Twoje doświadczenia na stronie
CodeWorlds
Powrót do kolekcji
Przewodnik11 min czytania

Strapi 5, otwarty system treści

Strapi to otwarty system treści z panelem do budowy modelu. Zmiany w piątce, koszt wdrożenia u siebie wobec chmury i pułapki przy migracji.

Strapi, czyli model treści budowany w panelu

Większość nowoczesnych systemów treści wymaga programisty do zmiany struktury danych. Strapi robi to inaczej: model budujesz w interfejsie, klikając, a API razem z panelem redakcyjnym powstaje z tego automatycznie.

Ta różnica decyduje o wyborze częściej, niż sugerują porównania funkcji. Zespół, w którym redakcja albo osoba prowadząca projekt ma sama dodać pole do formularza kontaktowego, potrzebuje właśnie tego. Zespół z programistami może wolić trzymać model w kodzie.

Projekt jest otwarty i można go uruchomić u siebie bez opłat licencyjnych, przy czym licencja jest podzielona i warto o tym wiedzieć. Większość kodu objęta jest licencją MIT, natomiast wszystko, co leży w katalogach oznaczonych jako wydanie dla przedsiębiorstw, podlega osobnej licencji producenta. Dlatego serwisy skanujące zależności pokazują przy tym projekcie licencję nierozpoznaną, a nie MIT. Producent oferuje też hosting zarządzany, i różnica między tymi dwiema drogami jest większa, niż wygląda na pierwszy rzut oka.

Co zmieniła piątka

Wersja piąta wprowadziła zmiany, które przy migracji wymagają realnej pracy, więc warto poznać je przed rozpoczęciem.

Najważniejsza dotyczy sposobu odwoływania się do treści. Wcześniej każdy wpis miał identyfikator liczbowy, teraz podstawowym odwołaniem jest osobny identyfikator dokumentu. Powód jest sensowny: jeden dokument może mieć wersję roboczą i opublikowaną oraz wersje w kilku językach, a wszystkie są tym samym dokumentem.

Konsekwencja jest bolesna przy migracji. Narzędzie automatyzujące przejście zamieni wywołania funkcji, natomiast nie odgadnie nowych identyfikatorów dla treści, która już istnieje, więc te miejsca trzeba przejrzeć ręcznie.

Druga zmiana dotyczy warstwy dostępu do danych. Dawny interfejs został wycofany na rzecz nowego, opartego na pojęciu dokumentu. Przy okazji zmieniło się zachowanie: pobranie wielu wpisów zawsze zwraca tablicę, a osobnej metody do stronicowania nie ma.

Trzecia dotyczy stanu publikacji. Parametr rozróżniający wersję roboczą od opublikowanej zmienił nazwę i sposób działania, co narzędzie migracyjne obsługuje samo.

Praktyczna rada przy migracji: uruchom narzędzie automatyzujące, a potem przeszukaj projekt pod kątem oznaczeń, które zostawiło w miejscach wymagających decyzji. To one wskazują, gdzie trzeba pomyśleć, i pominięcie ich kończy się błędami dopiero na produkcji.

Warto też zaplanować migrację na osobnej gałęzi i przetestować ją na kopii danych produkcyjnych, a nie na pustej bazie deweloperskiej. Nowe identyfikatory dotyczą istniejącej treści, więc problemy ujawniają się dopiero wtedy, gdy tej treści jest dużo i pochodzi z realnego serwisu.

Wdrożenie u siebie a chmura

To jest decyzja o największych konsekwencjach finansowych i warto podjąć ją świadomie.

Wariant własny nie kosztuje nic w opłatach licencyjnych. Płacisz za maszynę, bazę danych i magazyn plików, czyli za rzeczy, które i tak masz albo które kosztują niewiele. Przy małym serwisie to rząd kilkunastu dolarów miesięcznie, na przykład na Railway albo dowolnym innym dostawcy.

Wariant zarządzany kosztuje za projekt, w kilku progach różniących się limitami. Zdejmuje z Ciebie utrzymanie, aktualizacje i skalowanie, co przy zespole bez osoby od infrastruktury bywa warte swojej ceny.

Trzy rzeczy warto policzyć, zanim wybierzesz, bo intuicja myli się w obie strony.

Pierwsza to koszt utrzymania własnego wdrożenia. Aktualizacje, kopie zapasowe, monitorowanie i reagowanie, gdy coś przestanie działać, to praca kilku godzin miesięcznie. Przy stawce godzinowej programisty ta praca bywa droższa niż abonament.

Druga to opłaty za przekroczenie limitów w wariancie zarządzanym. Liczba zapytań, ruch wychodzący i miejsce na pliki są rozliczane osobno powyżej progu, więc serwis ze zdjęciami potrafi wygenerować rachunek wyraźnie wyższy od podstawy.

Trzecia to liczba projektów. Rozliczenie za projekt oznacza, że agencja prowadząca dziesięć serwisów płaci dziesięć razy, podczas gdy przy wdrożeniu własnym jedna maszyna obsłuży kilka mniejszych.

Budowanie modelu treści

Praca zaczyna się od panelu, w którym definiujesz typy treści i pola.

Code
Bash
npx create-strapi-app@latest moj-projekt

Po uruchomieniu tworzysz konto administratora i budujesz model klikając: typ treści dla artykułów, pola dla tytułu, treści i obrazka, powiązanie z autorem. API pojawia się natychmiast, razem z dokumentacją i panelem do wprowadzania treści.

To jest zaleta, której konkurencja z modelem w kodzie nie ma, i wada w tym samym miejscu. Model zmieniany klikaniem rozjeżdża się między środowiskami, bo zmiana wprowadzona lokalnie nie trafia automatycznie na produkcję.

Rozwiązaniem jest zapisywanie struktury w plikach projektu, co Strapi robi automatycznie. Zmiany modelu wprowadzone w trybie deweloperskim zapisują się jako pliki, które trafiają do repozytorium i wykonują się przy wdrożeniu.

Code
JSON
{
  "kind": "collectionType",
  "collectionName": "artykuly",
  "info": { "singularName": "artykul", "pluralName": "artykuly" },
  "attributes": {
    "tytul": { "type": "string", "required": true, "maxLength": 120 },
    "slug": { "type": "uid", "targetField": "tytul" },
    "tresc": { "type": "richtext" },
    "autor": { "type": "relation", "relation": "manyToOne", "target": "api::autor.autor" }
  }
}

Ten plik jest jedynym źródłem prawdy o modelu, więc przegląd zmiany w nim jest przeglądem zmiany struktury bazy. To jest ta właściwość, dla której warto trzymać się zasady zmieniania modelu wyłącznie lokalnie.

Z tego wynika zasada warta przyjęcia od początku: model zmieniaj wyłącznie lokalnie, nigdy na produkcji. Panel na produkcji służy do wprowadzania treści, a nie do zmiany jej struktury, i warto to ustawić również technicznie, wyłączając możliwość edycji modelu poza trybem deweloperskim.

Uprawnienia i dostęp do API

To obszar, w którym najczęściej popełnia się błąd o poważnych skutkach, bo domyślne ustawienia są przemyślane, a pierwsza próba uruchomienia API zwykle kończy się ich obejściem.

Nowo utworzony typ treści nie jest domyślnie dostępny publicznie. Zapytanie do API zwraca odmowę, co jest zachowaniem prawidłowym i mylącym, bo wygląda na błąd konfiguracji. Naturalnym odruchem jest włączenie dostępu publicznego dla wszystkich operacji, żeby sprawdzić, czy działa.

To właśnie moment, w którym pojawia się problem. Włączenie operacji zapisu dla roli publicznej oznacza, że każdy, kto zna adres API, może utworzyć, zmienić albo usunąć treść. Odkrywa się to zwykle wtedy, gdy w serwisie pojawiają się wpisy, których nikt nie dodawał.

Właściwy układ jest prosty. Rola publiczna dostaje wyłącznie odczyt i wyłącznie dla typów treści, które faktycznie mają być widoczne. Operacje zapisu wymagają tokenu, a token generuje się w panelu z ograniczonym zakresem i przekazuje wyłącznie przez zmienne środowiskowe.

Sprawdzenie zajmuje chwilę i warto je wykonać przed każdym wdrożeniem, bo panel pokazuje ustawienia, a nie ich skutek.

Code
Bash
curl -s -o /dev/null -w "odczyt: %{http_code}\n" \
  https://cms.mojafirma.pl/api/artykuly

curl -s -o /dev/null -w "zapis bez tokenu: %{http_code}\n" \
  -X POST -H "Content-Type: application/json" \
  -d '{"data":{"tytul":"test"}}' \
  https://cms.mojafirma.pl/api/artykuly

Pierwsze wywołanie powinno zwrócić 200, drugie 403. Kod 200 przy drugim oznacza, że rola publiczna ma prawo zapisu, czyli każdy, kto zna adres, może dodać treść.

Osobną warstwą są uprawnienia redakcyjne. Domyślnie osoba dodana do panelu widzi wszystko, a role pozwalają zawęzić to do konkretnych typów treści i operacji. Przy zespole liczącym więcej niż kilka osób warto z tego skorzystać, choćby po to, żeby nikt nie usunął przypadkiem typu treści razem z zawartością.

Wydajność i buforowanie

Kilka rzeczy, które przy większym ruchu decydują o tym, czy serwis działa, a które przy prototypie nie mają znaczenia.

Domyślnie zapytanie o listę zwraca ograniczoną liczbę wpisów, i warto ten limit rozumieć, bo aplikacja pobierająca „wszystkie artykuły" dostanie pierwsze kilkadziesiąt i nie zauważy, że reszty brakuje.

Rozwijanie powiązań jest tu drugą pułapką. Pobranie artykułów razem z autorami, kategoriami i obrazkami generuje zapytania do bazy proporcjonalnie do liczby wyników, więc lista dwudziestu artykułów potrafi wykonać sto zapytań.

Code
TEXT
Drogo:  /api/artykuly?populate=*

Taniej: /api/artykuly
          ?fields[0]=tytul&fields[1]=slug
          &populate[autor][fields][0]=imie
          &populate[okladka][fields][0]=url
          &pagination[pageSize]=20

Gwiazdka w pierwszym zapisie rozwija wszystkie powiązania i wszystkie pola każdego z nich, łącznie z treścią artykułu, której lista nie pokazuje. Drugi zapis pobiera dokładnie to, co widać na ekranie. Ograniczenie rozwijanych powiązań do faktycznie potrzebnych to najprostsza optymalizacja w całym systemie.

Trzecia rzecz to buforowanie po stronie aplikacji. System treści rzadko musi odpowiadać przy każdym wejściu użytkownika, bo treść zmienia się kilka razy dziennie. Generowanie stron statycznie i odświeżanie ich po zapisie zdejmuje z serwera niemal cały ruch, a przy Next.js wymaga jednego wywołania odświeżającego po publikacji.

Warto też pamiętać o obrazach. Domyślnie serwuje je ten sam proces, który obsługuje API, więc przy serwisie ze zdjęciami to on staje się wąskim gardłem. Przeniesienie plików do magazynu obiektowego z siecią dostarczania treści rozwiązuje to raz i przy okazji obniża koszt.

Strapi kontra alternatywy

RozwiązanieMocna stronaSłabośćKiedy wybrać
StrapiModel budowany w panelu, licencja swobodna, wdrożenie u siebieUtrzymanie po Twojej stronie, migracje między wersjamiRedakcja zmieniająca model bez programisty
SanityTreść jako dane, własny język zapytańModel wyłącznie w kodzieTreść używana w wielu miejscach naraz
PayloadPanel wewnątrz aplikacji, konfiguracja w kodzieWymaga programisty do każdej zmianyProjekt na Next.js z zespołem technicznym
ContentfulDojrzałość, wsparcie dla dużych organizacjiWysoka cena, sztywniejszy modelKorporacja z wymogami zgodności

Pierwszy wiersz wygrywa w jednej konkretnej sytuacji, i warto ją nazwać wprost: gdy osoba nietechniczna ma sama zmieniać strukturę treści. To jedyny system z tej czwórki, w którym to naprawdę działa, i jednocześnie powód, dla którego trafia do projektów, w których nikt tego nie potrzebuje.

Jeśli model i tak zmienia programista, pozostałe trzy wiersze dają lepsze narzędzia: kontrolę wersji modelu, czytelniejsze zapytania albo mniej rzeczy do utrzymania.

Warto też sprawdzić, czy treść jest tu w ogóle głównym problemem. Gdy projekt potrzebuje obok niej logowania, przesyłania plików i powiadomień w czasie rzeczywistym, prościej wychodzi zaplecze ogólnego przeznaczenia niż system treści z doklejonym uwierzytelnianiem. PocketBase daje to wszystko w jednym pliku wykonywalnym, z dwoma zastrzeżeniami, o których jego autor pisze wprost: projekt nie osiągnął jeszcze wersji pierwszej i nie skaluje się poziomo.

Utrzymanie i aktualizacje

Ta część decyduje o kosztach przy dłużej żyjącym projekcie i bywa niedoceniana przy wyborze.

Aktualizacje między wersjami głównymi wymagają pracy, co widać po zmianach w piątce. Narzędzie migracyjne pomaga, natomiast część zmian wymaga decyzji, których nie da się zautomatyzować.

Wtyczki są tu osobną kwestią. Ekosystem jest bogaty, a zgodność z nowymi wersjami zależy od autorów. Przy migracji to zwykle wtyczki, a nie kod aplikacji, decydują o tym, kiedy przejście jest możliwe, więc przed rozpoczęciem warto sprawdzić stan każdej używanej.

Baza danych to trzecia rzecz do zaplanowania. Domyślnie projekt startuje na bazie plikowej, wygodnej lokalnie i nieodpowiedniej na produkcję. Przejście na bazę relacyjną warto wykonać na początku, a nie po pierwszym problemie ze współbieżnym zapisem.

Pliki wgrywane przez redakcję domyślnie lądują na dysku serwera, co przy wdrożeniu bezserwerowym oznacza, że znikają przy każdym wdrożeniu. Wtyczka kierująca je do magazynu obiektowego rozwiązuje to raz i warto ją dodać przed wgraniem pierwszego zdjęcia, bo przeniesienie istniejących plików wymaga osobnego skryptu.

Typowe błędy

Pierwszy to zmiana modelu treści na produkcji. Struktura zapisuje się w plikach projektu, więc zmiany wprowadzane bezpośrednio na serwerze rozjeżdżają się z repozytorium i giną przy kolejnym wdrożeniu.

Drugi to pozostawienie bazy plikowej na produkcji. Sprawdza się lokalnie i zawodzi przy współbieżnych zapisach oraz przy każdym wdrożeniu na infrastrukturze bezserwerowej.

Trzeci to pliki wgrywane na dysk serwera. Przy wdrożeniu bezserwerowym znikają po każdym wdrożeniu, a odkrywa się to zwykle po tygodniu.

Czwarty to migracja bez sprawdzenia wtyczek. To one najczęściej blokują przejście na nową wersję, a nie kod aplikacji.

Piąty to pominięcie oznaczeń zostawionych przez narzędzie migracyjne. Wskazują miejsca wymagające decyzji, a ich zignorowanie kończy się błędami na produkcji.

Szósty to wybór wariantu zarządzanego bez policzenia opłat za przekroczenie limitów. Zapytania, ruch i miejsce na pliki są rozliczane osobno i przy serwisie ze zdjęciami potrafią przewyższyć podstawę abonamentu.

Siódmy to włączenie operacji zapisu dla roli publicznej przy pierwszym uruchamianiu API. Każdy, kto zna adres, może wtedy zmieniać treść, a odkrywa się to zwykle po pojawieniu się wpisów, których nikt nie dodawał.

FAQ

Czy Strapi jest darmowe?

Wersja społecznościowa jest wydana na licencji swobodnej i nie ma opłat licencyjnych, więc przy wdrożeniu u siebie płacisz wyłącznie za infrastrukturę. Producent oferuje też hosting zarządzany, rozliczany za projekt, z osobnymi opłatami za przekroczenie limitów zapytań, ruchu i miejsca.

Co zmieniła wersja piąta?

Przede wszystkim sposób odwoływania się do treści: podstawowym identyfikatorem jest teraz osobny identyfikator dokumentu, obejmujący jego wersję roboczą, opublikowaną i tłumaczenia. Dawna warstwa dostępu do danych została wycofana, a pobieranie wielu wpisów zawsze zwraca tablicę.

Jak trudna jest migracja z czwórki?

Narzędzie automatyzujące zamienia wywołania funkcji i część parametrów, natomiast nie odgadnie nowych identyfikatorów dla istniejącej treści. Te miejsca oznacza do przejrzenia i to one wymagają pracy. Przed rozpoczęciem sprawdź też zgodność wszystkich używanych wtyczek.

Czy redakcja naprawdę zmieni model bez programisty?

Tak, i to jest główna przewaga tego systemu. Warto natomiast wprowadzić zasadę, że zmiany modelu robi się wyłącznie w środowisku deweloperskim, bo struktura zapisuje się w plikach projektu i musi trafić na produkcję razem z kodem.

Wdrożenie u siebie czy chmura?

Przy jednym projekcie i zespole bez osoby od infrastruktury hosting zarządzany zwykle się opłaca. Przy kilku projektach albo przy istniejącym zapleczu technicznym wdrożenie własne wychodzi taniej, bo licencja nic nie kosztuje, a jedna maszyna obsłuży kilka mniejszych serwisów.

Dokumentacja stoi na stronie projektu, a listę zmian w wersji piątej opisuje dział poświęcony migracji.