{"product_id":"microservices-communication-patterns","title":"Microservices Communication Patterns","description":"\u003ch3\u003eMicroservices Communication Patterns\u003c\/h3\u003e\n\u003cp\u003eMonorepo CI without path filtering is a tax on every developer. At one enterprise I consulted for, a single character change in a README triggered a 45-minute build across 12 services because their pipeline did not differentiate which package changed. Developers started pushing directly to main to skip the queue. The pipeline that was supposed to protect quality became the reason quality degraded. This template uses path-based triggering, dependency-aware builds, and parallelized service pipelines that only build what changed.\u003c\/p\u003e\n\n\u003cp\u003eBuilt from monorepo pipelines I have operated at enterprise scale with 20+ services in a single repository, this workflow handles Nx, Turborepo, Lerna, and custom workspace configurations with intelligent change detection.\u003c\/p\u003e\n\n\u003ch3\u003ePipeline Stages\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003echange-detection\u003c\/strong\u003e — \u003ccode\u003edorny\/paths-filter@v3\u003c\/code\u003e analyzes the git diff to determine which workspace packages changed. Outputs a JSON matrix of affected packages that downstream jobs consume. Dependency graph analysis ensures that if \u003ccode\u003eshared-utils\u003c\/code\u003e changes, all packages that import it are also rebuilt.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003elint-affected\u003c\/strong\u003e — Runs linters only on changed packages. \u003ccode\u003enpx nx affected --target=lint\u003c\/code\u003e or \u003ccode\u003enpx turbo run lint --filter=...[HEAD~1]\u003c\/code\u003e. Caches lint results with \u003ccode\u003eactions\/cache@v4\u003c\/code\u003e keyed on file hash.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003etest-affected\u003c\/strong\u003e — Parallel test execution across affected packages. Each package runs in its own job via \u003ccode\u003estrategy.matrix\u003c\/code\u003e populated from the change detection output. Shared service containers (database, cache) are provisioned per job.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003ebuild-affected\u003c\/strong\u003e — Builds only changed packages and their dependents. Docker images are built with package-specific Dockerfiles. Build cache shared across PRs via \u003ccode\u003eactions\/cache@v4\u003c\/code\u003e with the lockfile hash as key.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003edeploy-affected\u003c\/strong\u003e — Deploys only the services that changed. Each service has its own deployment job with environment-specific gates. Services that did not change are not redeployed, reducing blast radius.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eintegration-test\u003c\/strong\u003e — Cross-service integration tests run only when inter-service contracts change. Contract changes trigger tests for both the producer and all consumer services.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eSecurity Gates\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003ePer-package CODEOWNERS\u003c\/strong\u003e — Each workspace package has a CODEOWNERS entry. Changes to \u003ccode\u003epackages\/auth\/\u003c\/code\u003e require security team review. Changes to \u003ccode\u003epackages\/billing\/\u003c\/code\u003e require finance team review.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eDependency isolation\u003c\/strong\u003e — Package-level lockfiles prevent a dependency update in one service from affecting another. \u003ccode\u003eactions\/dependency-review-action@v4\u003c\/code\u003e scans per-package dependency changes.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eScoped deployment credentials\u003c\/strong\u003e — Each service has its own deployment IAM role. The auth service deployer cannot access the billing service's database credentials.\u003c\/li\u003e\n\u003c\/ul\u003e\n\n\u003ch3\u003eEnvironment Matrix\u003c\/h3\u003e\n\u003cp\u003eDev deploys affected services on merge to \u003ccode\u003edevelop\u003c\/code\u003e. Staging deploys on release candidate tags. Production deploys individual services with independent approval gates — the auth service can deploy without waiting for the billing service approval. Each service maintains its own semantic version.\u003c\/p\u003e\n\n\u003ch3\u003eTop 3 Failures\u003c\/h3\u003e\n\u003cul\u003e\n\u003cli\u003e\n\u003cstrong\u003eTransitive dependency change missed\u003c\/strong\u003e — Package A depends on Package B which depends on Package C. A change in C is not detected as affecting A because the dependency graph only has direct edges. Fix: use \u003ccode\u003enx affected\u003c\/code\u003e or build a dependency graph from lockfile resolution that includes transitive dependencies.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eCache poisoning from branch merges\u003c\/strong\u003e — A feature branch caches a broken build artifact, then the main branch restores that cache. Fix: use \u003ccode\u003erestore-keys\u003c\/code\u003e hierarchy: exact key first, then branch-specific prefix, then main branch fallback. Never share caches from feature branches to main.\u003c\/li\u003e\n\u003cli\u003e\n\u003cstrong\u003eGitHub Actions matrix limit\u003c\/strong\u003e — More than 256 jobs in a matrix causes the workflow to fail. Fix: batch packages into groups of 10-20 and run them as sequential waves, or split into multiple workflow files with \u003ccode\u003eworkflow_call\u003c\/code\u003e triggers.\u003c\/li\u003e\n\u003c\/ul\u003e","brand":"Citadel Cloud Management","offers":[{"title":"Default Title","offer_id":54890411950371,"sku":"CCM-DEV-020","price":42.0,"currency_code":"USD","in_stock":true}],"thumbnail_url":"\/\/cdn.shopify.com\/s\/files\/1\/0979\/8539\/7027\/files\/citadel-devops-product_a743c7a4-56a4-40b1-ad5d-f7ff917bef19.jpg?v=1775138180","url":"https:\/\/www.citadelcloudmanagement.com\/products\/microservices-communication-patterns","provider":"Citadel Cloud Management","version":"1.0","type":"link"}