<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Deep</title>
    <description>The latest articles on DEV Community by Deep (@dmehro).</description>
    <link>https://dev.to/dmehro</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F395422%2F88df3c35-9b98-45da-85bf-8e95ec0b43d7.png</url>
      <title>DEV Community: Deep</title>
      <link>https://dev.to/dmehro</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/dmehro"/>
    <language>en</language>
    <item>
      <title>Ocelot - The API Gateway</title>
      <dc:creator>Deep</dc:creator>
      <pubDate>Sun, 09 Aug 2020 18:22:26 +0000</pubDate>
      <link>https://dev.to/dmehro/ocelot-the-api-gateway-3c25</link>
      <guid>https://dev.to/dmehro/ocelot-the-api-gateway-3c25</guid>
      <description>&lt;p&gt;Full article on - &lt;a href="https://dmehro.com/gettingstartedwithocelot/"&gt;https://dmehro.com/gettingstartedwithocelot/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;What is Ocelot&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Ocelot is an Open source API GW for the ASP.net core platform . It acts as primary entry point to you back-end services . API GW are also known as backend for frontends (since front end only knows about API GW endpoints not actual services).&lt;/p&gt;

&lt;p&gt;Behind the scene Ocelot library contains numerous middleware in a pre-defined order. When request reaches Ocelot middleware it inspect and manipulate request object per need, you can also write your own custom middleware {More details in next article} to modify per your project need.&lt;/p&gt;

&lt;p&gt;I will build working application to showcase Ocelot capabilities such as &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Base setup&lt;/li&gt;
&lt;li&gt;Response aggregation&lt;/li&gt;
&lt;li&gt;Rate limiting&lt;/li&gt;
&lt;li&gt;Service discovery&lt;/li&gt;
&lt;li&gt;Custom middleware&lt;/li&gt;
&lt;li&gt;Logging&lt;/li&gt;
&lt;li&gt;Securing API GW using IdentityServer4&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;BASE SETUP&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We will be using ASP.net core 3.1 for this project. Open Visual Studio 2019 and create a new blank solution .&lt;/p&gt;

&lt;p&gt;Usually we create separate solution for Microservices but for sake of simplicity I am keeping all services in same solution . These are sample services with single endpoints to show case how request is being handled at GW and how response is being returned .&lt;/p&gt;

&lt;p&gt;Create a folder name Microservices and add two asp.net core webapi projects. You can name them Catalog &amp;amp; Customer API.&lt;/p&gt;

