In this section, we are going to see how to build API gateway using Ocelot. Ocelot is one of the most popular libraries for API Gateways used in conjunction with Microservices project. In the last article, we have seen how to handle the traffic using envoy gateway. In this case, we are going to extend the same example using Ocelot and see how it works underneath. As we know already, Gateways are very useful and it helps with following features seamlessly.
- Rate Limiting
- Load Balancing
- Circuit Breaker
- Request Aggregation
Below I have pasted glimpse of the solution.
Download Code:- https://github.com/rahulsahay19/ocelot-gateway
Here, Ocelot will act as gateway for Movies and Series API. Also, we will be handling cross cutting concerns like authentication, rate limiting etc at gateway level itself. Here is the high-level diagram explaining the same.
Having said that, let’s get started. First we will see, key ingredients to make an app as gateway app. We first need to install, Ocelot gateway. Afterwards, we need to setup startup file like shown below.
That’s it. One liner enables and applies it as well. Then, we need to add, ocelot.json file like shown below.
Let’s understand this template. This template is pretty simple, it starts with Routes, wherein you will be providing different routes both upstream and downstream. Upstream, means whatever traffic coming from the internet and downstream means whatever going to the system. Then we have scheme, it can be https or http. Afterwards we have host and port. Host in this case is localhost and port where application is listening. We also have Upstream HTTP method. Here, in this case, we have Get, but we can have any HTTP verb here. One thing to understand here, that routes is an array which is basically a collection of different routes. Last but not the least, we have GlobalConfiguration, which takes the base url of the gateway.
Also, my program.cs file looks like
Here, you can see that, I am picking ocelot.json file based on ASPNETCORE_ENVIRONMENT. Then, just adding logging here, so that I can see how requests are getting processed here. Having said that, when I go ahead run all the projects, it will come like. Make sure to run as Multiple Startup Projects. Now, if I go to the route https://localhost:5006/movies, it will come like And, when I will do https://localhost:5006/series, it will come like Also, I have enabled API Version and swagger for individual API projects. Therefore, you can see the APIs from swagger endpoint as well at https://localhost:5001/swagger/index.html and https://localhost:5003/swagger/index.html. and, I am not going into the details of this swagger implementation. That you can see in the code itself. Till this point, we have seen how gateway is redirecting the traffic. Now, let’s go ahead and handle the authentication here. For that, I am going to introduce one new section in the ocelot.json file and it will now look like
Here, I have just added AuthenticationOptions to both the routes and said that provider key is Bearer. Also, for the sake of demonstration, I have allowed all the scopes. You can restrict this further. Now, in-order to incorporate bearer token here, I have also added “Microsoft.AspNetCore.Authentication.JwtBearer” package in the gateway project and now my startup file looks like
Regarding JWT Bearer concept, I have already discussed in the last post. Also, I have added the secret key in my appsettings.json like shown below. Having said that, now when I go ahead and try to hit the URL, it will give 401 error. At this moment, what we can do, we can generate JWT token and attach the same in header while making call. Therefore, in order to create the token we will call authenticate method from postman like shown below. Having said that, when we click on send, we should get token as response. Now, we need to attach this token while making call to the movies endpoint like shown below. With token in place, when I click on send button, it will return the result like shown below. One more thing to note here. Just to ease the testing process, I have integrated REST Client an extension for VSCode for making API calls. Best part is here, I can preserve my inputs and utilize later as well. You can find this extension in Code gallery. After sending this input I can get the response like And then, I can take this token and pass the same in header in the subsequent API calls like shown below. This is just an example for testing. Its not mandatory. And it will return output like Pretty simple. Now, let’s go ahead and see how to do rate limiting. Rate limiting is the one of the required feature to restrict DDos (Distributed Denial of service). Its also very easy to enable the same from ocelot.json like shown below.
Here, I have given 5s time interval which means if I try hitting the same URL multiple time in that 5s window, I will get API quota limit exceeded error like shown below.
Next, let’s see how to enable Response Caching in ocelot. For this, we need to add additional NuGet package say Ocelot.Cache.CacheManager. Once added, then I need to enable as shown below
and configuration looks like
With this change in place, API will return same data for 20 seconds duration. After that it will change the response otherwise will return from in memory dictionary which we added in the code. Now, let’s see how to handle circuit breaker concept with ocelot. In Microservices world, there are bunch of services, which are talking to each other either by HTTP calls or via message brokers. Either way there will be chances that any of these services will become unavailable for any reason. Hence, it becomes extremely important to make services resilient and circuit breaker pattern is a way to achieve that. Circuit breaker is basically a concept where in you try calling a service for pre-configured time and if it fails, then you just open the circuit which means further calls won’t go to service. In order to implement the same, I will be using Ocelot.Provider.Polly from NuGet.
After that, I just need add polly with ocelot like shown below.
Once this is done, I will modify my controller code to fail that purposely to simulate the change
After this I need to add little configuration in Ocelot to implement this. Its known as QOS aka Quality of Service.
It takes three options.
- ExceptionsAllowedBeforeBreaking:- This value must greater than 0. It means that the circuit breaker will break after a certain number of exceptions occur.
- DurationOfBreak:- This value specifies how long the circuit breaker will stay open after it is tripped.
- TimeoutValue :- This value specifies that a request will automatically be timed out if it takes more than this value.
Having said that, now when I go ahead and try running the movies service, it will break with below exception.
With this I would like to wrap this article. I will keep on enhancing this project with more best practices around Microservices. One more point to note here, since this is Microservices project, you need to be good at docker as all the services will be containerized and then orchestration will happen. If you like to learn docker from scratch, I have recorded a comprehensive course on “Docker for .Net and Angular Developers” on udemy platform. This is 5.5 hrs course with complete demo.
Download Code:- https://github.com/rahulsahay19/ocelot-gateway