Here’s another .NET Core tutorial again but now for micro services. I’ve been recently digging on how to properly communicate services on .NET Core environment. And here is the most up-to date way using an intermediary event queue bus that I found.
Join me and let’s jump in!
Prerequisites
First of all, you must have a .NET Core 3.1 SDK (Software Development Kit) installed in your computer and I also assumed you are currently running Windows 10 or some Linux with proper environment set.
Secondly, Docker so we won’t pollute our development workstation with many things concurrently installed. I also assumed you know how to work using docker workflow.
So where do we start?
First we setup our environment to have a RabbitMQ instance. We create first a docker-compose.yml
with the following contents.
After we create the above file, open a brand new terminal and go to the location of the file we created and execute the following command below.
This command is use to start the RabbitMQ instance in background. The management panel of RabbitMQ can be access in port 15672
using your favorite browser.
Next we plan how the system would work out, the services are expected to communicate through event bus with RabbitMQ as mediator. Here is the diagram in which I imagine the flow of the system.
After we finalized the flow of our program we ought now to create an empty project folder with a solution file. First open a powershell
, cmd
or bash
terminal so we could execute the code below.
If the dotnet
command is not available, kindly check if you have properly installed .NET SDK and the environment variables are set properly. Check whether the PATH
environment variable contains the directory of the dotnet
command so you can execute it globally.
Next thing we do after initializing our solution, create a src
folder which will contain all our projects then change directory onto it.
Inside the src
folder we will create three (3) projects on which we planned to worked on. These are named TokenGatewayApi
, TokenValidationService
, and lastly TokenContracts
.
The purpose of each the projects will be unveiled later on the article. All we need to know is we created two (2) web
projects and one (1) classlib
or in other terms shared library. Then after that we need to add the projects to the solution we created.
On the two (2) web
projects we created (specifically TokenGatewayApi
and TokenValidationService
) we need to add this two (2) nuget package and also the reference to our shared library TokenContracts
.
We also need to add the basic diagnostic nuget package which is provided by Microsoft. Check Microsoft.Diagnostics
library, which we will need in service status health check.
After adding the nuget package and referencing the contracts project to our web project, we will proceed with the coding stuff. Look at Fig. 9
image as this will be our reference structure for all the file we will be creating.
First we create our messages or contracts that we will be passing on the bus. Go into the TokenContracts
project folder then create a file named BaseContract.cs
which will contain the common field interface that will be inherited by other contracts.
Then we create the contract for submitting token, the fields will just be composed of the inherited base contracts fields and the token field on which we will pass the actual token.
Then after that create a file named TokenAccepted.cs
this will be the response contracts that will be sent by TokenValidationService
in response to the SubmitToken
contract.
Also create another file which will contain the negative response of submitting token, we will name it TokenRejected.cs
. This contract will be use to contain the error happened in TokenValidationService
.
Basically, that’s all for the TokenContracts
project.
We will now proceed on modifying the TokenGatewayApi
project. First before anything replace the contents of the appsettings.json
file. This config will be also use on the TokenValidationService
, so duplicate it and place on TokenValidationService
project.
Also we need to replace the contents of the launchsettings.json
inside the Properties
folder which resides in the root directory of the project. Same in appsettings.json
we will also use this config TokenValidationService
but we need to make an adjustment on the applicationUrl
inside the profiles section. For the TokenValidationService
we will change it to http://localhost:5001
instead of port 5000
.
And now we are ready to code. Woohoo!
Still inside the TokenGatewayApi
, modify the Startup.cs
file and import the following package namespaces.
Inside the ConfigureService
method we add health check scopes and initialize/or configure the MassTransit instance.
On the code we also added if you notice the AddRequestClient
, basically that creates a specified event bus client handler that will send our messages to the event bus. This will be similar as if we are sending directly to the SendEndpoint
with properly configured endpoint URI.
Then we mapped out our controllers and health check endpoints.
If you’ve followed the instruction your code will be similar to the code below for the Startup.cs
file.
Next we will create a model, first create a folder named ViewModels
in the root of project. Then create a file named TokenSubmissionViewModel.cs
, this file will contain the URL query parameters that we will be accepting and processing in our controller methods.
Inside the Controllers
folder, create another file which will be named TokenController.cs
. This file will be our main token handler processor from outside to internal services as facade.
If you look carefully at the token controller the most important part is the validate method, on which this would handle validation of submitted token through URL query parameters.
Inside the validate method we check whether the submitted model is valid, then we pass that token to the event bus or in our case MassTransit for validation. The response will also be shown immediately as we await the result coming from token validation service, and process the proper response to frontend clients.
When the token controller is done, we move to the TokenValidationService
project and start creating a consumer. Inside the project go into the Consumers
folder if created otherwise create that folder.
Create a file named SubmitTokenConsumer.cs
, this file specifically handles or consume any message that has been pass to the event bus containing the structure of SubmitToken
contract.
The most important part of that consumer is the Consume
method, on which the contract is being processed, after processing it will create a proper response whether the token is accepted or rejected. The message will either be Sent
or Published
to make a response, in our case as we know who send the contract to us we use RespondAsync
. And another thing is we don’t use publish as there are no other consumers that will consume our response from TokenValidationService
.
After modifying the token consumer, still on TokenValidationService
modify the Startup.cs
with the corresponding changes to initialize and connect to event bus.
Here is the full overview after changing the Startup.cs
file. It similar to the change we did on TokenGateway
project with the exception of adding ConfigureEndpoints
and AddConsumer
.
Create two (2) terminals (one for TokenGateway and another one for TokenValidationService). We will run both service in parallel in order for them communicate to each other. First from terminal navigate to each respective project folder, then build and run the project using the commands below.
When everything is okay, you should see accepted response when you try accessing the validate endpoint passing a token to it sample’s below.
To test the accepted and rejected response visit the endpoints below:
- http://localhost:5000/token/validate?token=SAMPLE to receive accepted response.
- http://localhost:5000/token/validate?token=TEST to get rejected response.
Conclusion
There are many ways to achieve microservice communication and this is just one of the ways I recently found. The best part of micro services is you can build your service in any language you preferred whether its rust, csharp, golang, elixir, and etc. and it will still communicate on the event bus.
Also guys, let me know if you found any problems on this code.
You can found the complete repository here.
Follow me for similar article, tips, and tricks ❤.