Mikroserwisy w Cursorze
Tworzenie mikroserwisów w Cursorze działa wtedy, gdy Agent Cursora widzi topologię serwisów i kontrakty, zanim zacznie pisać kod. Reguły projektu opisują, który serwis czym zarządza, Plan Mode ustala granicę, a kontrakt OpenAPI lub AsyncAPI powstaje i przechodzi bramkę jako pierwszy. Każdy serwis przyjmuje się na podstawie wyników poleceń: lint, diff zmian łamiących, testy kontraktowe, health check.
Ta strona jest dla programisty albo tech leada, który na co dzień buduje serwisy w Cursorze. Sytuacja jest znajoma: prosisz Agenta o serwis płatności i dostajesz schludną aplikację w Expressie, która czyta prosto z bazy zamówień, wymyśla własne nazwy zdarzeń i publikuje paymentComplete, podczas gdy dwaj konsumenci nasłuchują payment.completed. Nic nie pada aż do stagingu. Rozwiązaniem nie jest lepszy prompt, tylko kontekst, który Agent ładuje zawsze, i bramki, których nie da się obejść argumentacją.
Źródła tej strony sprawdzono 26 września 2026 r.: funkcje Cursora, z których korzysta (Rules, Plan Mode, Worktrees), pochodzą z dokumentacji Cursora zweryfikowanej 28 sierpnia 2026 r., a format plików reguł jest zgodny ze stroną reguły projektu w Cursorze. Nazwy w interfejsie mogą się różnić między wersjami Cursora 3.x, więc sprawdź je we własnej instalacji. Polecenia oasdiff, @redocly/cli, @asyncapi/cli i @pact-foundation/pact zweryfikowano 26 września 2026 r. w ich repozytoriach i w npm.
Co daje ci ten sposób pracy z mikroserwisami w Cursorze
Dział zatytułowany „Co daje ci ten sposób pracy z mikroserwisami w Cursorze”- Dwa rodzaje reguł projektu: regułę topologii ładowaną zawsze i po jednej regule na serwis, ładowanej dla jego plików, więc Agent wie, która baza i które zdarzenia należą do którego serwisu.
- Prompt dla Plan Mode, który ustala granicę serwisu, własność danych i zdarzenia, zanim zmieni się jakikolwiek plik.
- Pętlę „najpierw kontrakt”, w której plik OpenAPI lub AsyncAPI powstaje pierwszy, a CI blokuje go, gdy psuje konsumenta.
- Prompt do tworzenia szkieletu, który kopiuje konwencje serwisu, któremu już ufasz, oraz polecenia, które rozstrzygają, czy szkielet jest gotowy.
- Tabelę dowodów, która mówi recenzentowi, co sprawdzić zamiast czytania każdej wygenerowanej linii.
- Kroki naprawcze dla awarii typowych dla pracy z wieloma serwisami: wspólnych baz, cykli, rozjazdu zdarzeń i sieci w Docker Compose.
Jak pokazać Cursorowi kilka serwisów naraz?
Dział zatytułowany „Jak pokazać Cursorowi kilka serwisów naraz?”Agent przestrzega tylko granic, które widzi. Sposób, w jaki mu je pokażesz, zależy od tego, jak przechowujesz serwisy.
| Układ repozytoriów | Co Agent widzi domyślnie | Co dodać |
|---|---|---|
Monorepo (orders-service/, payments-service/, …) | Wszystkie serwisy | Jedną regułę topologii i po jednej regule na serwis ograniczonej do jego plików, żeby Agent nie pożyczał kodu przez granice |
| Polyrepo, kilka serwisów zmienianych razem | Jedno repozytorium | Multi-root workspace z serwisami, które zmieniasz, i te same reguły; konfigurację .code-workspace opisuje strona praca z wieloma repozytoriami w Cursorze |
| Polyrepo, wiele serwisów innych zespołów | Jedno repozytorium | Skopiuj opublikowane kontrakty innych zespołów do contracts/ i wskaż je w regułach zamiast otwierać ich kod |
Niezależnie od układu opisz topologię raz, w pliku .cursor/rules/service-topology.mdc:
---description: Service topology, data ownership and communication rules for every taskalwaysApply: true---# Services- api-gateway (Node.js, Express): routing, rate limiting, auth. No database.- orders-service (Node.js, Express): orders. Owns the `orders` Postgres database.- payments-service (Node.js, Express): payments and refunds. Owns the `payments` database.- users-service (Python, FastAPI): accounts and profiles. Owns the `users` database.- inventory-service (Go): stock and reservations. Owns the `inventory` database.
# Hard boundaries- Database per service. Never query another service's database; call its API or consume its events.- Contracts live in <service>/docs/openapi.yml and contracts/events/asyncapi.yml. Change the contract first.- Events are named <entity>.<past-tense-verb> (order.created, payment.completed) and carry event_id and correlation_id.- Every service exposes GET /health and GET /ready and logs JSON with correlation_id.
# Done means- `npx @redocly/cli lint <service>/docs/openapi.yml` passes- the service's own tests pass: `npm test --workspace <service>` (Node services), `pytest` in users-service, `go test ./...` in inventory-servicePotem dodaj po jednej regule na serwis, która ładuje się tylko wtedy, gdy Agent dotyka plików tego serwisu. Zapisz ją jako .cursor/rules/payments-service.mdc:
---description: Conventions for payments-serviceglobs: payments-service/**alwaysApply: false---- Stripe webhook signatures are verified with the secret in STRIPE_WEBHOOK_SECRET; never log the payload.- Consumes: order.created. Publishes: payment.initiated, payment.completed, payment.failed, payment.refunded.- Every consumer is idempotent on event_id and sends failures to the dead-letter queue.Regułę ładowaną zawsze trzymaj krótką, bo płaci za nią każda sesja. Zapisz oba pliki jako .mdc, w formacie ze strony reguły projektu w Cursorze, i nie zakładaj, że plik się ładuje tylko dlatego, że leży w .cursor/rules/: najpierw przeprowadź test kanarkowy z tej strony. Pokazuje on, czy plik w ogóle został wczytany.
Najpierw ustal granicę serwisu w Plan Mode
Dział zatytułowany „Najpierw ustal granicę serwisu w Plan Mode”Plan Mode według dokumentacji Cursora tworzy szczegółowy plan implementacji, zanim powstanie jakikolwiek kod. Tego potrzebuje decyzja o granicy: o własność danych spierasz się, kiedy nic jeszcze nie jest napisane. Otwórz nowy czat, przełącz go na Plan Mode i dołącz kod, który dziś wykonuje tę pracę.
Czytaj plan, a nie diff. Liczą się dwa pytania: czy któryś krok zostawia dwa serwisy zapisujące do tej samej tabeli i czy każdy krok ma polecenie, które dowodzi, że zadziałał. Jeśli granica wciąż budzi spór, rozmowa o architekturze należy do strony planowanie architektury w Cursorze, zanim zaczniesz budować.
Najpierw kontrakt, potem bramka w CI
Dział zatytułowany „Najpierw kontrakt, potem bramka w CI”Na kontrakcie polegają inne zespoły, więc to jego weryfikujesz najsurowiej. Wygeneruj go, zanim powstanie jakikolwiek handler, i trzymaj się nazewnictwa kontraktu, który już działa.
Zdarzenia zasługują na to samo. Jeśli trzymasz plik AsyncAPI dla exchange’y RabbitMQ albo tematów Kafki, poproś Agenta o dopisanie tam nowych komunikatów i zwaliduj plik poleceniem npx @asyncapi/cli validate contracts/events/asyncapi.yml (@asyncapi/cli 6.x wymaga Node 24 lub nowszego).
Dwa polecenia zamieniają kontrakt w bramkę, która działa przy każdym pull requeście, niezależnie od tego, czy zmienił go człowiek, czy Agent. Uruchom je w terminalu albo w CI:
# 1. The contract is well formed and follows your lint rulesnpx @redocly/cli lint payments-service/docs/openapi.yml
# 2. The change does not break an existing consumer (compare with the main branch)# (skipped for a new service, which has no base on main yet)if git cat-file -e origin/main:payments-service/docs/openapi.yml 2>/dev/null; then git show origin/main:payments-service/docs/openapi.yml > /tmp/openapi-base.yml && oasdiff breaking --fail-on ERR /tmp/openapi-base.yml payments-service/docs/openapi.ymlfioasdiff breaking --fail-on ERR kończy się kodem 1, gdy znajdzie pewną zmianę łamiącą, na przykład usunięte pole albo nowy wymagany parametr. Zainstalujesz go przez brew install oasdiff, go install github.com/oasdiff/oasdiff@latest albo obraz Dockera tufin/oasdiff. Nowy serwis nie ma jeszcze wersji bazowej na main, więc if pomija diff i do pierwszego merge’a działa tylko lint.
Kiedy kontrakt przejdzie bramkę, implementacja staje się wąskim zadaniem: „implement the handlers in payments-service so they match @payments-service/docs/openapi.yml exactly, using the validation middleware from @orders-service/src/routes/orders.ts”. Powierzchnię API wyznacza teraz kontrakt, a nie prompt.
Zbuduj szkielet nowego serwisu na wzór takiego, któremu ufasz
Dział zatytułowany „Zbuduj szkielet nowego serwisu na wzór takiego, któremu ufasz”Ogólny szablon pomija twoje konwencje. Kiedy wskażesz Agentowi serwis, który zespół już utrzymuje na produkcji, dostaje konkretne wzorce middleware’u, logowania i Dockera do skopiowania.
Port 3004 to przykład; użyj tego, który przydziela twój plik Compose. Szkielet jest gotowy, gdy te trzy polecenia przechodzą, lint Redocly przechodzi, a git diff --stat nie pokazuje żadnego pliku poza payments-service/ oprócz wpisu w Compose. To ostatnie sprawdzenie tanio wyłapuje sytuację, w której Agent „pomocnie” poprawił orders-service.
Wybieraj świadomie między wywołaniem synchronicznym a zdarzeniem
Dział zatytułowany „Wybieraj świadomie między wywołaniem synchronicznym a zdarzeniem”Agent może wywnioskować styl komunikacji ze sformułowania promptu: „Powiadom użytkownika, gdy zamówienie zostanie złożone” brzmi jak wywołanie funkcji i może się skończyć bezpośrednim wywołaniem HTTP do serwisu powiadomień. Zdecyduj o stylu sam i wpisz go do promptu.
| Wywołujący… | Użyj | Nazwij to w prompcie tak |
|---|---|---|
| Potrzebuje odpowiedzi, zanim odpowie sam (sprawdzenie stanu magazynu przy zakupie) | Synchronicznego REST lub gRPC z timeoutem i circuit breakerem | „Call inventory-service GET /v1/stock with a 2-second timeout” |
| Musi tylko wiedzieć, że praca zostanie wykonana (wysłanie potwierdzenia) | Zdarzenia | „Publish order.created; notification-service consumes it” |
| Rozpoczyna wieloetapową transakcję biznesową (zamówienie, płatność, magazyn) | Sagi zdarzeń z kompensacją | Buduj po jednym kroku; zobacz rozwój systemów rozproszonych z AI |
Przy konsumencie zdarzeń proś o zachowanie w razie awarii i o test, który go dowodzi, a nie tylko o ścieżkę szczęśliwą.
Jak zweryfikować zmianę w wielu serwisach bez czytania każdej linii?
Dział zatytułowany „Jak zweryfikować zmianę w wielu serwisach bez czytania każdej linii?”Recenzent pull requesta obejmującego kilka serwisów potrzebuje dowodów na granicach, bo to tam powstają błędy. Poniższa tabela to pakiet dowodów, którego należy wymagać; każdy wiersz to polecenie, do którego wyniku pull request prowadzi linkiem. Ideę stojącą za tym podejściem opisuje strona dowody zamiast czytania kodu.
| Dowód | Polecenie lub źródło | Co dowodzi | Kto zatwierdza |
|---|---|---|---|
| Kontrakt jest poprawny | npx @redocly/cli lint … i npx @asyncapi/cli validate … | Kontrakt ma poprawną strukturę | CI |
| Żaden konsument się nie psuje | oasdiff breaking --fail-on ERR względem origin/main | Nie ma usuniętych pól ani nowych wymaganych danych wejściowych | CI; zamierzone złamanie zatwierdza zespół-właściciel |
| Konsumenci nadal się zgadzają | Testy Pact gatewaya (npm test w api-gateway) zapisują plik paktu; build payments-service odtwarza go przez Verifier.verifyProvider() z Pacta i pada przy niezgodności | Oczekiwania gatewaya odpowiadają temu, co zwraca payments-service | CI po obu stronach |
| Serwis działa poprawnie | Własny zestaw testów serwisu, w tym powyższe testy idempotencji | Handlery i konsumenci są zgodni z kontraktem, także na ścieżkach błędów | CI |
| Działa razem z sąsiadami | docker compose up -d --wait i jedno żądanie end-to-end przez gateway | Sieć, konfiguracja i health checki współpracują | Autor, z wynikiem wklejonym do PR |
| Zmiana nie wyszła poza swój serwis | git diff --stat origin/main | Brak zmian w serwisach, których zadanie nie wymieniało | Recenzent, w 10 sekund |
Pact to jedna zależność deweloperska po obu stronach: npm install -D @pact-foundation/pact (w npm wersja 17.1.4, sprawdzono 26 września 2026 r.).
Przegląd przez człowieka skupia się wtedy na diffie kontraktu i kolejności migracji, które są krótkie i mają duże konsekwencje. Automatyczny przegląd pull requestów ponad tymi bramkami opisuje strona Bugbot, a podpięcie poleceń do pipeline’u — CI/CD z Cursorem.
Pracuj nad kilkoma serwisami równolegle
Dział zatytułowany „Pracuj nad kilkoma serwisami równolegle”Worktrees w Cursorze pozwalają Agentowi pracować w izolowanych checkoutach Gita, więc jeden agent może budować handlery payments-service, a drugi aktualizować klienta w gatewayu, każdy na własnej gałęzi. Daj każdemu agentowi jeden serwis, a wspólny kontrakt tylko do odczytu. Najpierw scal zmianę kontraktu, potem dostawcę, a na końcu konsumentów, i po każdym scaleniu ponownie przejdź tabelę dowodów. Uruchamianie i nadzorowanie takich agentów opisuje strona równoległe agenty w oknie Agents.
Debuguj żądanie, które przechodzi przez kilka serwisów
Dział zatytułowany „Debuguj żądanie, które przechodzi przez kilka serwisów”Gdy żądanie pada gdzieś między gatewayem a bazą, zbierz logi jednego correlation ID z każdego serwisu i pozwól Agentowi je zestawić. Użyj czatu w Plan Mode, żeby Agent najpierw zbadał sprawę i zaproponował rozwiązanie, zanim cokolwiek zmieni.
Brak serwisu na osi czasu, jak tutaj payments-service, sam w sobie jest ustaleniem: albo wywołanie nigdy nie nastąpiło, albo identyfikator korelacji (correlation ID) po drodze zaginął. Śledzenie i dashboardy, które robią z tego rutynę, opisuje strona monitoring z Cursorem.
Co się psuje, gdy Agent buduje mikroserwisy?
Dział zatytułowany „Co się psuje, gdy Agent buduje mikroserwisy?”Agent odpytuje bazę innego serwisu. Reguła topologii się nie załadowała albo prompt dołączał plik schematu innego serwisu. Naprawa: przeprowadź test kanarkowy ze strony o regułach projektu, usuń obcy schemat z czatu i powtórz granicę: „payments-service reads user data only through GET /v1/users/{id}”. Dodaj regułę lintu, która pada na importach między katalogami serwisów, żeby następną próbę wyłapała maszyna. W płaskiej konfiguracji ESLinta ogranicz wbudowaną regułę no-restricted-imports do jednego serwisu (ESLint 10.11.0, sprawdzono 26 września 2026 r.):
export default [ { files: ['orders-service/**'], rules: { 'no-restricted-imports': ['error', { patterns: [{ group: ['**/payments-service/**'], message: 'Call the payments API or consume its events.' }], }], }, },];Dwa serwisy wywołują się nawzajem. payments-service woła orders-service, który woła payments-service. Naprawa: w czacie w Plan Mode poproś Agenta o wypisanie z kodu wszystkich wywołań wychodzących każdego serwisu i o wskazanie cykli. Przerwij każdy cykl zdarzeniem albo przenieś wspólny krok do serwisu, który jest właścicielem danych.
Payloady zdarzeń rozjeżdżają się między wydawcą a konsumentem. Konsument przestaje działać, choć nigdzie nie pojawia się błąd, bo ktoś zmienił nazwę pola. Naprawa: niech plik AsyncAPI będzie jedyną definicją, dołączaj go do każdego promptu o zdarzeniach i dodaj do każdego konsumenta test odrzucania niezgodnego schematu z promptu powyżej.
Nowy kontener nie widzi sąsiadów. Agent napisał samodzielny Dockerfile i wpis Compose w domyślnej sieci. Naprawa: dołącz istniejący docker-compose.yml, nazwij sieć i wymagaj wyniku docker compose up -d --wait, zanim przyjmiesz szkielet.
Agent „naprawia” kontrakt, żeby pasował do jego kodu. Gdy Redocly albo oasdiff świeci na czerwono, Agent ma pokusę, by poprawić specyfikację. Naprawa: napisz w prompcie, że kontrakt jest ustalony i zmieniać wolno tylko handlery, a CI niech odrzuca każdy diff kontraktu bez zatwierdzenia przez zespół-właściciela.
Kontekst zapełnia się, zanim zacznie się właściwe zadanie. Cztery serwisy, ich schematy i plik Compose są dołączone do każdego czatu. Naprawa: dołączaj tylko serwisy wymienione w zadaniu, kontrakty innych zespołów trzymaj w contracts/, a resztę niech ładują reguły ograniczone do plików; strona zarządzanie kontekstem w Cursorze pokazuje, jak sprawdzić, co niesie sesja.
Jak tę samą pracę wykonują Claude Code i Codex
Dział zatytułowany „Jak tę samą pracę wykonują Claude Code i Codex”Pętla „najpierw kontrakt”, tabela dowodów i typowe awarie są takie same w każdym narzędziu; różni się tylko mechanizm kontekstu (CLAUDE.md w Claude Code, AGENTS.md w Codeksie). Wersję tego procesu dla wszystkich narzędzi, z sagami, propagacją śladu, migracjami schematów i odpowiednimi serwerami MCP, znajdziesz na stronie rozwój systemów rozproszonych z AI.