Jak wygląda architektura techniczna Shopify od strony backendu

  • 12 minut czytania
  • Shopify
shopify

Architektura techniczna Shopify fascynuje skalą i dojrzałością: od pojedynczego sklepu z kilkoma produktami po globalne marki obsługujące miliony zamówień. Aby zrozumieć, dlaczego platforma jest tak wydajna i elastyczna, warto zajrzeć za kulisy backendu: sposób przechowywania danych, komunikację mikroserwisów, kolejki zadań, cache oraz model rozszerzeń dla aplikacji. To tam rozgrywa się prawdziwa magia skalowania e‑commerce.

Fundamenty backendu Shopify: monolit, języki, skalowanie

Monolit Railsowy i jego ewolucja

Trzon backendu Shopify powstał jako duża aplikacja napisana w Ruby on Rails. Ten historyczny monolit wciąż jest sercem systemu, odpowiedzialnym za logikę biznesową sklepów, obsługę panelu administracyjnego, zarządzanie produktami, klientami oraz zamówieniami. Zamiast wczesnego podziału na mikroserwisy, zespół Shopify przez lata rozwijał jeden duży kod źródłowy, co ułatwiało szybkie zmiany i spójność logiki.

Z czasem, gdy liczba merchantów oraz wolumen ruchu rosły, monolit został podzielony logicznie na moduły, a krytyczne funkcjonalności zaczęto wynosić do osobnych usług. Mimo tego, duża część biznesu nadal wykorzystuje centralny kod Railsowy, który musi być ekstremalnie dobrze przetestowany, monitorowany i skalowany. Shopify postawiło na strategię, w której monolit jest traktowany jak “modułowa platforma”, a nie jak niekontrolowany chaos.

Języki programowania w backendzie

Choć Ruby wciąż jest głównym językiem w warstwie aplikacyjnej, backend Shopify to mieszanka kilku technologii, dobieranych pod kątem wydajności i charakteru zadań. Serce logiki domenowej to Ruby on Rails, ale krytyczne ścieżki wydajnościowe wykorzystują Go, Rust oraz czasem C++ dla niskopoziomowych komponentów.

Go świetnie sprawdza się przy wysoko równoległych usługach, takich jak systemy przetwarzania webhooków czy proxy API. Rust wykorzystywany jest tam, gdzie poprawność i bezpieczeństwo pamięci mają kluczowe znaczenie przy dużej przepustowości, na przykład w systemach kolejkowania lub strumieniowego przetwarzania zdarzeń. Ta wielojęzyczność wymusza dobre standaryzowanie protokołów komunikacji oraz formatów danych, aby różne komponenty mogły bezproblemowo ze sobą współpracować.

Architektura monolitu a mikroserwisy

Shopify nie jest czystą architekturą mikroserwisową. To hybryda, w której monolit pełni rolę centralnego systemu, a wokół niego funkcjonuje szereg wyspecjalizowanych usług. Wraz z rozwojem platformy zaczęto wydzielać z monolitu obszary o wyraźnie odseparowanej odpowiedzialności: system płatności, system powiadomień, system analityczny czy usługę odpowiedzialną za szablony i renderowanie motywów.

Podział ten pozwolił skupić się na skalowalności wąskich gardeł. Na przykład intensywnie wykorzystywany system generowania raportów może działać jako osobna usługa, używać specyficznej bazy danych i być skalowany niezależnie od reszty. Kluczowe jest utrzymanie wyraźnych kontraktów API między monolitem a mikroserwisami oraz unikanie nadmiernej granularności, która mogłaby zwiększyć złożoność operacyjną.

Skalowanie poziome i poziom izolacji sklepów

Architektura Shopify zakłada szeroką skalowalność poziomą: wiele instancji aplikacji uruchomionych równolegle, replikowane bazy danych oraz rozproszone cache. Platforma obsługuje ponad milion sklepów, dlatego każdy sklep musi być izolowany na poziomie danych i zasobów, jednocześnie współdzieląc infrastrukturę. Ta izolacja jest realizowana głównie w warstwie aplikacyjnej i bazodanowej.

