Skip to main content

abp-microservice

ABP Microservice solution template - service structure, Integration Services ([IntegrationService]), inter-service HTTP proxies, distributed events with Outbox/Inbox, Entity Cache, RabbitMQ/Redis/YARP setup. Use when working with the ABP microservice solution template or inter-service communication patterns.

소스 정보

저장소
abpframework/abp
최근 소스 활동
2026년 3월 22일 17:13
감지된 SKILL.md 언어
영어
스타
14,446
포크
3,720

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
abp-microservice
description
ABP Microservice solution template - service structure, Integration Services ([IntegrationService]), inter-service HTTP proxies, distributed events with Outbox/Inbox, Entity Cache, RabbitMQ/Redis/YARP setup. Use when working with the ABP microservice solution template or inter-service communication patterns.
# ABP Microservice Solution Template > **Docs**: https://abp.io/docs/latest/solution-templates/microservice ## Solution Structure ``` MyMicroservice/ ├── apps/ # UI applications │ ├── web/ # Web application │ ├── public-web/ # Public website │ └── auth-server/ # Authentication server (OpenIddict) ├── gateways/ # BFF pattern - one gateway per UI │ └── web-gateway/ # YARP reverse proxy ├── services/ # Microservices │ ├── administration/ # Permissions, settings, features │ ├── identity/ # Users, roles │ └── [your-services]/ # Your business services └── etc/ ├── docker/ # Docker compose for local infra └── helm/ # Kubernetes deployment ``` ## Microservice Structure (NOT Layered!) Each microservice has simplified structure - everything in one project: ``` services/ordering/ ├── OrderingService/ # Main project │ ├── Entities/ │ ├── Services/ │ ├── IntegrationServices/ # For inter-service communication │ ├── Data/ # DbContext (implements IHasEventInbox, IHasEventOutbox) │ └── OrderingServiceModule.cs ├── OrderingService.Contracts/ # Interfaces, DTOs, ETOs (shared) └── OrderingService.Tests/ ``` ## Inter-Service Communication ### 1. Integration Services (Synchronous HTTP) For synchronous calls, use **Integration Services** - NOT regular application services. #### Step 1: Provider Service - Create Integration Service ```csharp // In CatalogService.Contracts project [IntegrationService] public interface IProductIntegrationService : IApplicationService { Task<List<ProductDto>> GetProductsByIdsAsync(List<Guid> ids); } // In CatalogService project [IntegrationService] public class ProductIntegrationService : ApplicationService, IProductIntegrationService { public async Task<List<ProductDto>> GetProductsByIdsAsync(List<Guid> ids) { var products = await _productRepository.GetListAsync(p => ids.Contains(p.Id)); return ObjectMapper.Map<List<Product>, List<ProductDto>>(products); } } ``` #### Step 2: Provider Service - Expose Integration Services ```csharp // In CatalogServiceModule.cs Configure<AbpAspNetCoreMvcOptions>(options => { options.ExposeIntegrationServices = true; }); ``` #### Step 3: Consumer Service - Add Package Reference Add reference to provider's Contracts project (via ABP Studio or manually): - Right-click OrderingService → Add Package Reference → Select `CatalogService.Contracts` #### Step 4: Consumer Service - Generate Proxies ```bash # Run ABP CLI in consumer service folder abp generate-proxy -t csharp -u http://localhost:44361 -m catalog --without-contracts ``` Or use ABP Studio: Right-click service → ABP CLI → Generate Proxy → C# #### Step 5: Consumer Service - Register HTTP Client Proxies ```csharp // In OrderingServiceModule.cs [DependsOn(typeof(CatalogServiceContractsModule))] // Add module dependency public class OrderingServiceModule : AbpModule { public override void ConfigureServices(ServiceConfigurationContext context) { // Register static HTTP client proxies context.Services.AddStaticHttpClientProxies( typeof(CatalogServiceContractsModule).Assembly, "CatalogService"); } } ``` #### Step 6: Consumer Service - Configure Remote Service URL ```json // appsettings.json "RemoteServices": { "CatalogService": { "BaseUrl": "http://localhost:44361" } } ``` #### Step 7: Use Integration Service ```csharp public class OrderAppService : ApplicationService { private readonly IProductIntegrationService _productIntegrationService; public async Task<List<OrderDto>> GetListAsync() { var orders = await _orderRepository.GetListAsync(); var productIds = orders.Select(o => o.ProductId).Distinct().ToList(); // Call remote service via generated proxy var products = await _productIntegrationService.GetProductsByIdsAsync(productIds); // ... } } ``` > **Why Integration Services?** Application services are for UI - they have different authorization, validation, and optimization needs. Integration services are designed specifically for inter-service communication. **When to use:** Need immediate response, data required to complete current operation (e.g., get product details to display in order list). ### 2. Distributed Events (Asynchronous) Use RabbitMQ-based events for loose coupling. **When to use:** - Notifying other services about state changes (e.g., "order placed", "stock updated") - Operations that don't need immediate response - When services should remain independent and decoupled ```csharp // Define ETO in Contracts project [EventName("Product.StockChanged")] public class StockCountChangedEto { public Guid ProductId { get; set; } public int NewCount { get; set; } } // Publish await _distributedEventBus.PublishAsync(new StockCountChangedEto { ... }); // Subscribe in another service public class StockChangedHandler : IDistributedEventHandler<StockCountChangedEto>, ITransientDependency { public async Task HandleEventAsync(StockCountChangedEto eventData) { ... } } ``` DbContext must implement `IHasEventInbox`, `IHasEventOutbox` for Outbox/Inbox pattern. ## Performance: Entity Cache For frequently accessed data from other services, use Entity Cache: ```csharp // Register context.Services.AddEntityCache<Product, ProductDto, Guid>(); // Use - auto-invalidates on entity changes private readonly IEntityCache<ProductDto, Guid> _productCache; public async Task<ProductDto> GetProductAsync(Guid id) { return await _productCache.GetAsync(id); } ``` ## Pre-Configured Infrastructure - **RabbitMQ** - Distributed events with Outbox/Inbox - **Redis** - Distributed cache and locking - **YARP** - API Gateway - **OpenIddict** - Auth server ## Best Practices - **Choose communication wisely** - Synchronous for queries needing immediate data, asynchronous for notifications and state changes - **Use Integration Services** - Not application services for inter-service calls - **Cache remote data** - Use Entity Cache or IDistributedCache for frequently accessed data - **Share only Contracts** - Never share implementations - **Idempotent handlers** - Events may be delivered multiple times - **Database per service** - Each service owns its database
GitHub에서 보기