&lt;p&gt;Open project and add new controller CatalogController and add following code .&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace CatalogAPI.Services.Controllers
{
    [Route("api/[controller]")]
    public class CatalogController : Controller
    {
        [HttpGet]
        public IEnumerable&amp;lt;string&amp;gt; Get()
        {
            return new string[] { "Google Pixel", "Apple iPhone", "OnePlus Nord","Moto razor" };
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Repeat same step for CustomerAPI.Services project and add following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace CustomerAPI.Services.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class CustomerController : ControllerBase
    {
        [HttpGet]
        public IEnumerable&amp;lt;string&amp;gt; Get()
        {
            return new string[] { "Kylie J", "Justin B", "Cardy B", "Justin T" };
        }
    }
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;so back to original topic , lets setup Gateway . Add Empty Project under Gateway folder&lt;/p&gt;

&lt;p&gt;Install Ocelot package&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Install-Package Ocelot&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Lets configure our empty webAPI app to use as API GW. Add a json file to project which will be used for Ocelot configuration.&lt;/p&gt;

&lt;p&gt;Open Program.cs and update code as given below&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt; public class Program
    {
        public static void Main(string[] args)
        {
            CreateHostBuilder(args).Build().Run();
        }

        public static IHostBuilder CreateHostBuilder(string[] args) =&amp;gt;
              Host.CreateDefaultBuilder(args)
                 .ConfigureWebHostDefaults(webBuilder =&amp;gt;
                 {
                     webBuilder.UseStartup&amp;lt;Startup&amp;gt;();
                 })
                 .ConfigureAppConfiguration((hostingContext, config) =&amp;gt;
                 {
                     config
                     .SetBasePath(hostingContext.HostingEnvironment.ContentRootPath)
                     .AddJsonFile("OcelotConfiguration.json", optional: false, reloadOnChange: true);
                 });
    }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Gateway Program.cs&lt;/p&gt;

&lt;p&gt;Startup.cs&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;public void ConfigureServices(IServiceCollection services)
        {
            services.AddOcelot();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }

            app.UseRouting();

            app.UseEndpoints(endpoints =&amp;gt;
            {
                endpoints.MapGet("/", async context =&amp;gt;
                {
                    await context.Response.WriteAsync("Hello World!");
                });
            });

            app.UseOcelot();
        }
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;p&gt;Most important step to run your api gateway is route mapping, this is where your GW will decide which request needs to be send which downstream api. Open OcelotConfiguration.json and update following code&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight"&gt;&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  "Routes": [
    {
      "DownstreamPathTemplate": "/api/catalog",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44343
        }
      ],
      "UpstreamPathTemplate": "/catalog",
      "UpstreamHttpMethod": [ "GET" ]
    },
    {
      "DownstreamPathTemplate": "/api/customer",
      "DownstreamScheme": "https",
      "DownstreamHostAndPorts": [
        {
          "Host": "localhost",
          "Port": 44303
        }
      ],
      "UpstreamPathTemplate": "/customer",
      "UpstreamHttpMethod": [ "GET" ]
    }
  ]
}
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;Change port number per your machine/project configuration*&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;UpstreamPath -&amp;gt; Exposed endpoint on GW side and where client will send request&lt;/p&gt;

&lt;p&gt;DownstreamPath -&amp;gt; Actual backend service end point&lt;/p&gt;

&lt;p&gt;When request comes to &lt;a href="https://ocelotapigateway.xyz.com/customer"&gt;https://ocelotapigateway.xyz.com/customer&lt;/a&gt; end point then ocelot automatically maps this request to &lt;a href="https://localhost:44303/api/customer"&gt;https://localhost:44303/api/customer&lt;/a&gt;. This is all configuration based and you do not read to write single line of code for same.&lt;/p&gt;

&lt;p&gt;Before you test out make sure you have set multiple startup project in VS.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--U4PZKirX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z9c5u88jieazs8nquygr.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--U4PZKirX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/z9c5u88jieazs8nquygr.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am using postman to test these request&lt;/p&gt;

&lt;p&gt;Catalog request -&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--SLrHHUPH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/prfojii870kqfqne2t8j.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SLrHHUPH--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/prfojii870kqfqne2t8j.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Here request is being redirected to CatalogAPI.Services and we are getting response accordingly .&lt;/p&gt;

&lt;p&gt;Customer request-&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--1X-rmUbG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/24um8vjdq91otvfjzyyi.PNG" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--1X-rmUbG--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/i/24um8vjdq91otvfjzyyi.PNG" alt="Alt Text"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;With this we are done with foundational base setup for ocelot and we make more changes and make it generic in upcoming articles .&lt;/p&gt;

&lt;p&gt;Download working code from &lt;a href="https://github.com/DMehro/OcelotAPIGW"&gt;https://github.com/DMehro/OcelotAPIGW&lt;/a&gt;&lt;/p&gt;

</description>
      <category>begi</category>
    </item>
    <item>
      <title>Automate Development Environment setup via PowerShell</title>
      <dc:creator>Deep</dc:creator>
      <pubDate>Wed, 27 May 2020 17:17:52 +0000</pubDate>
      <link>https://dev.to/dmehro/automate-development-environment-setup-via-powershell-20pf</link>
      <guid>https://dev.to/dmehro/automate-development-environment-setup-via-powershell-20pf</guid>
      <description>&lt;p&gt;As a developer when we setup new Development machine we spent lot of time on finding and installing packages manually, there are times when this task has to be repeated by multiple developers , so what can we do to reduce some of pain point.&lt;/p&gt;

