From aa553942da22241d082e6a9f5b31db264e65b2f2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Tue, 17 Sep 2024 12:13:28 +0300 Subject: [PATCH] Implementing Integration Services --- ...ual-studio-product-integration-service.png | Bin 0 -> 20039 bytes docs/en/tutorials/modular-crm/index.md | 2 +- docs/en/tutorials/modular-crm/part-06.md | 70 +++++++++++++++++- 3 files changed, 69 insertions(+), 3 deletions(-) create mode 100644 docs/en/tutorials/modular-crm/images/visual-studio-product-integration-service.png diff --git a/docs/en/tutorials/modular-crm/images/visual-studio-product-integration-service.png b/docs/en/tutorials/modular-crm/images/visual-studio-product-integration-service.png new file mode 100644 index 0000000000000000000000000000000000000000..d36e44121448169c54779c43e2fc9606a39997c6 GIT binary patch literal 20039 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 C=Ji?t literal 0 HcmV?d00001 diff --git a/docs/en/tutorials/modular-crm/index.md b/docs/en/tutorials/modular-crm/index.md index c98cc1c7d3..466d5d61af 100644 --- a/docs/en/tutorials/modular-crm/index.md +++ b/docs/en/tutorials/modular-crm/index.md @@ -13,7 +13,7 @@ This tutorial is organized as the following parts: * [Part 03: Building the Products module](part-03.md) * [Part 04: Creating the initial Ordering module](part-04.md) * [Part 05: Building the Ordering module](part-05.md) -* [Part 06: Integrating modules](part-06.md) +* [Part 06: Integrating the modules](part-06.md) ## Download the Source Code diff --git a/docs/en/tutorials/modular-crm/part-06.md b/docs/en/tutorials/modular-crm/part-06.md index b5ef53cdd0..f341f17fb2 100644 --- a/docs/en/tutorials/modular-crm/part-06.md +++ b/docs/en/tutorials/modular-crm/part-06.md @@ -1,4 +1,4 @@ -# Integrating Modules +# Integrating the Modules ````json //[doc-nav] @@ -10,5 +10,71 @@ } ```` -TODO +In the previous parts, we've created two modules: The Products module to store and manage products and the Orders module to accept orders. However, these modules were completely independent from each other. Only the main application brings them together to execute in the same application, but these modules don't communicate to each other. +In this part, you will learn to implement three patterns for integrating these modules: + +1. The Order module will make request to the Products module to get product information when needed. +2. The Product module will listen to events from the Orders module, so it can decrease stock count of a product when an order is placed. +3. Finally, we will execute a database query that includes product and order data together. + +Let's begin from the first one... + +## Implementing Integration Services + +Remember from the [previous part](part-05.md), the Orders page shows products' identities instead of their names: + +![abp-studio-solution-runner-orders-page](images/abp-studio-solution-runner-orders-page.png) + +That is because the Orders module has no access to the product data, so it can not perform a JOIN query to get the names of products from the `Products` table. That is a natural result of the modular design. However, we also don't want to show a product's identity on the UI, which is not a good user experience. + +As a solution to that problem, the Orders module may ask product names to the Product module using an [integration service](../../framework/api-development/integration-services.md). Integration service concept in ABP is designed for request/response style inter-module (in modular applications) and inter-microservice (in distributed systems) communication. + +### Creating a Products Integration Service + +The first step is to create an integration service in the Products module, so other modules can consume it. + +We will define an interface in the `ModularCrm.Products.Application.Contracts` package and implement it in the `ModularCrm.Products.Application` package. + +#### Defining the `IProductIntegrationService` Interface + +Open the `ModularCrm.Products` .NET solution in your IDE, find the `ModularCrm.Products.Application.Contracts` project, create an `Integration` folder inside inside of that project and finally create an interface named `IProductIntegrationService` into that folder. The final folder structure should be like that: + +![visual-studio-product-integration-service](images/visual-studio-product-integration-service.png) + +Open the `IProductIntegrationService.cs` file and replace it's content with the following code block: + +````csharp +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp; +using Volo.Abp.Application.Services; + +namespace ModularCrm.Products.Integration +{ + [IntegrationService] + public interface IProductIntegrationService : IApplicationService + { + Task> GetProductsByIdsAsync(List ids); + } +} +```` + +`IProductIntegrationService` is very similar to a typical [application service](../../framework/architecture/domain-driven-design/application-services.md). The only difference is that it has an `[IntegrationService]` attribute on top of the interface definition. In that way, ABP can recognize and behave differently for them (for example, ABP doesn't expose [integration services](../../framework/api-development/integration-services.md) as HTTP APIs by default if you've configured the *[Auto API Controllers](../../framework/api-development/auto-controllers.md)* feature) + +`IProductIntegrationService` has a single method that gets a list of product Ids and returns a list of `ProductDto` objects for these Ids. Any other module can use that method to get details of products when it only has some product Ids. This is exactly what we need in the Ordering module. + +> **Design Tip** +> +> You may think if we can use the existing application services (like `IProductAppService`) from other modules instead of creating specific integration services. Technically you can use, ABP has no restriction. However, from good design and best practice points, we don't suggest it. Because, application services are designed to be consumed specifically by the presentation layer. They will have different authorization and validation logic, they will need different DTO input and output properties, they will have different performance, optimization and caching requirements, and so on. And most importantly, all these will change by the time based on UI requirements and these changes may break your integrations later. It is best to implement specific integration APIs that is designed and optimized for that purpose. +> +> We've reused the `ProductDto` object that was actually created for `IProductAppService`. That can be reasonable from the maintenance point. But, if you think your integration service results can be different than the application service results in the future, it can be good to separate them from the first day, so you don't need to introduce breaking changes later. + +#### Creating the `ProductIntegrationService` Class + +Okay, we've defined the integration service interface. Now, we can implement it in the `ModularCrm.Products.Application` project: + + + +s