Dane konkretnego sklepu identyfikowane są poprzez unikalny identyfikator shop_id, który jest kluczem w wielu tabelach. Dzięki temu można logicznie wydzielać dane per sklep, jednocześnie trzymając je w tych samych klastrach bazodanowych. To podejście umożliwia dynamiczne balansowanie obciążenia: gdy niektóre sklepy rosną szybciej, ich dane i ruch można przenieść na osobne klastry lub instancje, nie zmieniając logiki po stronie samych merchantów.

Warstwa danych: bazy, cache, kolejki

Relacyjne bazy danych i sharding

Podstawową technologią przechowywania danych w Shopify jest relacyjna baza danych, tradycyjnie MySQL (lub kompatybilne rozwiązania). Model danych jest silnie ustrukturyzowany: produkty, warianty, kolekcje, klienci, zamówienia, płatności, ustawienia sklepu – wszystko to przechowywane jest w relacyjnych tabelach powiązanych kluczami obcymi. Taki model pozwala zachować spójność i możliwość wykonywania złożonych zapytań analitycznych.

Aby sprostać skali, Shopify stosuje sharding i partycjonowanie danych. Oznacza to, że różne sklepy lub typy danych mogą być trzymane w różnych fizycznych klastrach bazodanowych. W praktyce backend aplikacji zawiera logikę routingu, która wie, do którego shardu skierować zapytanie na podstawie identyfikatora sklepu lub innego klucza. Replikacja odczytów na read-replicas pozwala odciążyć główną bazę, a mechanizmy failover zapewniają odporność na awarie węzłów.

System cache: od danych po szablony

Przy tak dużej liczbie odwołań do tych samych informacji, cache jest jednym z najważniejszych elementów backendu. Shopify wykorzystuje rozproszone systemy cache, takie jak Memcached lub Redis, aby skrócić czas dostępu do często używanych danych: ustawień sklepu, struktur nawigacji, konfiguracji płatności, fragmentów HTML wygenerowanych z motywów czy wyników kosztownych zapytań.

Cache funkcjonuje na kilku poziomach: w warstwie aplikacyjnej, na poziomie baz danych oraz w warstwie CDN. W aplikacji kluczowe fragmenty renderowania strony sklepu są cache’owane per sklep, per język, a czasem per użytkownik. Inwalidacja cache jest precyzyjnie projektowana: gdy merchant zmienia cenę produktu lub aktywuje nowy motyw, odpowiednie wpisy w cache są usuwane, aby klienci zobaczyli aktualne informacje. To wymaga rozbudowanej logiki zdarzeniowej w backendzie.

Kolejki zadań i przetwarzanie asynchroniczne

Asynchroniczność jest fundamentem skalowalności Shopify. Zadania, których nie trzeba wykonywać w czasie rzeczywistym, trafiają do kolejek, aby nie obciążać procesu obsługi żądania HTTP. W Shopify funkcjonuje rozbudowana warstwa kolejek, oparta na technologiach takich jak Kafka, RabbitMQ lub wewnętrzne narzędzia, które pozwalają buforować miliony zadań na sekundę.

Przykładowe zadania asynchroniczne to generowanie raportów, wysyłka e‑maili potwierdzających, synchronizacja stanów magazynowych, import i eksport produktów, przetwarzanie plików (np. zdjęć), a także wywoływanie webhooków do aplikacji zewnętrznych. Backend definiuje klasy zadań, które zawierają minimalny zestaw danych (najczęściej identyfikatory), a worker pobiera te dane, następnie wykonuje logikę biznesową i zapisuje wyniki w bazie. Dzięki temu użytkownik panelu administracyjnego nie musi czekać na zakończenie ciężkich operacji.

Eventy, logowanie i obserwowalność

W tak złożonym systemie krytyczne znaczenie ma obserwowalność: zbieranie logów, metryk i zdarzeń. Shopify wykorzystuje podejście event-driven – wiele zmian w systemie generuje zdarzenia (np. order_created, product_updated), które są zapisywane w dziennikach i strumieniach zdarzeń. Te strumienie mogą być następnie wykorzystywane przez inne usługi do analizy, automatyzacji czy integracji.

Metryki zebrane z instancji aplikacyjnych, baz danych i kolejek trafiają do scentralizowanych systemów monitoringu. Dzięki temu inżynierowie mogą szybko wykrywać anomalie, jak wzrost błędów 5xx dla danej usługi, spadek wydajności zapytań SQL czy zator w kolejce zadań. Taka architektura obserwowalności jest niezbędna, by utrzymać stabilność platformy podczas kampanii z ogromnymi pikami ruchu, takich jak Black Friday.

