Depot – building ASP.NET Core distributed application

Depot – building ASP.NET Core distributed application

In this article, I’d like to guide you through the development process of the simple application named Depot. It was created for my presentation about using .NET Core in practice, which is a part of .NET Core Tour. The overall journey will last 10 steps, so get ready.


 

The purpose

Application per se will be quite straightforward, yet its sole purpose is to familiarize you with some of the ASP.NET Core framework features (middleware, IoC, options etc.) as well the variety of tools such as RabbitMQ, MongoDB, Redis or Docker that can be easily used for building the software.

Depot will allow sending HTTP POST request containing {key, value} object to the API which will push it further to the RabbitMQ service bus (CreateEntry command). Then, the message shall be consumed by Entries Service and once validated, it will either produce the CreateEntryRejected event or EntryCreated (consumed by the API). For the latter scenario, the data will be stored in MongoDB database and also in the Redis distributed cache with 10 seconds timespan of sliding expiration. Eventually, we can browse the logs available in the API whether the operation has succeeded.

On top of that, the whole application can be run using Docker and docker compose tools (just browse to the scripts directory) and the repository itself is using Travis CI as the open source build server.

You can easily browse the history of the repository by using the git checkout and navigating to the particular revision by switching between available tags from 1 to 10.

1. Init

At the very beginning, we want to create 2 Web API projects using dotnet new webapi command: Depot.Api and Depot.Services.Entries. Make sure we have required references,
set the port of the second project to the 5050 then execute dotnet restore and dotnet run to see whether everything works fine.

2. Common messages

Since we want to create a distributed application, there’s a need of having some common contract in order to exchange the messages via service bus. Thus, we create new commands and events and make sure that our web services reference this particular project.

3. RabbitMQ

You can choose from multiple services buses available out there, but I really like the RabbitMQ. I’m also using RawRabbit library to handle the connection and subscribe to the messages. You can find settings of the RabbitMQ inside appsettings.json file.

4. Event and command handlers

Once we have our 2 services, common messages and service bus in place, we’re finally able to implement the first version of our distributed system. All that is needed to achieve that goal is to implement the appropriate event and command handlers. Just make sure that you do not miss setting up IoC container in the Startup class.

5. Storing entries and logs

At this point, it would be nice to actually store the data somewhere – let’s start with memory. We can create the very naive repositories and hold everything internally in the memory. Once it’s done, we can extend our command and event handlers to make use of the newly created storage.

6. Autofac, Middleware, Exceptions

It’s very easy to use a different IoC container, for example, Autofac. Also, thanks to the nature of ASP.NET Core framework and the way it’s built using so-called middleware, we can easily plug our own code into it and for example implement a global exception handler.

7. MongoDB

The time has come to actually make use of some real database. I chose MongoDB for this example – make sure you have it up and running and there’s a database named Depot available. You can change the settings by editing the appsettings.json file.

8. Redis

What about caching? For sure, we could use IMemoryCache, but we’r ere building a distributed system, right? Therefore, we need to have distributed caching as well, otherwise, your system will fail, once the first HTTP request which involves use of caching mechanism goes to server A, and the second one to server B. Since I’m a big fan of Redis, there’s a great news – it can be easily used in the ASP.NET Core applications.

9. Tests

The very final step, before we can actually deploy the application. Let’s write some tests finally. First, let’s create a new directory tests and 2 new projects Depot.Tests and Depot.Tests.EndToEnd using dotnet new xunit command. The former project will be all about typical unit tests (using xUnit, Moq and FluentAssertions) while latter will allow to execute integration tests by running the application in memory.

10. Docker, Travis, scripts

You can skip that part, as the application is already finished, however, if you want to greatly improve your deployment including automated build and testing using Travis CI and packing your source code into the Docker containers, take a look at the available Dockerfiles in the web service projects, as well as the .travis files in the root directory.

Summary

As you can see it’s neither that difficult nor time-consuming to build a pretty cool app on top of the ASP.NET Core and other fancy tools. Beware, that the code is rather simplistic and not really a production ready, yet I do hope that it will help you start with playing with distributed and (micro)services application in general.

If you would like to see more sophisticated apps built with ASP.NET Core (and NancyFX) using similar techniques, you can take a look at the Collectively which is an open source platform built by me and a friend of mine (about which I’d like to write more in a near future) or into my another open source project Warden for which I’m also building a distributed backend services.

6 Comments Depot – building ASP.NET Core distributed application

  1. Pingback: Depot – building ASP.NET Core distributed application - How to Code .NET

  2. Pingback: Dew Drop - May 15, 2017 (#2479) - Morning Dew

  3. Raphael

    Hi,

    nice article but somehow I can’t get the project to run, I’m getting the following error:

    Step 5/9 : RUN dotnet build
    —> Running in 540ef3bec4cc
    Couldn’t find ‘project.json’ in current directory

    This is weird since the project already switched to .csproj and I’m using the latest SDK and .net CORE (1.1.2).

    Any ideas?

    Reply
  4. Kevin

    Great article! I have no clue on how distributed application works but thanks to this article i am able to piece all necessary tools.
    I would like to ask on the WHY part, why Depot needs to send HTTP POST key value pair to service entry? What is the main entry point that triggers the Deport to send? Do you have an article about it? That would be helpful. Thanks in advance!

    Reply
    1. Piotr Gankiewicz

      Hi Kevin,
      Thank you! So basically the idea behind the distributed systems is that you have a main API which acts as a sort of gateway to the actual system running as the set of (micro)services.
      Once the client sends HTTP request to the API (e.g. {key,value} to the /entries endpoint), this message will be published on the service bus and consumed by some particular service that knows how to process it. Going further, such service can generate some event (another message that goes to the service bus) that can be again consumed by other services and so on.

      Reply

Leave A Comment

Your email address will not be published. Required fields are marked *