&lt;p&gt;One way is to still continue old school way and  manually download and then install them or you can use following powershell script automate this process.&lt;/p&gt;

&lt;p&gt;Following script I have used to setup my machine for generic C#.net Development Environment .&lt;/p&gt;

&lt;p&gt;&lt;i&gt;&lt;br&gt;
I have added commands to setup IIS as well because lot of folks in my team has to have same setting on IIS to run projects. You can ignore if you don`t need. Given script is quite straight forward , first of all you install chocolaty package and then let chocolaty handle all that manual hard work.&lt;br&gt;
&lt;i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Here is list of software which will be installed via following script
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Chocolaty&lt;/li&gt;
&lt;li&gt;GIT client&lt;/li&gt;
&lt;li&gt;IIS (all features which needs to be enabled for CP development )&lt;/li&gt;
&lt;li&gt;Webdeploy&lt;/li&gt;
&lt;li&gt;URL Rewrite&lt;/li&gt;
&lt;li&gt;Notepad++&lt;/li&gt;
&lt;li&gt;NodeJS&lt;/li&gt;
&lt;li&gt;NPM&lt;/li&gt;
&lt;li&gt;Postman&lt;/li&gt;
&lt;li&gt;Redis desktop manager&lt;/li&gt;
&lt;li&gt;Zeplin&lt;/li&gt;
&lt;li&gt;Service bus explorer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;b&gt;Before you run this script make sure to run power-shell in elevated mode .&lt;/b&gt;&lt;/p&gt;

&lt;p&gt;&lt;i&gt;There are some software which you have to manually install because either these software's are not available on chocolaty or needs user input (Microsoft Visual Studio, MS SQL Server ) &lt;/i&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;For more articles please visit my blog at &lt;a href="https://dmehro.com/"&gt;https://dmehro.com/&lt;/a&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>sideprojects</category>
      <category>dotnet</category>
      <category>csharp</category>
    </item>
    <item>
      <title>Automate GIT PULL
</title>
      <dc:creator>Deep</dc:creator>
      <pubDate>Tue, 26 May 2020 06:21:49 +0000</pubDate>
      <link>https://dev.to/dmehro/automate-git-pull-fb1</link>
      <guid>https://dev.to/dmehro/automate-git-pull-fb1</guid>
      <description>&lt;p&gt;Have you encountered a situation where you have a bunch of projects git repos and every morning you have to manually do git pull for all the project repos, so that you have the latest code in local development machine.&lt;/p&gt;

&lt;p&gt;Well I used to go to each and every repo folders and open git bash and manually pull the latest changes. Think of you have ten different projects/solutions/Microservice you work on day to day basis and you have to repeat this process every time, its tedious right, so as a developer what can we do AUTOMATE boring tedious tasks.&lt;/p&gt;

&lt;p&gt;Well you can say this level of automation won't save a lot of time for me, maybe 10 mins a day. Well you are kind of correct but think of 10*5*4 = 200, you will save 200 mins a month. Not bad huh so let's get to the actual script on how can we do that.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisite:
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Install GIT on your machine&lt;/li&gt;
&lt;li&gt;Admin privileges(though its not required but sometimes PS acts crazy if you don’t have admin permission)&lt;/li&gt;
&lt;li&gt;Group all project repo under single directory in your local box (for example I have all my project repos located under C:\Code, you can modify below script if you project scattered all across your drive )&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;&lt;i&gt;You can skip user input by hard coding 'repoLocalpath'&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Using the above script you can customize based on your needs such as find a difference before pulling remote changes or push/sync all repo.&lt;/p&gt;

</description>
      <category>git</category>
      <category>automation</category>
      <category>productivity</category>
      <category>github</category>
    </item>
  </channel>
</rss>