Model sklepu: konfiguracja, motywy i API

Konfiguracja sklepu jako dane w bazie

Każdy sklep Shopify to zestaw skonfigurowanych danych przechowywanych w bazie. Ustawienia waluty, języków, stref podatkowych, metod dostawy, bramek płatności i ról użytkowników są zapisane w tabelach powiązanych z konkretnym sklepem. Sama platforma zapewnia wspólną logikę, ale to dane per sklep decydują, jak zachowa się backend w trakcie przetwarzania zamówienia.

Model danych został zaprojektowany tak, by był możliwie elastyczny: wiele ustawień przechowywanych jest w strukturach pół‑strukturalnych, takich jak pola JSON, co ułatwia wprowadzanie nowych funkcji bez łamania istniejącego schematu. Jednocześnie krytyczne dane transakcyjne, takie jak płatności czy faktury, mają silnie typowane kolumny i restrykcje, aby minimalizować ryzyko błędów i zapewnić zgodność z wymogami prawnymi w różnych krajach.

Motywy, Liquid i renderowanie widoków

Warstwa prezentacji sklepu opiera się na systemie motywów, zbudowanym wokół języka szablonów Liquid. Choć Liquid widoczny jest głównie po stronie frontendowej, backend odgrywa kluczową rolę w jego przetwarzaniu. Gdy klient wchodzi na stronę produktu, backend pobiera dane o sklepie, produkcie, wariantach, promocjach, następnie przekazuje je do silnika Liquid, który generuje finalny HTML.

Silnik renderujący musi być wyjątkowo wydajny i bezpieczny, ponieważ szablony są tworzone przez zewnętrznych developerów, a zmienne pochodzą z danych użytkownika. Backend ogranicza dostęp do wrażliwych funkcji, sandboxuje wykonywanie logiki Liquid oraz stosuje cache dla wyników renderowania. Dodatkowo, system motywów wspiera sekcje i bloki, których konfiguracja jest przechowywana w bazie, co pozwala merchantom na dynamiczne zmiany układu strony bez ingerencji w kod szablonu.

Publiczne API: REST i GraphQL

Kluczowym elementem backendu Shopify są publiczne API, umożliwiające komunikację z aplikacjami partnerskimi, integracjami i systemami zewnętrznymi. Tradycyjnie platforma oferowała REST API, jednak z czasem coraz większy nacisk położono na GraphQL API, które pozwala na bardziej precyzyjne pobieranie danych, ograniczając nadmiarowe pola oraz liczbę zapytań.

Warstwa API to osobna brama aplikacyjna w backendzie, z mechanizmami autoryzacji OAuth, limitami rate limiting oraz dokładnym wersjonowaniem. Żądania trafiają do odpowiednich kontrolerów lub resolverów GraphQL, które korzystają z tego samego modelu domenowego, co panel administracyjny. Dzięki temu aplikacje zewnętrzne mogą tworzyć, modyfikować i odczytywać większość zasobów sklepu: produkty, zamówienia, rabaty, klientów czy ustawienia wysyłki.

Bezpieczeństwo, autoryzacja i uprawnienia

Warstwa backendu implementuje rozbudowany system autoryzacji. Kupujący mają inne prawa niż użytkownicy panelu administracyjnego, a aplikacje zewnętrzne dostają dostęp tylko do tego zakresu danych, na który wyraził zgodę merchant przy instalacji. Uprawnienia są przechowywane w bazie, a każda operacja modyfikująca dane jest sprawdzana pod kątem tego, czy dany podmiot (użytkownik lub aplikacja) może ją wykonać.

Towarzyszą temu dodatkowe mechanizmy bezpieczeństwa: walidacja payloadów, ochrona przed CSRF w panelu administracyjnym, zabezpieczenia przed nadużyciami w publicznych API oraz systemy wykrywania anomalii, takie jak nietypowy wzrost liczby żądań z konkretnego tokena. Całość musi spełniać wymogi regulacyjne, w tym ochrony danych osobowych, co dodatkowo wpływa na projekt backendu i sposób przechowywania wrażliwych informacji.

