Synchronous Communication between Microservices

This documentation introduces guidance for inter-service communication between two microservices using synchronous HTTP communication.

The below sample demonstrates how to make a request to ProductService from OrderService. See Add New Microservice Guide to understand how to add a new microservice project (OrderService) to your solution.

Client Credentials Flow

Add to main solution

The Client Credentials flow is a server to server flow and there is no user authentication involved in the process. Instead of the user, the client ID (service itself) as the subject is authenticated with a predefined secret. The resulting access token contains client information instead of user information.

Updating OrderService Application Contracts

In order to make ProductService application services available for OrderService application, you need to add the project reference of ProductService.Application.Contracts to OrderService.Application.Contracts and then add the module dependency attribute to the OrderServiceApplicationContractsModule class. Here are the steps:

Add csproj reference:

Open Acme.BookStore.OrderService.Application.Contracts.csproj and add the following project reference

<ProjectReference Include="..\..\..\product\src\Acme.BookStore.ProductService.Application.Contracts\Acme.BookStore.ProductService.Application.Contracts.csproj" />

Add DependsOn attribute:

Open OrderServiceApplicationContractsModule.cs class and add the following module dependency

typeof(ProductServiceApplicationContractsModule)

Add order service module dependency into the Administration Service

Now you can call Product Application Services from the OrderService application :

Add order service module dependency into the Administration Service

Build the OrderService.Application project with dotnet build command if you are having problems with resolving the new namespaces.

Since there is no implementation of IProductAppService and IProductPublicAppService in OrderService.Application, you need to configure it to make remote HTTP calls. To achieve it, you need to add the project reference of Acme.BookStore.ProductService.HttpApi.Client project to Acme.BookStore.OrderService.Application and then add the module dependency to OrderServiceApplicationModule. Here are the steps:

Add csproj reference:

Open Acme.BookStore.OrderService.Application.csproj and add the following project reference

<ProjectReference Include="..\..\..\product\src\Acme.BookStore.ProductService.HttpApi.Client\Acme.BookStore.ProductService.HttpApi.Client.csproj" />

Add DependsOn attribute:

Open OrderServiceApplicationModule.cs class and add the following module dependency

typeof(ProductServiceHttpApiClientModule)

Add order service module dependency into the Administration Service

Open the appsettings.json file in the OrderService.HttpApi.Host project and update RemoteServices section to route HTTP requests to the internal gateway. Then these requests will be redirected to the Product Service.

"RemoteServices": {
  "Default": {
    "BaseUrl": "https://localhost:44302/",
    "UseCurrentAccessToken": "false"
  }
}

appsettings.json of OrderService.HttpApi.Host project should look like below:

Add order service module dependency into the Administration Service

Configuring Auto-Discovery Endpoint

To automate requesting access token and adding it as bearer to the request headers; add Volo.Abp.Http.Client.IdentityModel NuGet package to the OrderService.HttpApi.Host project.

Add package reference:

Open Acme.BookStore.OrderService.HttpApi.Host.csproj and add the following line (update the version attribute according to your project!)

<PackageReference Include="Volo.Abp.Http.Client.IdentityModel" Version="4.4.2" />

Add DependsOn attribute:

Open OrderServiceHttpApiHostModule.cs class and add the following module dependency

typeof(AbpHttpClientIdentityModelModule)

Add order service module dependency into the Administration Service

Update IdentityClients section in appsettings.json file of the OrderService.HttpApi.Host to configure Client Credential access token request with client secret to the AuthServer end point.

  "IdentityClients": {
    "Default": {
      "GrantType": "client_credentials", 
      "ClientId": "BookStore_OrderService",
      "ClientSecret": "1q2w3e*",
      "Authority": "https://localhost:44322", 
      "Scope": "ProductService"
    }
  }

OrderService.HttpApi.Host appsettings should look like below:

Add order service module dependency into the Administration Service

IdentityServer Configuration

You can also do the same functionality explained in this step by using IdentityServer Management UI. However it is a good practice to keep IdentityServerDataSeeder up to date.

To keep IdentityServerDataSeeder updated, you need to do the following steps in the IdentityServerDataSeeder.cs class. Note that there are 2 IdentityServerDataSeeder.cs classes in the solution:

  1. Acme.BookStore.DbMigrator\IdentityServerDataSeeder.cs
  2. Acme.BookStore.IdentityService.HttpApi.Host\DbMigrations\IdentityServerDataSeeder.cs.

Add ProductService.Application.Contracts Reference for Permissions:

If you will use the DbMigrator application, you can skip this step since DbMigrator project already has this reference.

For Acme.BookStore.IdentityService.HttpApi.Host\DbMigrations\IdentityServerDataSeeder.cs add ProductService.Application.Contracts project reference as below:

<ProjectReference Include="..\..\..\product\src\Acme.BookStore.ProductService.Application.Contracts\Acme.BookStore.ProductService.Application.Contracts.csproj" />

Create New Client:

OrderService itself is a new client and you need to add the OrderService as a client under CreateClientsAsync as well. Open IdentityServerDataSeeder.cs and add the below line in

await CreateClientAsync(
    name: "BookStore_OrderService",
    scopes: commonScopes.Union(new[]
    {
        "ProductService"
    }),
    grantTypes: new[] {"client_credentials"},
    secret: "1q2w3e*".Sha256(),
    permissions: new[] {ProductServicePermissions.Products.Default}
);

OrderService.HttpApi.Host appsettings IdentityClients section data must match with the client creation data.

ProductAppService has permission authorization and will return 401 unauthorized exception when a request has been made. To overcome this issue, add the required permissions of the service you are making to.

Add order service module dependency into the Administration Service

Since OrderService will only use GetList method of the ProductAppService, we are adding ProductServicePermissions.Products.Default permission for this client.

Below you can see a screenshot of the final IdentityServerDataSeeder.cs, creating OrderService client:

IdentityServerDataSeeder changes

When the databases are seeded, BookStore_Identity.IdentityServerClients database should have a new client and BookStore_Administration.AbpPermissionGrants should be seeded with ProviderName C:

IdentityServerDataSeeder changes

Next

Contributors


Last updated: September 23, 2021 Edit this page on GitHub

Was this page helpful?

Please make a selection.

To help us improve, please share your reason for the negative feedback in the field below.

Please enter a note.

Thank you for your valuable feedback!

Please note that although we cannot respond to feedback, our team will use your comments to improve the experience.

In this document
Community Talks

Building Modular Monolith Applications Using .NET and ABP Framework

17 Oct, 17:00
Online
Watch the Event
Mastering ABP Framework Book
Mastering ABP Framework

This book will help you gain a complete understanding of the framework and modern web application development techniques.

Learn More