{"id":2023,"date":"2023-07-17T11:20:09","date_gmt":"2023-07-17T11:20:09","guid":{"rendered":"http:\/\/waqar-arshad.com\/?p=2023"},"modified":"2023-07-17T11:20:09","modified_gmt":"2023-07-17T11:20:09","slug":"ocelot-creating-the-api-gateway-with-microservices","status":"publish","type":"post","link":"http:\/\/waqar-arshad.com\/index.php\/2023\/07\/17\/ocelot-creating-the-api-gateway-with-microservices\/","title":{"rendered":"Ocelot-Creating the API Gateway with Microservices"},"content":{"rendered":"<div class=\"pld-like-dislike-wrap pld-template-1\">\r\n    <div class=\"pld-like-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-like-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"2023\" data-trigger-type=\"like\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-up\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-like-count-wrap pld-count-wrap\">    <\/span>\r\n<\/div><div class=\"pld-dislike-wrap  pld-common-wrap\">\r\n    <a href=\"javascript:void(0)\" class=\"pld-dislike-trigger pld-like-dislike-trigger  \" title=\"\" data-post-id=\"2023\" data-trigger-type=\"dislike\" data-restriction=\"cookie\" data-already-liked=\"0\">\r\n                        <i class=\"fas fa-thumbs-down\"><\/i>\r\n                <\/a>\r\n    <span class=\"pld-dislike-count-wrap pld-count-wrap\"><\/span>\r\n<\/div><\/div>\n<p><strong>Create the Solution<\/strong><strong><\/strong><\/p>\n\n\n\n<p>For this article, we are going to create three APIs to represent our microservices. When we finish with implementation, every microservice is going to be inside the same .NET Solution. That said, we need to create an empty solution that will be the container for all of our APIs.<\/p>\n\n\n\n<p>Once the solution is ready, let\u2019s create three folders:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>API gateway<\/li>\n\n\n\n<li>Article<\/li>\n\n\n\n<li>Writer<\/li>\n<\/ul>\n\n\n\n<p><strong>Create an Article Microservice<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Now, let\u2019s create our first microservice inside the&nbsp;Article&nbsp;folder. We are going to create an&nbsp;ASP.NET Core Web API&nbsp;project and name it&nbsp;Article.Api.<\/p>\n\n\n\n<p>Secondly, let\u2019s create an&nbsp;ArticlesController&nbsp;class with three endpoints:<\/p>\n\n\n\n<p><strong>[<\/strong>HttpGet<strong>]<\/strong><\/p>\n\n\n\n<p>public IActionResult Get<strong>()<\/strong><\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; return Ok<strong>(<\/strong>_articleRepository.GetAll<strong>())<\/strong>;<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p><strong>[<\/strong>HttpGet<strong>(<\/strong>&#8220;{id}&#8221;<strong>)]<\/strong><\/p>\n\n\n\n<p>public IActionResult Get<strong>(<\/strong>int id<strong>)<\/strong><\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; var article = _articleRepository.Get<strong>(<\/strong>id<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; if <strong>(<\/strong>article is null<strong>)<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return NotFound<strong>()<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; return Ok<strong>(<\/strong>article<strong>)<\/strong>;<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p><strong>[<\/strong>HttpDelete<strong>(<\/strong>&#8220;{id}&#8221;<strong>)]<\/strong><\/p>\n\n\n\n<p>public IActionResult Delete<strong>(<\/strong>int id<strong>)<\/strong><\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; var deletedId = _articleRepository.Delete<strong>(<\/strong>id<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; if <strong>(<\/strong>deletedId == 0<strong>)<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return NotFound<strong>()<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; return NoContent<strong>()<\/strong>;<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>The first endpoint is responsible for returning every article from the database.<\/p>\n\n\n\n<p>The second is responsible for returning a single article based on the&nbsp;id&nbsp;we send as a parameter. If it doesn\u2019t exist in the database, this endpoint is going to return a&nbsp;NotFoundResult&nbsp;(HTTP status code 404).<\/p>\n\n\n\n<p>The third endpoint receives an&nbsp;id&nbsp;as a parameter and deletes this specific record from the database. In case this&nbsp;id&nbsp;doesn\u2019t exist, this endpoint returns a&nbsp;NotFound&nbsp;(HTTP status 404).<\/p>\n\n\n\n<p>Additionally, we have to create a model class:<\/p>\n\n\n\n<p>public class Article<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public int Id <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public string? Title <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public DateTime LastUpdate <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public int WriterId <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>And a repository class that represents our database and the operations:<\/p>\n\n\n\n<p>public class ArticleRepository : List<strong>&lt;<\/strong>Models.Article<strong>&gt;<\/strong>, IArticleRepository<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private readonly static List<strong>&lt;<\/strong>Models.Article<strong>&gt;<\/strong> _articles = Populate<strong>()<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; private static List<strong>&lt;<\/strong>Models.Article<strong>&gt;<\/strong> Populate<strong>()<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var result = new List<strong>&lt;<\/strong>Models.Article<strong>&gt;()<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Models.Article<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Id = 1,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Title = &#8220;First Article&#8221;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriterId = 1,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LastUpdate = DateTime.Now<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}<\/strong>,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Models.Article<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Id = 2,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Title = &#8220;Second title&#8221;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriterId = 2,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LastUpdate = DateTime.Now<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}<\/strong>,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; new Models.Article<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Id = 3,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Title = &#8220;Third title&#8221;,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WriterId = 3,<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LastUpdate = DateTime.Now<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return result;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public List<strong>&lt;<\/strong>Models.Article<strong>&gt;<\/strong> GetAll<strong>()<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return _articles;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public Models.Article? Get<strong>(<\/strong>int id<strong>)<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return _articles.FirstOrDefault<strong>(<\/strong>x =<strong>&gt;<\/strong> x.Id == id<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public int Delete<strong>(<\/strong>int id<strong>)<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var removed = _articles.SingleOrDefault<strong>(<\/strong>x =<strong>&gt;<\/strong> x.Id == id<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if <strong>(<\/strong>removed != null<strong>)<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; _articles.Remove<strong>(<\/strong>removed<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return removed?.Id ?? 0;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>To finish this initial project, let\u2019s set up our application to run at&nbsp;localhost&nbsp;port&nbsp;5001&nbsp;and don\u2019t start a&nbsp;swagger&nbsp;page:<\/p>\n\n\n\n<p>&#8220;Profile&#8221;: <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;Article.Api&#8221;: <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;commandName&#8221;: &#8220;Project&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;dotnetRunMessages&#8221;: true<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;launchBrowser&#8221;: false<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;applicationUrl&#8221;: &#8220;https:\/\/localhost:5001&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;environmentVariables&#8221;: <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;ASPNETCORE_ENVIRONMENT&#8221;: &#8220;Development&#8221;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>Now that our&nbsp;Article.Api&nbsp;is ready, we should create our second API.&nbsp;<\/p>\n\n\n\n<p><strong>Create a Writer Microservice<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Similar to the previous API, let\u2019s create an API inside the&nbsp;writer&nbsp;folder and name it&nbsp;Writer.Api. Then, we are going to add a&nbsp;WritersController&nbsp;class and three endpoints.<\/p>\n\n\n\n<p>The first and the second endpoint return every writer in the database and a single writer filtered by an&nbsp;id&nbsp;(very similar to the&nbsp;Article.Api). You can inspect that in&nbsp;<a href=\"https:\/\/github.com\/CodeMazeBlog\/CodeMazeGuides\/blob\/main\/aspnetcore-webapi\/ApiGatewayWithOcelot\/Writer.Api\/Controllers\/WritersController.cs\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>our source code<\/strong><\/a>.<\/p>\n\n\n\n<p>The third endpoint is responsible for inserting a new writer into the database:<\/p>\n\n\n\n<p><strong>[<\/strong>HttpPost<strong>]<\/strong><\/p>\n\n\n\n<p>public IActionResult Post<strong>([<\/strong>FromBody<strong>]<\/strong>Models.Writer writer<strong>)<\/strong><\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; var result = _writerRepository.Insert<strong>(<\/strong>writer<strong>)<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; return Created<strong>(<\/strong>$&#8221;\/get\/{result.Id}&#8221;, result<strong>)<\/strong>;<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>Of course, we have to create the&nbsp;Writer&nbsp;class:<\/p>\n\n\n\n<p>public class Writer<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public int Id <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; public string? Name <strong>{<\/strong> get; set; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>Also, have to create a new Repository (WriterRepository) representing the database. You can find&nbsp;<a href=\"https:\/\/github.com\/CodeMazeBlog\/CodeMazeGuides\/tree\/main\/aspnetcore-webapi\/ApiGatewayWithOcelot\/Writer.Api\/Repositories\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>the implementation here<\/strong><\/a>.<\/p>\n\n\n\n<p>In this class, we create a list of&nbsp;writers&nbsp;and the methods responsible for filtering and inserting writers.<\/p>\n\n\n\n<p>To finalize, we should modify the&nbsp;launchSettings.json&nbsp;file to set up this microservice to start at port 5002 and to don\u2019t use the swagger page (similar to the article API).<\/p>\n\n\n\n<p><strong>Creating the API Gateway<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Finally, we are going to implement our API Gateway using Ocelot.<\/p>\n\n\n\n<p>First, let\u2019s create a new&nbsp;ASP.NET Core Web API&nbsp;project inside the&nbsp;ApiGateway&nbsp;folder and name it&nbsp;OcelotApiGateway.<\/p>\n\n\n\n<p>Now, let\u2019s install the&nbsp;Ocelot&nbsp;package into our project:<\/p>\n\n\n\n<p>Install-Package Ocelot<\/p>\n\n\n\n<p>Then, let\u2019s change the&nbsp;LaunchSettings.json&nbsp;file to run at port&nbsp;5003.<\/p>\n\n\n\n<p>Once it is done, we are ready to create our configuration file.<\/p>\n\n\n\n<p><strong>Create the ocelot.json File&nbsp;<\/strong><strong><\/strong><\/p>\n\n\n\n<p>We need to create, at the root of our project, a new JSON file, and name it&nbsp;ocelot.json.<\/p>\n\n\n\n<p>To start, let\u2019s modify the file and define two keys,&nbsp;GlobalConfiguration&nbsp;and&nbsp;Routes&nbsp;(an array of objects):<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp; &#8220;GlobalConfiguration&#8221;: <strong>{},<\/strong><\/p>\n\n\n\n<p>&nbsp; &#8220;Routes&#8221;: <strong>[<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{}<\/strong><\/p>\n\n\n\n<p>&nbsp; <strong>]<\/strong>&nbsp;<\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>As a continuation, let\u2019s configure our project to use the Ocelot.<\/p>\n\n\n\n<p>Inside the&nbsp;Program&nbsp;class, in the builder section, let\u2019s add the&nbsp;ocelot.json&nbsp;file and the Ocelot service to our application:<\/p>\n\n\n\n<p>builder.Configuration.AddJsonFile<strong>(<\/strong>&#8220;ocelot.json&#8221;, optional: false, reloadOnChange: true<strong>)<\/strong>;<\/p>\n\n\n\n<p>builder.Services.AddOcelot<strong>(<\/strong>builder.Configuration<strong>)<\/strong><\/p>\n\n\n\n<p><strong>Ocelot.json File Configuration<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Inside the&nbsp;GlobalConfiguration&nbsp;key, we are going to set up our API Gateway host and port:<\/p>\n\n\n\n<p>&#8220;GlobalConfiguration&#8221;: <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;BaseUrl&#8221;: &#8220;https:\/\/localhost:5003&#8221;<\/p>\n\n\n\n<p>&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p>Next, inside the&nbsp;Routes&nbsp;key, let\u2019s configure the endpoints of our application with some nested keys:<\/p>\n\n\n\n<p>&#8220;Routes&#8221;: <strong>[{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamPathTemplate&#8221;: &#8220;\/gateway\/writers&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamHttpMethod&#8221;: <strong>[<\/strong>&#8220;Get&#8221;<strong>],<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamPathTemplate&#8221;: &#8220;\/api\/writers&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamScheme&#8221;: &#8220;https&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamHostAndPorts&#8221;: <strong>[{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Host&#8221;: &#8220;localhost&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Port&#8221;: 5002<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}]<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>},<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamPathTemplate&#8221;: &#8220;\/gateway\/writers\/{id}&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamHttpMethod&#8221;: <strong>[<\/strong>&#8220;Get&#8221;<strong>],<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamPathTemplate&#8221;: &#8220;\/api\/writers\/{id}&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamScheme&#8221;: &#8220;https&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamHostAndPorts&#8221;: <strong>[{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Host&#8221;: &#8220;localhost&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Port&#8221;: 5002<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}]<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>},<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamPathTemplate&#8221;: &#8220;\/gateway\/writers&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamHttpMethod&#8221;: <strong>[<\/strong>&#8220;Post&#8221;<strong>],<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamPathTemplate&#8221;: &#8220;\/api\/writers&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamScheme&#8221;: &#8220;https&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamHostAndPorts&#8221;: <strong>[{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Host&#8221;: &#8220;localhost&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Port&#8221;: 5002<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}]<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>},<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamPathTemplate&#8221;: &#8220;\/gateway\/articles&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamHttpMethod&#8221;: <strong>[<\/strong>&#8220;Get&#8221;<strong>],<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamPathTemplate&#8221;: &#8220;\/api\/articles&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamScheme&#8221;: &#8220;https&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamHostAndPorts&#8221;: <strong>[{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Host&#8221;: &#8220;localhost&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Port&#8221;: 5001<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}]<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>},<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamPathTemplate&#8221;: &#8220;\/gateway\/articles\/{id}&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;UpstreamHttpMethod&#8221;: <strong>[<\/strong>&#8220;Get&#8221;<strong>,<\/strong> &#8220;Delete&#8221;<strong>],<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamPathTemplate&#8221;: &#8220;\/api\/articles\/{id}&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamScheme&#8221;: &#8220;https&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;DownstreamHostAndPorts&#8221;: <strong>[{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Host&#8221;: &#8220;localhost&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Port&#8221;: 5001<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <strong>}]<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>]<\/strong><\/p>\n\n\n\n<p>The&nbsp;<strong>UpstreamPathTemplate<\/strong>&nbsp;defines the URL of the API Gateway that receives the requests and then redirects to the microservice API (DownstreamPathTemplate).<\/p>\n\n\n\n<p>The&nbsp;<strong>UpstreamHttpMethod<\/strong>&nbsp;defines the HTTP Methods (Get, Put, Post, Patch \u2026) that the API Gateway uses to distinguish between the requests.<\/p>\n\n\n\n<p>The&nbsp;<strong>DownstreamPathTemplate<\/strong>&nbsp;represents the endpoint at the microservice that is going to receive the request. In other words, it takes the request of the UpstreamPathTemplate and redirects to the DownstreamPathTemplate.<\/p>\n\n\n\n<p>The&nbsp;<strong>DownstreamScheme<\/strong>&nbsp;represents the protocol to communicate with the microservice.&nbsp;<\/p>\n\n\n\n<p>The&nbsp;<strong>DownstreamHostAndPorts<\/strong>&nbsp;defines the URL and the port from the microservices that are going to receive the requests.<\/p>\n\n\n\n<p><strong>Running the Application<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Once all our APIs are inside the same .NET Solution, we need to configure the Visual Studio to run every API simultaneously.<\/p>\n\n\n\n<p>To do that, let\u2019s right-click on the solution and then, click&nbsp;Properties:<\/p>\n\n\n\n\n\n<p><a href=\"https:\/\/code-maze.com\/wp-content\/uploads\/2022\/05\/Solution-Property.png\"><strong><\/strong><\/a><\/p>\n\n\n\n<p>With the property window open, in the left menu, we choose the option&nbsp;Startup Project. Then, in the right section, we choose the&nbsp;Multiple startup projects&nbsp;option and change all microservices&nbsp;Action&nbsp;to&nbsp;Start.&nbsp;<\/p>\n\n\n\n<p>Notice that, when we run the application, it is going to start all microservices we have in our solution.<\/p>\n\n\n\n<p><strong>Requesting Endpoints<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Now, instead of requesting our microservices endpoints directly, we are going to gather all requests in the Ocelot API Gateway&nbsp;UpstreamPathTemplate.&nbsp;<\/p>\n\n\n\n<p>To request every article from our database, let\u2019s make a request to:<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/localhost:5003\/gateway\/articles\n<\/div><\/figure>\n\n\n\n<p>To get a specific writer from the database, let\u2019s make a request to:<\/p>\n\n\n\n<figure class=\"wp-block-embed\"><div class=\"wp-block-embed__wrapper\">\nhttps:\/\/localhost:5003\/gateway\/writers\/1\n<\/div><\/figure>\n\n\n\n<p>The&nbsp;localhost:5003&nbsp;means that we are making requests to our Ocelot API Gateway. The&nbsp;\/gateway\/article&nbsp;and the&nbsp;\/gateway\/writers\/1, represents the&nbsp;UpstreamPathTemplate&nbsp;we previously configured in our&nbsp;ocelot.json&nbsp;file from our API Gateway.<\/p>\n\n\n\n<p><strong>Ocelot Features<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Ocelot has a bunch of features. In this article, we are going to implement two of them.<\/p>\n\n\n\n<p><strong>Using Rate Limiting<\/strong><strong><\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/code-maze.com\/aspnetcore-web-api-rate-limiting\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>Rate limiting<\/strong><\/a>&nbsp;<strong>is the process of restricting the number of requests for a resource within a specific time window.<\/strong><\/p>\n\n\n\n<p>In this scenario, we are going to limit the number of requests for the&nbsp;\/api\/articles&nbsp;endpoint:<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;UpstreamPathTemplate&#8221;: &#8220;\/gateway\/articles&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;UpstreamHttpMethod&#8221;: <strong>[<\/strong>&#8220;Get&#8221;<strong>],<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;DownstreamPathTemplate&#8221;: &#8220;\/api\/articles&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;DownstreamScheme&#8221;: &#8220;https&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;DownstreamHostAndPorts&#8221;: <strong>[{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Host&#8221;: &#8220;localhost&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Port&#8221;: 5001<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}],<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;RateLimitOptions&#8221;: <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;EnableRateLimiting&#8221;: true<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Period&#8221;: &#8220;10s&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;PeriodTimespan&#8221;: 10<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Limit&#8221;: 3<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>In our current configuration, we need to add a new&nbsp;RateLimitOptions&nbsp;object with some properties.<\/p>\n\n\n\n<p>First, we need to set the&nbsp;EnableRateLimiting&nbsp;property value to&nbsp;true.<\/p>\n\n\n\n<p>The second property we need to set up is the&nbsp;Period. This property defines the specific time window that this rate limit is acting on.<\/p>\n\n\n\n<p>The&nbsp;PeriodTimespan&nbsp;defines the number of seconds we need to wait to request this endpoint after we got the maximum number of requests within the&nbsp;Period. In this case, let\u2019s set its value to 10 seconds.<\/p>\n\n\n\n<p>The last property is the&nbsp;Limit. It defines the maximum number of requests within 10 seconds (Period&nbsp;property).<\/p>\n\n\n\n<p>Once we request this&nbsp;UpstreamPathTemplate&nbsp;(\/gateway\/articles) more than 3 times within 10 seconds, the API Gateway is going to return a&nbsp;Too Many Request&nbsp;(HTTP status 429).<\/p>\n\n\n\n<p><strong>Using Cache With Ocelot<\/strong><strong><\/strong><\/p>\n\n\n\n<p>Caching is another easy-to-implement Ocelot feature.<\/p>\n\n\n\n<p>First, we need to install the ocelot caching package:<\/p>\n\n\n\n<p>Install-Package Ocelot.Cache.CacheManager<\/p>\n\n\n\n<p>The second step is to add the cache manager to our services inside the&nbsp;Program&nbsp;class:<\/p>\n\n\n\n<p>builder.Services.AddOcelot<strong>(<\/strong>builder.Configuration<strong>)<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; .AddCacheManager<strong>(<\/strong>x =<strong>&gt;<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; x.WithDictionaryHandle<strong>()<\/strong>;<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>})<\/strong>;<\/p>\n\n\n\n<p>Then, we need to add the&nbsp;FileCacheOptions&nbsp;object to the endpoint we want to cache and set the&nbsp;TtlSeconds:<\/p>\n\n\n\n<p><strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp; &#8220;UpstreamPathTemplate&#8221;: &#8220;\/gateway\/writers&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp; &#8220;UpstreamHttpMethod&#8221;: <strong>[<\/strong> &#8220;Get&#8221; <strong>],<\/strong><\/p>\n\n\n\n<p>&nbsp; &#8220;DownstreamPathTemplate&#8221;: &#8220;\/api\/writers&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp; &#8220;DownstreamScheme&#8221;: &#8220;https&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp; &#8220;DownstreamHostAndPorts&#8221;: <strong>[<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Host&#8221;: &#8220;localhost&#8221;<strong>,<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8220;Port&#8221;: 5002<\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p>&nbsp; <strong>],<\/strong><\/p>\n\n\n\n<p>&nbsp; &#8220;FileCacheOptions&#8221;: <strong>{<\/strong><\/p>\n\n\n\n<p>&nbsp;&nbsp;&nbsp; &#8220;TtlSeconds&#8221;: 10<\/p>\n\n\n\n<p>&nbsp; <strong>}<\/strong><\/p>\n\n\n\n<p><strong>}<\/strong><\/p>\n\n\n\n<p>The&nbsp;TtlSeconds&nbsp;(Time-to-live in seconds) means the time that the Ocelot is going to cache the data. After that time, Ocelot is going to discard the cache.<\/p>\n\n\n\n<p>While the data is in the cache, the API Gateway doesn\u2019t make an HTTP request to our microservice.&nbsp; That means we are saving resources from our microservice. Once the cache expires, the API Gateway requests the microservice once more and saves the data in the cache again.<\/p>\n\n\n\n<p>As we said, Ocelot has a lot more features, and to learn more about it you can read the&nbsp;<a href=\"https:\/\/ocelot.readthedocs.io\/en\/latest\/\" target=\"_blank\" rel=\"noreferrer noopener\"><strong>documentation<\/strong><\/a>.<\/p>\n\n\n\n<p><strong>Conclusion<\/strong><strong><\/strong><\/p>\n\n\n\n<p>In this article, we have talked about what Ocelot is and how to implement an API Gateway using Ocelot. We have implemented two APIs and learned how to implement and configure the Ocelot to redirect requests to these microservices.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Create the Solution For this article, we are going to create three APIs to represent our microservices. When we finish with implementation, every microservice is going to be inside the same .NET Solution. That said, we need to create an empty solution that will be the container for all of our APIs. Once the solution [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"","footer-sml-layout":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[39],"tags":[],"class_list":["post-2023","post","type-post","status-publish","format-standard","hentry","category-api-gateway"],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"admin","author_link":"http:\/\/waqar-arshad.com\/index.php\/author\/waqar_29_1\/"},"uagb_comment_info":27,"uagb_excerpt":"Create the Solution For this article, we are going to create three APIs to represent our microservices. When we finish with implementation, every microservice is going to be inside the same .NET Solution. That said, we need to create an empty solution that will be the container for all of our APIs. Once the solution&hellip;","_links":{"self":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/2023","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/comments?post=2023"}],"version-history":[{"count":1,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/2023\/revisions"}],"predecessor-version":[{"id":2027,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/posts\/2023\/revisions\/2027"}],"wp:attachment":[{"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/media?parent=2023"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/categories?post=2023"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/waqar-arshad.com\/index.php\/wp-json\/wp\/v2\/tags?post=2023"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}