Rozszerzalność: aplikacje, webhooki i integracje

Architektura aplikacji partnerskich

Jedną z największych zalet Shopify jest ekosystem aplikacji, które rozszerzają funkcje sklepów: od prostych widgetów po rozbudowane systemy ERP. Z technicznego punktu widzenia aplikacje te to osobne serwisy utrzymywane przez partnerów, komunikujące się z backendem Shopify przez API i webhooki. Sama platforma pełni rolę centralnego hubu, który wystawia dane oraz reaguje na zdarzenia.

Instalacja aplikacji odbywa się najczęściej przy użyciu OAuth. Po uzyskaniu zgody merchantów aplikacja otrzymuje token dostępu, z którym może wywoływać API. Backend Shopify obsługuje proces autoryzacji, przechowuje informacje o zainstalowanych aplikacjach oraz kontroluje zakres ich uprawnień. To pozwala rozdzielić logikę główną od logiki rozszerzeń, utrzymując stabilny rdzeń platformy, a jednocześnie dając ogromną elastyczność.

Webhooki i architektura zdarzeniowa

Webhooki są centralnym mechanizmem komunikacji event-driven z aplikacjami zewnętrznymi. Gdy w sklepie dzieje się coś istotnego – powstaje zamówienie, aktualizowany jest produkt, zmienia się stan magazynowy – backend Shopify generuje zdarzenie i wysyła HTTP POST na adres URL skonfigurowany przez aplikację. To pozwala aplikacjom reagować w czasie zbliżonym do rzeczywistego, bez konieczności ciągłego odpytywania API.

Technicznie, obsługa webhooków mocno opiera się na kolejkach zadań. Zdarzenie jest zapisywane w kolejce, następnie workery wysyłają żądania do zewnętrznych serwisów, obsługując retry w razie błędów. Backend rejestruje wyniki dostarczenia, limity oraz potencjalne nadużycia. Dodatkowo webhooki są podpisywane za pomocą sekretu współdzielonego, aby aplikacja mogła zweryfikować, że żądanie pochodzi rzeczywiście od Shopify, co jest istotne dla zachowania bezpieczeństwo.

Integracje z płatnościami i logistyką

Obsługa płatności i logistyki należy do najbardziej złożonych części backendu. Shopify musi integrować się z wieloma bramkami płatności, przewoźnikami i lokalnymi systemami, często o bardzo różnych API i wymaganiach prawnych. Aby uprościć ten chaos, platforma wprowadza warstwę abstrakcji: jednolity model płatności i przesyłek, który mapuje się na różne zewnętrzne usługi.

Po stronie backendu istnieje moduł, który odpowiada za nawiązywanie połączeń z zewnętrznymi bramkami: tworzenie transakcji, obsługę zwrotów, anulacji i sporów. Dane o płatnościach są przechowywane w znormalizowany sposób, natomiast szczegóły dostawców trzymane są w polach specyficznych dla integracji. Podobnie wygląda logistyką: backend oblicza ceny dostaw, generuje etykiety, śledzi statusy przesyłek, komunikując się z API firm kurierskich. Takie podejście pozwala sklepom korzystać z wielu dostawców, a jednocześnie zachować spójny model danych wewnątrz platformy.

Rozszerzenia interfejsu administracyjnego

Poza API danych Shopify oferuje możliwość rozszerzania panelu administracyjnego. Aplikacje mogą osadzać własne widoki wewnątrz interfejsu admina, komunikując się z backendem poprzez dedykowane endpointy. Choć część pracy odbywa się po stronie frontendu, backend musi obsłużyć logikę routingów, autoryzacji oraz renderowania osadzonych elementów.

Rozszerzenia UI często korzystają z GraphQL Admin API, które udostępnia te same zasoby co panel, ale w formie zoptymalizowanej do budowy interaktywnych narzędzi. Backend zapewnia także mechanizmy, takie jak paginacja kursorowa, filtrowanie, sortowanie oraz złożone typy relacji, by ułatwić tworzenie narzędzi raportowych i paneli analitycznych. Dzięki temu merchant może widzieć funkcje dostarczane przez aplikacje partnerskie tak, jakby były natywną częścią platformy.

< Powrót

Zapisz się do newslettera


Zadzwoń Napisz