<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/"
    xmlns:atom="http://www.w3.org/2005/Atom" xmlns:media="http://search.yahoo.com/mrss/" version="2.0">
    <channel>
        
        <title>
            <![CDATA[ Middleware - freeCodeCamp.org ]]>
        </title>
        <description>
            <![CDATA[ Browse thousands of programming tutorials written by experts. Learn Web Development, Data Science, DevOps, Security, and get developer career advice. ]]>
        </description>
        <link>https://www.freecodecamp.org/news/</link>
        <image>
            <url>https://cdn.freecodecamp.org/universal/favicons/favicon.png</url>
            <title>
                <![CDATA[ Middleware - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sat, 27 Jun 2026 11:23:54 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/tag/middleware/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ What is Middleware? Definition and Example Use Cases ]]>
                </title>
                <description>
                    <![CDATA[ By Yiğit Kemal Erinç Middleware is a commonly used term in web development. It can mean many things depending on the context, which makes the term a bit confusing. In this article, we will start by defining the term and then continue with a discussio... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/what-is-middleware-with-example-use-cases/</link>
                <guid isPermaLink="false">66d45e4fbc9760a197a1039a</guid>
                
                    <category>
                        <![CDATA[ Application Security ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Middleware ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Mon, 31 Aug 2020 17:10:48 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2020/08/edgar-chaparro-DPo30-zDO5g-unsplash.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Yiğit Kemal Erinç</p>
<p>Middleware is a commonly used term in web development. It can mean many things depending on the context, which makes the term a bit confusing.</p>
<p>In this article, we will start by defining the term and then continue with a discussion on some different use cases. </p>
<p>After reading this article, you will be able to get more involved in technical and architectural conversations with your peers. You will also be more capable in terms of designing secure and reliable APIs and data flows.</p>
<h2 id="heading-definition-of-middleware">Definition of Middleware</h2>
<p>Middleware is a software that acts as an intermediary between two applications or services to facilitate their communication. </p>
<p>You can think of it as a proxy that can act as a data accumulator, translator, or just a proxy that forwards requests.</p>
<h2 id="heading-common-use-cases-for-middleware">Common Use Cases for Middleware</h2>
<h3 id="heading-1-translator">1) Translator</h3>
<p>There are many data-interchange formats, such as JSON, XML and Protobuf. Even though we mostly use JSON nowadays, each of them have their own use cases. </p>
<p>For example, Protobuffers are known to be more performant than JSON but they are not human readable. So you might be using Protobuffers for internal services and you might use JSON when the API consumer is a browser. </p>
<p>You can also check out my <a target="_blank" href="https://erinc.io/2020/08/09/what-is-protobuf-and-when-to-use-it/">article</a> on Protobuffers if you are interested in learning more about them.</p>
<p>Now let's say we need these two services, which speak different protocols, to communicate with each other.</p>
<p>We can create a middleware that makes use of a data conversion library and translates the requests to a format that the receiving service can understand.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/0.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h3 id="heading-2-accumulating-duplicating-data">2) Accumulating-Duplicating Data</h3>
<p>Microservice architecture is a popular architectural pattern that is commonly applied in modern applications. </p>
<p>If you're not familiar with microservices architecture, it basically means that your application consists of many small apps or services that are independent of each other and operate together by communicating over the internet.</p>
<p>For example, in an e-commerce project, you may have a microservice for storing and retrieving products, another microservice for searching, and another one for authentication and storing users. And each has its own database.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/1-10.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Now let's say that we want to implement our search in a way that it searches for both users and products. </p>
<p>If this was a monolithic application we could simply write a query to search each table and join the results. But now our databases are running on different servers. </p>
<p>This problem has multiple solutions, and we will look at two of them.</p>
<h4 id="heading-accumulating-data">Accumulating Data</h4>
<p>We can use a middleware to send requests to both servers, and ask them to search their databases for usernames and products that match the searched word. </p>
<p>Then we can accumulate the results from both servers and return them to the client. Note that the number of requests increases linearly as we increase the number of servers (and we also need to merge those data).</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/4-3.png" alt="Image" width="600" height="400" loading="lazy"></p>
<h4 id="heading-duplicating-data">Duplicating Data</h4>
<p>We can store duplicate data in our search server so it can directly search them instead of requesting from product and user servers. This is less efficient in terms of memory but much faster – and speed is critical for search services.</p>
<p>If the tables we need are Product and User, we can create those tables in our search server as well. Then, whenever we save a new user to our user database, we will also save one copy in the search server.</p>
<p>We have a couple options: first, we can call the Search server's save methods from the User and Product servers' save methods to duplicate the data. Or we can create a middleware for saving, which will do the following: </p>
<ul>
<li>Whenever a save request arrives, call Product/User server's save and Search server's save. </li>
<li>If the first save fails, do not call the save on other one (this keeps the databases consistent).</li>
</ul>
<p>Let's look at the design diagrams without and with a middleware. First, this is how it looks without:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/2-7.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Looks ugly, right? Indeed, it is ugly and it will make your code more complicated and tightly coupled.</p>
<p>Here is the same solution with a middleware:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/08/3-6.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>In this scenario, the client-side just calls the middleware to save a product or user and it handles the rest. </p>
<p>There is no code related to duplicating the data either in the Product or User servers or the client-side. Middleware takes care of that stuff.</p>
<h3 id="heading-3-api-security">3) API Security</h3>
<p>For any front end client-side code, we can view the outgoing requests, either in the browser's console or via a proxy. </p>
<p>We talked about a User server that takes care of the login and sign-up. If our front end code directly sends the requests to that server, the address of our authentication server is exposed. After learning the IP address of our backend, attackers can use tools to find our endpoints and scan our server for vulnerabilities.</p>
<p>We can use middleware as a proxy to conceal our authentication server's URL. Our front end communicates with middleware and it will forward the request to the authentication server, and return the response back. </p>
<p>This approach also allows us to block all requests to our authentication server, except the requests from our middleware's URL. This makes our authentication server much more secure. </p>
<p>This was not possible previously, because our front end was communicating with the authentication server. Since the front end means the client's computer, we couldn't apply an IP filter.</p>
<h3 id="heading-4-exposing-public-apis">4) Exposing Public APIs</h3>
<p>In the previous part, we learned that middlewares can be used to restrict access to our API. </p>
<p>Now let's look at the other side of the equation: what if we want to give restricted access to our API? Maybe we are a Software Engineer at a bank and the bank is planning a hackathon. We would need to provide access to our API, right? </p>
<p>But since we are a bank, of course we can't provide access to the whole API and allow every operation. This means that we need to find a way to provide restricted access.</p>
<p>For this purpose, we can implement a middleware that only exposes some of the endpoints and redirects the requests to our actual API. Then we provide this API to the developers at the hackathon.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this post, we started off by defining what middleware is and tried to categorize the use-cases of middlewares in web development. </p>
<p>Keep in mind that this is not a complete list of use-cases, but still I hope it was helpful to you. </p>
<p>Thank you for reading. If you liked the article, I invite you to check out my <a target="_blank" href="https://erinc.io/">blog</a>. You can also subscribe to my mailing list to get notified when I publish a new post :)</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Todo API in Deno and Oak ]]>
                </title>
                <description>
                    <![CDATA[ By Adeel Imran I am a JavaScript/Node developer who secretly likes (actually, loves and adores) Deno. I have been a huge fan of Deno ever since it was announced and I've been wanting to play with it.  This tutorial focuses on creating a set of REST A... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-a-todo-api-in-deno-written-by-a-guy-coming-from-node/</link>
                <guid isPermaLink="false">66d45d5d51f567b42d9f8413</guid>
                
                    <category>
                        <![CDATA[ 2020 ]]>
                    </category>
                
                    <category>
                        <![CDATA[ code ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Deno ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Middleware ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Fri, 29 May 2020 11:33:00 +0000</pubDate>
                <media:content url="https://cdn-media-2.freecodecamp.org/w1280/5f9c9ab6740569d1a4ca273d.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Adeel Imran</p>
<p>I am a JavaScript/Node developer who secretly likes (actually, loves and adores) Deno. I have been a huge fan of Deno ever since it was announced and I've been wanting to play with it. </p>
<p>This tutorial focuses on creating a set of REST APIs for a Todo application. Keep in mind that I did not touch on the database here – I will cover that <a target="_blank" href="https://www.freecodecamp.org/news/how-to-use-mysql-in-deno-oak/">in another article</a>.</p>
<p>At any point if you feel lost or want to check a reference, here is the entire source code of this tutorial: <strong><a target="_blank" href="https://github.com/adeelibr/deno-playground/tree/master/chapter_1:oak">Chapter 1: Oak</a>.</strong></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2021/04/image-171.png" alt="Image" width="600" height="400" loading="lazy">
_Photo by [Unsplash](https://unsplash.com/@bernardtheclerk?utm_source=ghost&amp;utm_medium=referral&amp;utm_campaign=api-credit"&gt;Bernard de Clerk / &lt;a href="https://unsplash.com/?utm_source=ghost&amp;utm_medium=referral&amp;utm<em>campaign=api-credit)</em></p>
<h3 id="heading-things-we-will-cover">Things we will cover</h3>
<ul>
<li>Create a basic server</li>
<li>Create 5 APIs (routes/controller)</li>
<li>Create a middleware to log API requests as they are made in the console</li>
<li>Create a not found (404) middleware when the user tries to access an unknown API</li>
</ul>
<h3 id="heading-what-will-we-need">What will we need</h3>
<ul>
<li>An installed version of Deno (don't worry I'll walk you through it)</li>
<li>A tiny bit of knowledge of Typescript</li>
<li>Would be awesome if you have worked with Node/Express before (don't worry if you haven't — this tutorial is very basic)</li>
</ul>
<h2 id="heading-lets-get-started">Let's get started</h2>
<p>First things first let's install Deno. I am on a Mac computer so I am using brew. Simply open your terminal and type:</p>
<pre><code>$ brew install deno
</code></pre><p>But if you are using a different operating system, just head over to <a target="_blank" href="https://deno.land/#installation"><strong>deno.land installation</strong></a><strong>.</strong> They have a lot of ways you can easily install it on your machine.</p>
<p>Once you have it installed, close the terminal, open a new one, and type:</p>
<pre><code>$ deno --version
</code></pre><p>It should output something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-28-at-22.34.24.png" alt="Image" width="600" height="400" loading="lazy">
<em>running command "deno --version" to see which version of deno is installed</em></p>
<p>Awesome! With this we are almost done with 10% of this tutorial. </p>
<p>Let's move ahead and create the backend API for our Todo app.</p>
<h3 id="heading-setting-up-the-project">Setting up the project</h3>
<p>Before you move on, here is the entire source code of this tutorial: <strong><a target="_blank" href="https://github.com/adeelibr/deno-playground/tree/master/chapter_1:oak">Chapter 1: Oak</a>.</strong></p>
<p>Let's get started:</p>
<ul>
<li>Create a new folder and call it <strong>chapter_1:oak</strong> (but you can call it anything you want)</li>
<li>Once you create a folder simply <code>cd</code> into your new project. Create a file called <strong>server.ts</strong> and write the following code in it:</li>
</ul>
<pre><code class="lang-server.ts">import { Application } from "https://deno.land/x/oak/mod.ts";

const app = new Application();
const port: number = 8080;

console.log('running on port ', port);
await app.listen({ port });
</code></pre>
<p>Let's run this file. Open your terminal and in your project root folder type:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>I will talk about what the <code>--allow-net</code> flag does, but for now just bear with me ?.</p>
<p>You should get something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-28-at-22.33.28.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>What we have done so far is create a server which listens on port 8080. It doesn't do much right now besides being able to run on port 8080.</p>
<p>If you have used JavaScript before, one thing you might have noticed is we are importing packages in a different way. We have to do something like:</p>
<pre><code><span class="hljs-keyword">import</span> { Application } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/x/oak/mod.ts"</span>;
</code></pre><p>When you run <code>deno run ---allow-net &lt;file_name&gt;</code> in your terminal, Deno will look at all your imports and install them locally in your machine if they are not there. </p>
<p>The first time you run this it will go to this URL <code>https://deno.land/x/oak/mod.ts</code> and install the <code>oak</code> package. Oak is basically a Deno framework for writing API's. It will put it somewhere locally in your cache.</p>
<p>In the next line we do this:</p>
<pre><code><span class="hljs-keyword">const</span> app = <span class="hljs-keyword">new</span> Application();
</code></pre><p>This creates a new instance of our application, and it will be the basis of everything as you progress further in this tutorial. You can add routes to the application instance, attach middleware like API logging, write a 404 not found, and so on.</p>
<p>Then we write:</p>
<pre><code><span class="hljs-keyword">const</span> port: number = <span class="hljs-number">8080</span>;
<span class="hljs-comment">// const port = 8080; // =&gt; can also be written like this</span>
</code></pre><p>Both are the same and do the same thing. The only difference is writing <code>const port: number = 8080</code> tells Typescript that <code>port</code> variable is of type number.</p>
<p>If you were to write <code>const port: number = "8080"</code>, this would throw an error in your terminal, as port is of type <code>number</code>. But we are trying to assign it a <code>string</code> of value "8080". </p>
<p>If you want to learn more about different types of types (pun intended) check out this very easy and basic guide on <a target="_blank" href="https://www.typescriptlang.org/docs/handbook/basic-types.html"><strong>Basic types by Typescript</strong></a>. Just give it a quick glance for 2-3 minutes and head back here.</p>
<p>And in the end we have:</p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'running on port '</span>, port);
<span class="hljs-keyword">await</span> app.listen({ port });
</code></pre><p>We simply console here the port number and tell Deno to listen to the port, which is 8080.</p>
<p>It isn't doing much right now. Let's make it do something basic like show a <em>JSON</em> message in your browser when you go to http:localhost:8080<em>.</em></p>
<p>Add the following to your <strong>server.ts</strong> file:</p>
<pre><code class="lang-server.ts">import { Application, Router } from "https://deno.land/x/oak/mod.ts";

const app = new Application();
const port: number = 8080;

const router = new Router();
router.get("/", ({ response }: { response: any }) =&gt; {
  response.body = {
    message: "hello world",
  };
});
app.use(router.routes());
app.use(router.allowedMethods());

console.log('running on port ', port);
await app.listen({ port });
</code></pre>
<p>The new thing added here is that we are now also importing <code>Router</code> along with <code>Application</code> from <code>oak</code> in line 1.</p>
<p>Next what we do is:</p>
<pre><code><span class="hljs-keyword">const</span> router = <span class="hljs-keyword">new</span> Router();
router.get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">{ response }: { response: any }</span>) =&gt;</span> {
  response.body = {
    <span class="hljs-attr">message</span>: <span class="hljs-string">"hello world"</span>,
  };
});
app.use(router.routes());
app.use(router.allowedMethods());
</code></pre><p>We create a new router instance by doing <code>const router = new Router()</code> and then we create a new route called <code>/</code> which is of type <code>get</code>.</p>
<p>Let's break this down:</p>
<pre><code>router.get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">{ response }: { response: any }</span>) =&gt;</span> {
  response.body = {
    <span class="hljs-attr">message</span>: <span class="hljs-string">"hello world"</span>,
  };
});
</code></pre><p><code>router.get</code> takes 2 parameters. The first is route which we have set to <code>/</code> and the second is function. The function itself takes an argument which is an object. What I am doing here is <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment">destructuring</a> the object and getting only <code>response</code>.</p>
<p>Next I am type checking <code>response</code> similar to how I did <code>const port: number = 8080;</code>. All I am doing is <code>{ response }: { response: any }</code> which is telling TypeScript here that the <code>response</code> which I have destructed can be of type <code>any</code>.</p>
<p><code>any</code> helps you avoid type checking in TypeScript. You can read more about it <a target="_blank" href="https://www.typescriptlang.org/docs/handbook/basic-types.html#any">here</a>.</p>
<p>Then all I am doing is taking that <code>response</code> object and setting <code>response.body.message = "hello world";</code>.</p>
<pre><code>response.body = {
  <span class="hljs-attr">message</span>: <span class="hljs-string">"hello world"</span>,
};
</code></pre><p>Last but not least, we just add these two lines:</p>
<pre><code>app.use(router.routes());
app.use(router.allowedMethods());
</code></pre><p>This tells Deno to include all routes by our router (currently we only have one) and the next line tells Deno to allow all methods for this route(s) like <code>GET, POST, PUT, DELETE</code>.</p>
<p>And now we are done. ✅ Let's run this and see what we have:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>The <code>---allow-net</code> property tells Deno that this app gives the user the permission to access its content via the port opened up.</p>
<p>Now open your favorite browser and go to <code>http://localhost:8080</code>. You will see something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-28-at-23.11.08.png" alt="Image" width="600" height="400" loading="lazy">
<em>Result of running localhost:8080 on your browser</em></p>
<p>Honestly the hardest part is done. Conceptually we are 60% there.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/images.jpeg" alt="Image" width="600" height="400" loading="lazy">
<em>Master Yoda approves</em></p>
<p>Awesome.</p>
<p>Just one last thing before we start with our Todo API. Let's replace:</p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">'running on port '</span>, port);
<span class="hljs-keyword">await</span> app.listen({ port });
</code></pre><p>with:</p>
<pre><code class="lang-server.ts">app.addEventListener("listen", ({ secure, hostname, port }) =&gt; {
  const protocol = secure ? "https://" : "http://";
  const url = `${protocol}${hostname ?? "localhost"}:${port}`;
  console.log(`Listening on: ${port}`);
});

await app.listen({ port });
</code></pre>
<p>The code we had before was not very accurate, because we were simply console logging a message and then waiting for the app to start listening on a port.</p>
<p>With the later version we wait for the app to start listening on <code>port</code> and we can listen by adding an event listener to our <code>app</code> instance with the following: <code>app_.addEventListener_("listen", ({ secure, hostname, port }) =&gt; {}</code>. </p>
<p>The first param is the event we want to listen for (which is <code>listen</code> ?) and then the second param is an object which we destruct to <code>{ secure, hostname, port }</code>. Secure is a boolean, hostname is a string, and port is a number.</p>
<p>Now when we start our app, it will only console the message once the app actually starts listening on port.</p>
<p>We can just go one step ahead and make it more colorful. Let's add a new module to the top of the file in <code>server.ts</code>:</p>
<pre><code><span class="hljs-keyword">import</span> { green, yellow } <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/std@0.53.0/fmt/colors.ts"</span>;
</code></pre><p>And then inside our event listener method we can replace:</p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Listening on: <span class="hljs-subst">${port}</span>`</span>);
</code></pre><p>with:</p>
<pre><code><span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${yellow(<span class="hljs-string">"Listening on:"</span>)}</span> <span class="hljs-subst">${green(url)}</span>`</span>);
</code></pre><p>Now when we do:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>it will show this in our console:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-28-at-23.34.29.png" alt="Image" width="600" height="400" loading="lazy">
<em>Cool, now we have a colourful console.</em></p>
<p>If you get stuck anywhere you can simply go to the source code of this tutorial <a target="_blank" href="https://github.com/adeelibr/deno-playground/tree/master/chapter_1:oak"><strong>here</strong></a>.</p>
<p>Let's create our Todo API's routes next.</p>
<ul>
<li>Create a new folder in your root folder called <code>routes</code> and inside that folder create a file called <code>todo.ts</code></li>
<li>At the same time in your root folder create a new folder called <code>controllers</code> and inside that folder create a file called <code>todo.ts</code></li>
</ul>
<p>Let's first touch the <code>controllers/todo.ts</code> file:</p>
<pre><code class="lang-controllers/todo.ts">export default {
  getAllTodos: () =&gt; {},
  createTodo: async () =&gt; {},
  getTodoById: () =&gt; {},
  updateTodoById: async () =&gt; {},
  deleteTodoById: () =&gt; {},
};
</code></pre>
<p>We are simply exporting an object here with some named functions which are empty (for now).</p>
<p>Next go inside your file <code>routes/todo.ts</code> and type this:</p>
<pre><code class="lang-routes/todo.ts">import { Router } from "https://deno.land/x/oak/mod.ts";

const router = new Router();
// controller
import todoController from "../controllers/todo.ts";

router
  .get("/todos", todoController.getAllTodos)
  .post("/todos", todoController.createTodo)
  .get("/todos/:id", todoController.getTodoById)
  .put("/todos/:id", todoController.updateTodoById)
  .delete("/todos/:id", todoController.deleteTodoById);

export default router;
</code></pre>
<p>This might look familiar to people who have worked with Node and Express. </p>
<p>All we are doing here is importing <code>Route</code> from <code>oak</code> and then setting up a new instance of Router by doing <code>const router = new Router();</code>.</p>
<p>Next we import our controllers by doing:</p>
<pre><code><span class="hljs-keyword">import</span> todoController <span class="hljs-keyword">from</span> <span class="hljs-string">"../controllers/todo.ts"</span>;
</code></pre><p>One thing to notice here in Deno is every time we import a local file in our Deno project we have to provide the file extension. This is because Deno doesn't know whether the file being imported is a <code>.js</code> or <code>.ts</code> file.</p>
<p>Moving forward we simply set all of our routes according to REST conventions:</p>
<pre><code class="lang-routes/todo.ts">router
  .get("/todos", todoController.getAllTodos)
  .post("/todos", todoController.createTodo)
  .get("/todos/:id", todoController.getTodoById)
  .put("/todos/:id", todoController.updateTodoById)
  .delete("/todos/:id", todoController.deleteTodoById);
</code></pre>
<p>The code above will translate to our API definition like this:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>TYPE</td><td>API ROUTE</td><td></td><td></td><td></td></tr>
</thead>
<tbody>
<tr>
<td>GET</td><td>/todos</td><td></td><td></td><td></td></tr>
<tr>
<td>GET</td><td>/todos/:id</td><td></td><td></td><td></td></tr>
<tr>
<td>POST</td><td>/todos</td><td></td><td></td><td></td></tr>
<tr>
<td>PUT</td><td>/todos/:id</td><td></td><td></td><td></td></tr>
<tr>
<td>DELETE</td><td>/todos/:id</td><td></td><td></td></tr>
</tbody>
</table>
</div><p>and at the end we simply export our router by doing <code>_export_ _default_ router;</code>.</p>
<p>We are done with creating our routes structure. (Now, each route doesn't do anything because our controllers are empty, we will add functionality to them in a bit.)</p>
<p>Here's the last piece of the puzzle before we start adding functionality to each route controller. We need to attach this <code>router</code> to our <code>app</code> instance.</p>
<p>So head over to <code>server.ts</code> file and do the following:</p>
<ul>
<li>Add this to the very top:</li>
</ul>
<pre><code><span class="hljs-comment">// routes</span>
<span class="hljs-keyword">import</span> todoRouter <span class="hljs-keyword">from</span> <span class="hljs-string">"./routes/todo.ts"</span>;
</code></pre><ul>
<li>Remove this piece of code:</li>
</ul>
<pre><code><span class="hljs-keyword">const</span> router = <span class="hljs-keyword">new</span> Router();
router.get(<span class="hljs-string">"/"</span>, <span class="hljs-function">(<span class="hljs-params">{ response }: { response: any }</span>) =&gt;</span> {
  response.body = {
    <span class="hljs-attr">message</span>: <span class="hljs-string">"hello world"</span>,
  };
});
app.use(router.routes());
app.use(router.allowedMethods());
</code></pre><ul>
<li>Replace it with:</li>
</ul>
<pre><code>app.use(todoRouter.routes());
app.use(todoRouter.allowedMethods());
</code></pre><p>This is it – we are done. Your <code>server.ts</code> file should look like this now:</p>
<pre><code class="lang-server.ts">import { Application } from "https://deno.land/x/oak/mod.ts";
import { green, yellow } from "https://deno.land/std@0.53.0/fmt/colors.ts";

// routes
import todoRouter from "./routes/todo.ts";

const app = new Application();
const port: number = 8080;

app.use(todoRouter.routes());
app.use(todoRouter.allowedMethods());

app.addEventListener("listen", ({ secure, hostname, port }) =&gt; {
  const protocol = secure ? "https://" : "http://";
  const url = `${protocol}${hostname ?? "localhost"}:${port}`;
  console.log(
    `${yellow("Listening on:")} ${green(url)}`,
  );
});

await app.listen({ port });
</code></pre>
<p>If you got stuck anywhere while following this, simple head over to the source code of this tutorial <strong><a target="_blank" href="https://github.com/adeelibr/deno-playground/tree/master/chapter_1:oak">here</a>.</strong></p>
<p>Awesome, now we have our routes with no functionality at the moment. So let's add that functionality in our controllers.</p>
<p>But before we do that we have to create 2 more (tiny) files.</p>
<ul>
<li>In your root folder create a new folder called <code>interfaces</code> and inside that folder create a file called <code>Todo.ts</code> (make sure Todo is capitalized, as it won't give any syntax error here if you don't – these are just conventions.)</li>
<li>Also in your root folder create a new folder called <code>stubs</code> and inside that folder create a file called <code>todos.ts</code></li>
</ul>
<p>Let's create an interface in our <code>interfaces/Todo.ts</code> file. Simply add the following code:</p>
<pre><code class="lang-interfaces/todo.ts">export default interface Todo {
  id: string,
  todo: string,
  isCompleted: boolean,
}
</code></pre>
<p>What is an interface?</p>
<p>One of the core things in TypeScript is checking the shape that value has. Similar to <code>const port: number = 8080</code> or <code>{ response }: { response : any }</code>, we can also type check an object. </p>
<p>In TypeScript, interfaces fill the role of naming these types, and are a powerful way of <strong>defining contracts within</strong> your code as well as <strong>contracts with code outside</strong> of your project. </p>
<p>Here is an another example of an interface:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// We have an interface</span>
<span class="hljs-keyword">interface</span> LabeledValue {
  label: <span class="hljs-built_in">string</span>;
}

<span class="hljs-comment">// the arg passed to this function labeledObj is </span>
<span class="hljs-comment">// of type LabeledValue (interface)</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printLabel</span>(<span class="hljs-params">labeledObj: LabeledValue</span>) </span>{
  <span class="hljs-built_in">console</span>.log(labeledObj.label);
}

<span class="hljs-keyword">let</span> myObj = {label: <span class="hljs-string">"Size 10 Object"</span>};
printLabel(myObj);
</code></pre>
<p>Hopefully this example gives you a bit more insight into interfaces. If you want more detailed information check out the docs on <a target="_blank" href="https://www.typescriptlang.org/docs/handbook/interfaces.html">interfaces here</a>.</p>
<p>Now that our interface is ready, let's mock some data (since we don't have an actual database for this tutorial).</p>
<p>Let's create a mock list of todos first in our <code>stubs/todos.ts</code> file. Simply add the following:</p>
<pre><code class="lang-stubs/todos.ts">import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interface
import Todo from '../interfaces/Todo.ts';

let todos: Todo[] = [
  {
    id: v4.generate(),
    todo: 'walk dog',
    isCompleted: true,
  },
  {
    id: v4.generate(),
    todo: 'eat food',
    isCompleted: false,
  },
];

export default todos;
</code></pre>
<ul>
<li>Two things to notice here: we add a new package and use its method <code>v4</code> by doing <code>_import_ { v4 } _from_ "https://deno.land/std/uuid/mod.ts";</code>. Then every time we use <code>v4.generate()</code> it will create a new random string of <code>id</code>.  </li>
</ul>
<p>The <code>id</code> can not be a <code>number</code>, only a <code>string</code> because in our <code>Todo</code> interface we have defined <code>id</code> as a string.</p>
<ul>
<li>The other thing to focus on here is <code>let _todos_: _Todo_[]</code> = []. This basically tells Deno that our todos array is of type <code>Todo</code> (which is awesome, our compiler now <em>automagically</em> knows that each item in our array can only have <code>{**id**: _string_, **todo**: _string_ &amp; **isCompleted**: _boolean_}</code> it will not accept any other key).</li>
</ul>
<p>If you want to learn more about <code>interfaces</code> in TypeScript check out this amazing detailed documentation on interfaces <strong><a target="_blank" href="https://www.typescriptlang.org/docs/handbook/interfaces.html">here</a>.</strong></p>
<p>Awesome. If you have come this far, give yourself a pat on the back. Good job everyone.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/download-1.jpeg" alt="Image" width="600" height="400" loading="lazy">
<em>The Rock appreciates all the effort you are doing</em></p>
<h2 id="heading-lets-work-on-our-controllers">Let's work on our controllers</h2>
<p>In your file <code>controllers/todo.ts</code>:</p>
<pre><code class="lang-controllers/todos.ts">export default {
  getAllTodos: () =&gt; {},
  createTodo: async () =&gt; {},
  getTodoById: () =&gt; {},
  updateTodoById: async () =&gt; {},
  deleteTodoById: () =&gt; {},
};
</code></pre>
<p>Let's write the controller for <code>getAllTodos</code>:</p>
<pre><code class="lang-controllers/todos.ts">// stubs
import todos from "../stubs/todos.ts";

export default {
  /**
   * @description Get all todos
   * @route GET /todos
   */
  getAllTodos: ({ response }: { response: any }) =&gt; {
    response.status = 200;
    response.body = {
      success: true,
      data: todos,
    };
  },
  createTodo: async () =&gt; {},
  getTodoById: () =&gt; {},
  updateTodoById: async () =&gt; {},
  deleteTodoById: () =&gt; {},
};
</code></pre>
<p>Before I begin on this block of code, let me explain that every controller has an argument – let's call it <code>context</code>.</p>
<p>So we can deconstruct <code>_getAllTodos_: (context) =&gt; {}</code> to:</p>
<pre><code>getAllTodos: <span class="hljs-function">(<span class="hljs-params">{ request, response, params }</span>) =&gt;</span> {}
</code></pre><p>And since we are using <code>typescript</code> we have to add type checking to all of these variables:</p>
<pre><code>getAllTodos: <span class="hljs-function">(<span class="hljs-params">
  { request, response, params }: { 
    request: any, 
    response: any, 
    params: { id: string },
  },
</span>) =&gt;</span> {}
</code></pre><p>So we have added type checks to all 3 <code>{ request, response, params }</code></p>
<ul>
<li><code>request</code> is what the user sends us (information like headers and JSON data)</li>
<li><code>response</code> is what we send the user back in the API response</li>
<li><code>params</code> is what we define in our router routes, that is:</li>
</ul>
<pre><code class="lang-ts">.get(<span class="hljs-string">"/todos/:id"</span>, <span class="hljs-function">(<span class="hljs-params">{ params}: { params: { id: <span class="hljs-built_in">string</span> } }</span>) =&gt;</span> {})
</code></pre>
<p>So the <code>:id</code> in <code>/todos/:id</code> is the param. Params are a way to get information from the URL. In this example we know that we have an <code>/:id</code> . So when the user tries to access this API (that is, <code>/todos/756</code>) <strong>756</strong> is basically the <strong>:id</strong> param. Since it is in the URL we know it is of type <code>string</code>.</p>
<p>Now that we have our basic definitions defined let's get back to our todos controller:</p>
<pre><code class="lang-controllers/todos.ts">// stubs
import todos from "../stubs/todos.ts";

export default {
  /**
   * @description Get all todos
   * @route GET /todos
   */
  getAllTodos: ({ response }: { response: any }) =&gt; {
    response.status = 200;
    response.body = {
      success: true,
      data: todos,
    };
  },
  createTodo: async () =&gt; {},
  getTodoById: () =&gt; {},
  updateTodoById: async () =&gt; {},
  deleteTodoById: () =&gt; {},
};
</code></pre>
<p>For <code>getAllTodos</code> we only need <code>response</code> . If you remember, <code>response</code> is what is needed to send data back to the user.</p>
<p>For people coming from a Node and Express background, one big thing that is different here is that we don't need to <code>return</code> the response object. Deno does this for us automatically.</p>
<p>All we have to do is set <code>response.status</code> which in this case is <code>200</code>.</p>
<p>More on response statuses <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Status"><strong>here</strong></a><strong>.</strong></p>
<p>The other thing we set is the <code>response.body</code> which in this case is an object:</p>
<pre><code class="lang-ts">{
  success: <span class="hljs-literal">true</span>,
  data: todos
}
</code></pre>
<p>I will go ahead and run my server:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><blockquote>
<p><strong>Revision:</strong> The <code>---allow-net</code> property tells Deno that this app gives the user permission to access its content via the port opened up.</p>
</blockquote>
<p>Once your server is running, you can access the <code>GET /todos</code> API. I am using <code>postman</code> which is a Google Chrome extension and can be downloaded <a target="_blank" href="https://chrome.google.com/webstore/detail/postman/fhbjgbiflinjbdggehcddcbncdddomop//%40">here</a>.</p>
<p>You can use whatever rest client you like. I like using <code>postman</code> because I think it is very easy.</p>
<p>In Postman, open up a new tab. Set the request to type <code>GET</code> and in the <code>URL</code> bar type <code>http://localhost:8080/todos</code>. Hit <code>Send</code> and this is what you see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-02.01.11.png" alt="Image" width="600" height="400" loading="lazy">
<em>GET /todos API response</em></p>
<p>Cool! 1 API done, 4 more to go. ??</p>
<p>If you feel stuck anywhere just have sneak peak at the source code directly <a target="_blank" href="https://github.com/adeelibr/deno-playground/tree/master/chapter_1:oak"><strong>here</strong></a><strong>.</strong></p>
<p>Let's move on to our next controller:</p>
<pre><code class="lang-controllers/todos.ts">import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interfaces
import Todo from "../interfaces/Todo.ts";
// stubs
import todos from "../stubs/todos.ts";

export default {
  getAllTodos: () =&gt; {},
  /**
   * @description Add a new todo
   * @route POST /todos
   */
  createTodo: async (
    { request, response }: { request: any; response: any },
  ) =&gt; {
    const body = await request.body();
    if (!request.hasBody) {
      response.status = 400;
      response.body = {
        success: false,
        message: "No data provided",
      };
      return;
    }

    // if everything is fine then perform
    // operation and return todos with the
    // new data added.
    let newTodo: Todo = {
      id: v4.generate(),
      todo: body.value.todo,
      isCompleted: false,
    };
    let data = [...todos, newTodo];
    response.body = {
      success: true,
      data,
    };
  },
  getTodoById: () =&gt; {},
  updateTodoById: async () =&gt; {},
  deleteTodoById: () =&gt; {},
};
</code></pre>
<p>Since we are going to be adding a new Todo to our list, I have imported 2 modules in the controller file.</p>
<ul>
<li><code>import { v4 } from</code><a target="_blank" href="https://deno.land/std/uuid/mod.ts">https://deno.land/std/uuid/mod.ts</a><code>;</code> this will be used to create a new unique one for the todo being created</li>
<li><code>import Todo from "../interfaces/Todo.ts";</code> this will be used to ensure that the new todo that is being created follows the same structure.</li>
</ul>
<p>Our <code>createTodo</code> controller is <code>async</code> meaning there are some promises used inside the controller. </p>
<p>Let's break it into smaller parts:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">const</span> body = <span class="hljs-keyword">await</span> request.body();
<span class="hljs-keyword">if</span> (!request.hasBody) {
      response.status = <span class="hljs-number">400</span>;
      response.body = {
        success: <span class="hljs-literal">false</span>,
        message: <span class="hljs-string">"No data provided"</span>,
      };
      <span class="hljs-keyword">return</span>;
}
</code></pre>
<p>First we get the content of the JSON body that the user has sent us. Then we use <code>oak's</code> built-in method called <code>request.hasBody</code> to check if the user has even sent any content. If not then we can do <code>if (!request_._hasBody) {}</code> inside this <code>if</code> block. </p>
<p>We set the status to <code>400</code> (400 means that the user did something they were not suppose to do) and the body is set to <code>{success: false, message: "no data provided }</code>. Then we simple add <code>return;</code> to ensure that no further code below is executed.</p>
<p>Next we do this:</p>
<pre><code><span class="hljs-comment">// if everything is fine then perform</span>
<span class="hljs-comment">// operation and return todos with the</span>
<span class="hljs-comment">// new data added.</span>
<span class="hljs-keyword">let</span> newTodo: Todo = {
  <span class="hljs-attr">id</span>: v4.generate(),
  <span class="hljs-attr">todo</span>: body.value.todo,
  <span class="hljs-attr">isCompleted</span>: <span class="hljs-literal">false</span>,
};
<span class="hljs-keyword">let</span> data = [...todos, newTodo];
response.body = {
  <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
  data,
};
</code></pre><p>We create a new todo by doing this:</p>
<pre><code><span class="hljs-keyword">let</span> newTodo: Todo = {
  <span class="hljs-attr">id</span>: v4.generate(),
  <span class="hljs-attr">todo</span>: body.value.todo,
  <span class="hljs-attr">isCompleted</span>: <span class="hljs-literal">false</span>,
};
</code></pre><p><code>let newTodo: Todo = {}</code> ensures that <code>newTodo</code> follows the same structure as the rest of the todos. We then assign a random id by using <code>v4.generate()</code>, set todo to <code>body.value.todo</code> and <code>isCompleted</code> to  <code>false</code>.</p>
<p>The thing to notice here is all the data the user sends us we can access from <code>body.value</code> in <code>oak</code>.</p>
<p>Next we do the following:</p>
<pre><code><span class="hljs-keyword">let</span> data = [...todos, newTodo];
response.body = {
  <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
  data,
};
</code></pre><p>Append the <code>newTodo</code> to our current list of todos and simply set the body to <code>{success: true &amp; data: data</code>.</p>
<p>And we are done ✅ with this controller as well.</p>
<p>Let's restart our server:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>In my postman, I open up a new tab. Set the request to <code>POST</code> type and in the <code>URL</code> bar type <code>http://localhost:8080/todos</code>. Then hit <code>Send</code> and this is what you see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-02.24.00.png" alt="Image" width="600" height="400" loading="lazy">
<em>I send an empty request and get a 400 status error code along with an error message</em></p>
<p>Then I send some content in the body of the request payload and try again:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-02.24.15.png" alt="Image" width="600" height="400" loading="lazy">
<em>Awesome, POST /todos with body content { todo: "eat a lamma" } is success &amp; we can see content appended to our current todo list</em></p>
<p>Cool, we can see that our API is working as expected.</p>
<p>Two APIs down, three more to go. </p>
<p>We are almost there. Most of the hard work is done. ☺️ ? ? ?</p>
<p>Let's move on to our third API:</p>
<pre><code class="lang-controllers/todos.ts">import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interfaces
import Todo from "../interfaces/Todo.ts";
// stubs
import todos from "../stubs/todos.ts";

export default {
  getAllTodos: () =&gt; {},
  createTodo: async () =&gt; {},
  /**
   * @description Get todo by id
   * @route GET todos/:id
   */
  getTodoById: (
    { params, response }: { params: { id: string }; response: any },
  ) =&gt; {
    const todo: Todo | undefined = todos.find((t) =&gt; {
      return t.id === params.id;
    });
    if (!todo) {
      response.status = 404;
      response.body = {
        success: false,
        message: "No todo found",
      };
      return;
    }

    // If todo is found
    response.status = 200;
    response.body = {
      success: true,
      data: todo,
    };
  },
  updateTodoById: async () =&gt; {},
  deleteTodoById: () =&gt; {},
};
</code></pre>
<p>Let's talk about our controller for <code>GET todos/:id</code>. This will get us a todo by ID.</p>
<p>Let's break this down into smaller parts and discuss it:</p>
<pre><code><span class="hljs-keyword">const</span> todo: Todo | <span class="hljs-literal">undefined</span> = todos.find(<span class="hljs-function">(<span class="hljs-params">t</span>) =&gt;</span> t.id === params.id);
<span class="hljs-keyword">if</span> (!todo) {
  response.status = <span class="hljs-number">404</span>;
  response.body = {
    <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"No todo found"</span>,
  };
  <span class="hljs-keyword">return</span>;
}
</code></pre><p>In the first part we set a new <code>const todo</code> and set its type to either <code>Todo</code> or <code>undefined</code>. So <code>todo</code> will either be an object with the <code>Todo</code> interface shape or it will be <code>undefined</code> – it can not be anything else.</p>
<p>We then <code>_todos.find_((_t_)</code> =&gt; <em>t.id</em> === <em>params.id</em>); use <a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find">Array.find()</a> to find the <code>todo</code> with the id provided in <code>params.id</code>. If it matches we get a <code>Todo</code> with shape <code>todo</code>, otherwise <code>undefined</code>.</p>
<p>If <code>todo</code> is undefined, it means that this <code>if</code> block will run:</p>
<pre><code><span class="hljs-keyword">if</span> (!todo) {
  response.status = <span class="hljs-number">404</span>;
  response.body = {
    <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"No todo found"</span>,
  };
  <span class="hljs-keyword">return</span>;
}
</code></pre><p>Here we simply set the status to <code>404</code> which means <code>not found</code> along with our standard failure response or <code>{ status, message }</code></p>
<p>Cool, right? ?</p>
<p>Next we simply do this:</p>
<pre><code><span class="hljs-comment">// If todo is found</span>
response.status = <span class="hljs-number">200</span>;
response.body = {
  <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">data</span>: todo,
};
</code></pre><p>Set a <code>200</code> success response and in our response body we set <code>success: true &amp; data: todo</code>.</p>
<p>Let's run this in our postman.</p>
<p>Let's restart our server:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>In my postman, I open up a new tab. Set the request to <code>GET</code> type and in the <code>URL</code> bar type <code>http://localhost:8080/todos/:id</code>, then hit <code>Send</code>.</p>
<p>Since we are generating ID's randomly, first get all todos by hitting theget all todos API. Then from any todo get one of its ID to test this newly created API.<br>Every time you restart this Deno application, new ID's will be generated.</p>
<p>Let's go:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-02.40.52.png" alt="Image" width="600" height="400" loading="lazy">
<em>404 status, no record found case</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-02.41.36.png" alt="Image" width="600" height="400" loading="lazy">
<em>Provided it a known ID and it returned the todo associated with that ID along with status 200</em></p>
<p>If you need to reference the original source code of this tutorial go <a target="_blank" href="https://github.com/adeelibr/deno-playground/tree/master/chapter_1:oak"><strong>here</strong></a>.</p>
<p>Great, 3 APIs done, 2 more to go.</p>
<pre><code class="lang-controllers/todos.ts">import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interfaces
import Todo from "../interfaces/Todo.ts";
// stubs
import todos from "../stubs/todos.ts";

export default {
  getAllTodos: () =&gt; {},
  createTodo: async () =&gt; {},
  getTodoById: () =&gt; {},
  /**
   * @description Update todo by id
   * @route PUT todos/:id
   */
  updateTodoById: async (
    { params, request, response }: {
      params: { id: string },
      request: any,
      response: any,
    },
  ) =&gt; {
    const todo: Todo | undefined = todos.find((t) =&gt; t.id === params.id);
    if (!todo) {
      response.status = 404;
      response.body = {
        success: false,
        message: "No todo found",
      };
      return;
    }

    // if todo found then update todo
    const body = await request.body();
    const updatedData: { todo?: string; isCompleted?: boolean } = body.value;
    let newTodos = todos.map((t) =&gt; {
      return t.id === params.id ? { ...t, ...updatedData } : t;
    });
    response.status = 200;
    response.body = {
      success: true,
      data: newTodos,
    };
  },
  deleteTodoById: () =&gt; {},
};
</code></pre>
<p>Let's talk about our controller for <code>PUT todos/:id</code>. This will update a todo by ID.</p>
<p>Let's break this down into smaller bits:</p>
<pre><code><span class="hljs-keyword">const</span> todo: Todo | <span class="hljs-literal">undefined</span> = todos.find(<span class="hljs-function">(<span class="hljs-params">t</span>) =&gt;</span> t.id === params.id);
<span class="hljs-keyword">if</span> (!todo) {
  response.status = <span class="hljs-number">404</span>;
  response.body = {
    <span class="hljs-attr">success</span>: <span class="hljs-literal">false</span>,
    <span class="hljs-attr">message</span>: <span class="hljs-string">"No todo found"</span>,
  };
  <span class="hljs-keyword">return</span>;
}
</code></pre><p>This is something we did exactly the same with the previous controller as well, so I won't go into much detail here.</p>
<p>Pro tip here: You can if you want make this piece of code a generic code block and then use it in both controllers.</p>
<p>Next we do this:</p>
<pre><code><span class="hljs-comment">// if todo found then update todo</span>
<span class="hljs-keyword">const</span> body = <span class="hljs-keyword">await</span> request.body();
<span class="hljs-keyword">const</span> updatedData: { todo?: string; isCompleted?: boolean } = body.value;
<span class="hljs-keyword">let</span> newTodos = todos.map(<span class="hljs-function">(<span class="hljs-params">t</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> t.id === params.id ? { ...t, ...updatedData } : t;
});
response.status = <span class="hljs-number">200</span>;
response.body = {
  <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">data</span>: newTodos,
};
</code></pre><p>The piece of code I want to talk about here is the following:</p>
<pre><code><span class="hljs-keyword">const</span> updatedData: { todo?: string; isCompleted?: boolean } = body.value;
<span class="hljs-keyword">let</span> newTodos = todos.map(<span class="hljs-function">(<span class="hljs-params">t</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> t.id === params.id ? { ...t, ...updatedData } : t;
});
</code></pre><p>First we do <code>const updatedData = body.value</code> and then add type checking to <code>updatedData</code> like the following:</p>
<pre><code>updatedData: { todo?: string; isCompleted?: boolean }
</code></pre><p>This piece of code is telling TS that <code>updatedData</code> is an object which can <code>have/not have</code> <em>todo: string and</em> also can <code>have/not have</code> <em>isCompleted: boolean.</em></p>
<p>Then we simply map over all todos like this:</p>
<pre><code><span class="hljs-keyword">let</span> newTodos = todos.map(<span class="hljs-function">(<span class="hljs-params">t</span>) =&gt;</span> {
  <span class="hljs-keyword">return</span> t.id === params.id ? { ...t, ...updatedData } : t;
});
</code></pre><p>And where <code>params.id</code> match with <code>t.id</code> we simply append everything to that object we get from the user.</p>
<p>We are done with this API as well. </p>
<p>Let's restart our server:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>Open up a new tab in Postman. Set the request to <code>PUT</code> and in the <code>URL</code> bar type in <code>http://localhost:8080/todos/:id</code>, then hit <code>Send</code>:</p>
<p>Since we are generating ID's randomly,  first get all todos by hitting get all todos API. Then from any todo get one of its ID to test this newly created API.<br>Every time you restart this Deno application, new ID's will be generated.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-02.59.39.png" alt="Image" width="600" height="400" loading="lazy">
<em>404 status returned and no todo found error message given</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-03.00.21.png" alt="Image" width="600" height="400" loading="lazy">
<em>Provided a known ID, updated todo content in body. It returned the updated todo along with all the other todos</em></p>
<p>This is amazing – four APIs done and just one more to go.</p>
<pre><code class="lang-controllers/todos.ts">import { v4 } from "https://deno.land/std/uuid/mod.ts";
// interfaces
import Todo from "../interfaces/Todo.ts";
// stubs
import todos from "../stubs/todos.ts";

export default {
  getAllTodos: () =&gt; {},
  createTodo: async () =&gt; {},
  getTodoById: () =&gt; {},
  updateTodoById: async () =&gt; {},
  /**
   * @description Delete todo by id
   * @route DELETE todos/:id
   */
  deleteTodoById: (
    { params, response }: { params: { id: string }; response: any },
  ) =&gt; {
    const allTodos = todos.filter((t) =&gt; t.id !== params.id);

    // remove the todo w.r.t id and return
    // remaining todos
    response.status = 200;
    response.body = {
      success: true,
      data: allTodos,
    };
  },
};
</code></pre>
<p>Let's talk about our controller for <code>Delete todos/:id</code> this will delete a todo by ID.</p>
<p>We simply run a filter on all todos:</p>
<pre><code><span class="hljs-keyword">const</span> allTodos = todos.filter(<span class="hljs-function">(<span class="hljs-params">t</span>) =&gt;</span> t.id !== params.id);
</code></pre><p>Remove the <code>todo.id</code> that matches with <code>params.id</code> and return the rest.</p>
<p>Then we do this:</p>
<pre><code><span class="hljs-comment">// remove the todo w.r.t id and return</span>
<span class="hljs-comment">// remaining todos</span>
response.status = <span class="hljs-number">200</span>;
response.body = {
  <span class="hljs-attr">success</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">data</span>: allTodos,
};
</code></pre><p>Simply return all the todos left which do not have the same todo.id.</p>
<p>Let's restart our server:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>Open up a new tab in Postman. This time set the request to <code>DELETE</code> and in the <code>URL</code> bar type <code>http://localhost:8080/todos/:id</code> and hit <code>Send</code>.</p>
<p>Since we are generating ID's randomly,  first get all todos by hitting get all todos API. Then from any todo get one of its ID to test this newly created API.<br>Every time you restart this Deno application, new ID's will be generated.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-03.07.54.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>With this we are all done with all five APIs.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/75bdf06df3fd6ddd9d3311d8cb2be029.jpg" alt="Image" width="600" height="400" loading="lazy"></p>
<hr>
<p>Now we only have two things remaining:</p>
<ul>
<li>Add a not found route middleware so that when the user tries to access an unknown route it gives an error.</li>
<li>Add a logger API that consoles the response time it took to return data from one API endpoint.</li>
</ul>
<h2 id="heading-creating-a-route-middleware-for-routes-that-arent-found">Creating a route middleware for routes that aren't found</h2>
<p>In your root folder create a new folder called <code>middlewares</code>. Inside that folder create a file called <code>notFound.ts</code> and inside this file add this code:</p>
<pre><code class="lang-middlwares/notfound.ts">export default ({ response }: { response: any }) =&gt; {
  response.status = 404;
  response.body = {
    success: false,
    message: "404 - Not found.",
  };
};
</code></pre>
<p>Here we aren't doing anything new – it is very similar to our controllers structure. Just returning a status <code>404</code> (which means not found) along with a JSON object for <code>{ success, message }</code>.</p>
<p>Next go in your <code>server.ts</code> file and add the following content:</p>
<ul>
<li>Add this import somewhere at the top:</li>
</ul>
<pre><code class="lang-server.ts">// not found
import notFound from './middlewares/notFound.ts';
</code></pre>
<ul>
<li>And then just below your <code>app.use(todoRouter.allowedMethods())</code> add this line like this:</li>
</ul>
<pre><code class="lang-server.ts">app.use(todoRouter.routes());
app.use(todoRouter.allowedMethods());

// 404 page
app.use(notFound);
</code></pre>
<p>The order of execution is important here: every time we try to access an API end point it will first match/check routes from our <code>todoRouter</code>. If none are found, it will then execute <code>app_.use_(notFound);</code>. </p>
<p>Let's see if this works.</p>
<p>Restart the server:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>Open up a new tab in Postman. Set the request to <code>GET</code> and in the <code>URL</code> bar type <code>http://localhost:8080/something-unknown</code>, then hit <code>Send</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-12.28.10.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>So we now have a route middleware that we put at the end of our routes in <code>server.ts</code> as <code>app_.use_(notFound);</code>. If no route matches this middleware it will execute and return a <code>404</code> status code (which means not found). Then we simply send a response message like always which is <code>{success, message}</code>.</p>
<p><strong>Pro tip:</strong> We have decided that <code>{success, message}</code> is what we return in failed scenarios and <code>{success, data}</code> is what we return to user in success scenarios. So we can even make these to object/shapes as interfaces and add them to our project to ensure consistency and safe type checking.</p>
<p>Cool, now we are done with one of our middlewares – let's add the other middleware for logging our APIs in the console.</p>
<p><strong>Reminder:</strong> If you get stuck anywhere you can use the <a target="_blank" href="https://github.com/adeelibr/deno-playground/tree/master/chapter_1:oak">source code here</a>.</p>
<h2 id="heading-logging-apis-in-console">Logging APIs in console</h2>
<p>In your <code>middlewares</code> folder create a new file called <code>logger.ts</code> and enter the following code:</p>
<pre><code class="lang-middlewares/logger.ts">import {
  green,
  cyan,
  white,
  bgRed,
} from "https://deno.land/std@0.53.0/fmt/colors.ts";

const X_RESPONSE_TIME: string = "X-Response-Time";

export default {
  logger: async (
    { response, request }: { response: any, request: any },
    next: Function,
  ) =&gt; {
    await next();
    const responseTime = response.headers.get(X_RESPONSE_TIME);
    console.log(`${green(request.method)} ${cyan(request.url.pathname)}`);
    console.log(`${bgRed(white(String(responseTime)))}`);
  },
  responseTime: async (
    { response }: { response: any },
    next: Function,
  ) =&gt; {
    const start = Date.now();
    await next();
    const ms: number = Date.now() - start;
    response.headers.set(X_RESPONSE_TIME, `${ms}ms`)
  },
};
</code></pre>
<p>In your <code>server.ts</code> file add this code:</p>
<ul>
<li>Import this somewhere at the top:</li>
</ul>
<pre><code class="lang-server.ts">// logger
import logger from './middlewares/logger.ts';
</code></pre>
<ul>
<li>Just above your <code>todoRouter</code> code add these middlewares like this:</li>
</ul>
<pre><code><span class="hljs-comment">// order of execution is important;</span>
app.use(logger.logger);
app.use(logger.responseTime);

app.use(todoRouter.routes());
app.use(todoRouter.allowedMethods());
</code></pre><p>Now let's discuss what we just did.</p>
<p>Let's talk about the <code>logger.ts</code> file and break it down into bits:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">import</span> {
  green,
  cyan,
  white,
  bgRed,
} <span class="hljs-keyword">from</span> <span class="hljs-string">"https://deno.land/std@0.53.0/fmt/colors.ts"</span>;
</code></pre>
<p>I am importing some console colors and console background colors that I want to use in API logging.</p>
<p>This is similar to what we did in our <code>eventListener</code> in our <code>server.ts</code> file. We will use colors in our console to log API requests.</p>
<p>Next I set <code>const X_RESPONSE_TIME: string = "X-Response-Time";</code>. This is the header we will inject in our API requests as they come into our server. I am calling this <code>X_RESPONSE_TIME</code> and its value is <code>X-Response-Time</code>. I will demonstrate its usage in a bit.</p>
<p>Next we simply export an object like this:</p>
<pre><code class="lang-middlewares/logger.ts">export default {
    logger: async ({ response, request }, next) {}
    responseTime: async ({ response }, next) {}
};
</code></pre>
<p>And then we simply use it inside our <code>server.ts</code> file like this:</p>
<pre><code class="lang-server.ts">// order of execution is important;
app.use(logger.logger);
app.use(logger.responseTime);
</code></pre>
<p>Let's now discuss what is happening in our logger middleware code and discuss it execution style using <code>next()</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-12.51.36.png" alt="Image" width="600" height="400" loading="lazy">
<em>Execution of order of logging middleware when GET /todos API is called.</em></p>
<p>The only difference here and in the controllers we had before is the use of the <code>next()</code> function. This functions helps us jump from one controller to the other as shown in the image below.</p>
<p>So in:</p>
<pre><code class="lang-middlewares/logger.ts">export default {
  logger: async (
    { response, request }: { response: any, request: any },
    next: Function,
  ) =&gt; {
    await next();
    const responseTime = response.headers.get(X_RESPONSE_TIME);
    console.log(`${green(request.method)} ${cyan(request.url.pathname)}`);
    console.log(`${bgRed(white(String(responseTime)))}`);
  },
  responseTime: async (
    { response }: { response: any },
    next: Function,
  ) =&gt; {
    const start = Date.now();
    await next();
    const ms: number = Date.now() - start;
    response.headers.set(X_RESPONSE_TIME, `${ms}ms`)
  },
};
</code></pre>
<p>Keep in mind that this is what we have in our <code>server.ts</code> file:</p>
<pre><code class="lang-server.ts">// order of execution is important;
app.use(logger.logger);
app.use(logger.responseTime);

app.use(todoRouter.routes());
app.use(todoRouter.allowedMethods());
</code></pre>
<p>The order of execution is as follows:</p>
<ul>
<li>logger.logger middleware</li>
<li>logger.responseTime middleware</li>
<li>todoRouter controller (whatever path is called by the user, for the purpose of explanation I am assuming that the user called <code>GET /todos</code> API to get all todos.)</li>
</ul>
<p>So it will first execute logger.logger middleware which is this:</p>
<pre><code class="lang-middlewares/logger.ts">logger: async (
    { response, request }: { response: any, request: any },
    next: Function,
  ) =&gt; {
    await next();
    const responseTime = response.headers.get(X_RESPONSE_TIME);
    console.log(`${green(request.method)} ${cyan(request.url.pathname)}`);
    console.log(`${bgRed(white(String(responseTime)))}`);
  },
</code></pre>
<p>It will come inside this function and immediately as it reads <code>await next()</code> it quickly jumps to the next middleware which is <code>responseTime</code>:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-12.51.36-1.png" alt="Image" width="600" height="400" loading="lazy">
<em>Sharing the image above again for revision.</em></p>
<p>Inside <code>responseTime</code>, it only executes two lines which are (look at execution order 2 in image above):</p>
<pre><code class="lang-middlewares/logger.ts">const start = Date.now();
await next();
</code></pre>
<p>before jumping to the <code>getAllTodos</code> controller. Once it goes inside <code>getAllTodos</code> it will run the entire code inside that controller. </p>
<p>Since in that controller we are not using <code>next()</code> it will simply return the flow of logic back to <code>responseTime</code> controller. There it will run the following:</p>
<pre><code class="lang-middlewares/logger.ts">const ms: number = Date.now() - start;
response.headers.set(X_RESPONSE_TIME, `${ms}ms`)
</code></pre>
<p>Now keeping in perspective of the order of execution which is <code>2, 3, 4</code> (look at the image above).</p>
<p>This is what happens:</p>
<ul>
<li>We capture the data in <code>ms</code> by doing <code>const</code> <em><code>start</code></em> <code>=</code> <em><code>Date.now</code></em><code>();</code>. Then we immediately call <code>next()</code> which goes to <code>getAllTodos</code> controller and runs the entire code. Then it comes back in the <code>responseTime</code> controller.</li>
<li>We then subtract that <code>start</code> date with whatever the date is at that moment by doing <code>const _ms_: _number_ = _Date.now_()</code> - <em>start</em>; <code>ms</code>. Here it will return a number which is basically the difference in milliseconds that will tell us all the time it took Deno to execute our <code>getAllTodos</code> controller.</li>
</ul>
<p>Sharing the image once again for review:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-12.51.36-2.png" alt="Image" width="600" height="400" loading="lazy"></p>
<ul>
<li>Next we simply set headers in our <code>response</code> like this:</li>
</ul>
<pre><code>response.headers.set(X_RESPONSE_TIME, <span class="hljs-string">`<span class="hljs-subst">${ms}</span>ms`</span>)
</code></pre><p>Which just sets the header value <code>X-Response-Time</code> to the milliseconds it took Deno to execute our API.</p>
<ul>
<li>Then from execution order <code>4</code> we move back to execution order <code>5</code> (have a look at the image above for reference).</li>
</ul>
<p>Here we simply do:</p>
<pre><code class="lang-middlwares/logger.ts">const responseTime = response.headers.get(X_RESPONSE_TIME);
console.log(`${green(request.method)} ${cyan(request.url.pathname)}`);
console.log(`${bgRed(white(String(responseTime)))}`);
</code></pre>
<ul>
<li>We get the time we passed in the <code>X-Response-Time</code></li>
<li>Then we take that time and simply console it colourfully in the console.</li>
</ul>
<p><code>request.method</code> tells us the method used to call our API, that is  <code>GET, PUT etc</code> while <code>request.url.pathname</code> will tell the API which path the user used i.e, <code>/todos</code></p>
<p>Let's see if this works.</p>
<p>Restart the server:</p>
<pre><code>$ deno run --allow-net server.ts
</code></pre><p>Open up a new tab in Postman. Set the request to <code>GET</code>, type in <code>http://localhost:8080/todos</code>, and hit <code>Send</code>.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-13.17.13.png" alt="Image" width="600" height="400" loading="lazy"></p>
<p>Hit the API a couple of times in Postman. Then when you go back to the console, you should see something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2020/05/Screenshot-2020-05-29-at-13.21.03.png" alt="Image" width="600" height="400" loading="lazy">
<em>API being logged in our console</em></p>
<p>This is it – we are done.</p>
<p>If you still feel stuck, take a look at the entire source code for this tutorial here: <a target="_blank" href="https://github.com/adeelibr/deno-playground/tree/master/chapter_1:oak">github.com/adeelibr/deno-playground/tree/master/chapter_1:oak</a></p>
<p>I hope that you found this article useful and that it was able to help you learn something today.</p>
<p>If you liked it, please do share it on social media. If you want to have a discussion about it, reach out to me on <a target="_blank" href="https://twitter.com/adeelibr">Twitter</a>.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Azure Logic Apps Use Case – Black Friday ]]>
                </title>
                <description>
                    <![CDATA[ By Nadeem Ahamed This blog gives an overview of how Azure Serverless technologies came to rescue when the custom-built integration system went down. Also, it shows the high-level architecture solution built using Azure Serverless services like Logic ... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/azure-logic-apps-use-case-black-friday/</link>
                <guid isPermaLink="false">66d46041787a2a3b05af43e8</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Logic Apps ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Middleware ]]>
                    </category>
                
                    <category>
                        <![CDATA[ use-cases ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ freeCodeCamp ]]>
                </dc:creator>
                <pubDate>Thu, 04 Jul 2019 04:25:56 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2019/07/black-friday-Banner-image.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>By Nadeem Ahamed</p>
<p>This blog gives an overview of how Azure Serverless technologies came to rescue when the custom-built integration system went down. Also, it shows the high-level architecture solution built using Azure Serverless services like Logic Apps, Service Bus Queue and Topics, etc to replace the legacy system.</p>
<p>This article was originally published at <a target="_blank" href="https://www.serverless360.com">Serverless360.com</a></p>
<h2 id="heading-how-it-all-started">How it all Started?</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/1-Legacy-system.png" alt="Legacy system" width="600" height="400" loading="lazy"></p>
<p>About three years ago, Northwind, a company who runs their business in B2B space wanted to extend its business to B2C. So, the company wanted to open a Web Shop (SaaS). Since it was a B2B specialized company there were no warehouse and transport service to serve the customers effectively. The company chose to go ahead with LSP (Logistics Service Provider) instead. The legacy system was built using a middleware to connect the Web Shop and the LSP. Later, the legacy system was integrated with the email system. The complexity of the system increased as several branches (Web shops) opened across the globe.</p>
<p>One day, the whole system went down, and the company started losing hundreds of orders. Then, the company approached an expert team to fix their middleware.</p>
<h3 id="heading-requirements-to-be-considered"><strong>Requirements to be considered</strong></h3>
<ul>
<li>Stability – the system needs to be stable enough to handle a lot of orders.</li>
<li>Monitoring – the system should be monitored to alert the operation personnel when something goes wrong.</li>
<li>To handle 10,000 orders per hour.</li>
<li>New SaaS webshop</li>
</ul>
<h2 id="heading-the-solution">The Solution</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/2-serverless-middleware.png" alt="Serverless middleware" width="600" height="400" loading="lazy"></p>
<p>The expert team replaced the middleware using Azure serverless technologies. Predominantly, Logic Apps and other Serverless entities like Azure Functions, Service Bus Queues and Topics were used. The stateful middleware was changed to stateless using event-based approach.</p>
<h2 id="heading-what-is-serverless">What is Serverless?</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/3-what-is-serverless.png" alt="what is serverless" width="600" height="400" loading="lazy"></p>
<p><strong>The abstraction of server, platform, and runtime</strong> – There is no need to provision or maintain any servers. There is no software or runtime to install, maintain, or administer.</p>
<p><strong>Event-driven scaling</strong> – This is one of the important characteristics of Serverless, you shouldn’t worry about scaling your solution if demand arises.</p>
<p><strong>Micro-billing</strong> – When your code is executed you pay per execution. Typically, the vendors calculate this based on memory consumption and the time it takes for the execution.</p>
<h3 id="heading-advantages">Advantages</h3>
<p><strong>Manage apps not servers</strong> – The significant advantage of serverless is that the user does not manage the servers, but the cloud service providers do.</p>
<p><strong>Reduced DevOps</strong> – It reduces the DevOps cost as the infrastructure is maintained by CSP.</p>
<p><strong>Faster time to Market</strong> – It reduces the time to market as serverless technology screens the ground works and lets the developer focus on the logic.</p>
<h2 id="heading-azure-logic-apps">Azure Logic Apps</h2>
<blockquote>
<p><em>You can run a business workflow in Azure using the Logic App service.</em></p>
</blockquote>
<p>The Logic App is a logical container for one workflow you can define using triggers and actions. A trigger can instantiate a workflow, which can consist of one or many activities (actions). For instance, you can trigger a workflow by sending an HTTP request or schedule a workflow every hour to retrieve data from a public website. There are 200+ out-of-the-box connectors available for enterprise integration.</p>
<h3 id="heading-benefits">Benefits</h3>
<ul>
<li>Out-of-the-box connector reduces the integration challenges</li>
<li>Connect and Integrate data from the cloud to on-premises</li>
<li>B2B and enterprise messaging in the cloud</li>
<li>A powerful web-based workflow designer</li>
</ul>
<h2 id="heading-pricing-of-azure-logic-apps">Pricing of Azure Logic Apps</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/4-logic-Apps-pricing.png" alt="Azure logic Apps pricing" width="600" height="400" loading="lazy"></p>
<p>The pricing is very simple. It works on the pay-as-you-go model, it would cost you only a few nickels. For instance, if you process 1000 service bus messages a day, with a workflow of five actions it would cost you EUR 4.62 approx. To execute a normal action, it would cost $ 0.000025 and for a Standard connector, it would cost you $0.000125. Even, the Enterprise connector would cost you only $0.001. For more information see the pricing page <a target="_blank" href="https://azure.microsoft.com/en-in/pricing/details/logic-apps/">here</a>.</p>
<h2 id="heading-basic-architecture-solution">Basic Architecture Solution</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/5-Basic-architecture-solution.png" alt="Basic architecture solution" width="600" height="400" loading="lazy"></p>
<p>Initially, there is a webshop connected to Webshop publisher Logic App through Webhook. The Webshop publisher Logic Apps act as the orchestrator for the workflow. The data from the Webshop is converted into Canonical entity and passed to the Canonical Order Mapper Logic App. Subsequently, the control flows to the CE publisher where the translation of the object happens. Then, the translated object is sent to Service Bus Topic. Topic Subscriptions provide a one-to-many form of communication, in a publish/subscribe pattern. Get to know about Topic Subscription rules <a target="_blank" href="https://www.serverless360.com/blog/manage-azure-topic-subscription-rules">here</a>.  Based on the filter, the orders are sent to LSP Subscriber and MS (Marketing System) Subscriber.</p>
<h2 id="heading-impressive-scalability-of-azure-logic-apps">Impressive Scalability of Azure Logic Apps</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/6-impressive-scalability.png" alt="impressive scalability" width="600" height="400" loading="lazy"></p>
<p>On running the above workflow, it could process 73,120 orders in 20 min. Every order would get processed in less than 3 seconds and the success rate was above 98 percent. The above log shows that there were 73,120 runs completed and out of which 72,972 runs were accomplished and 148 runs were failed.</p>
<h2 id="heading-view-of-entities-in-a-resource-group">View of Entities in a Resource Group</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/7-view-of-entities.png" alt="view of entities" width="600" height="400" loading="lazy"></p>
<p>The above picture represents how the entities will be listed in a Resource Group. For better management of the entities use the Display Name tag. It helps the user to debug the workflow in case of failure.</p>
<h2 id="heading-webshop-publisher-logic-app">Webshop Publisher Logic App</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/8-webshop-publisher-logic-app.png" alt="webshop publisher logic app" width="600" height="400" loading="lazy"></p>
<p>Out-of-the-box, there is an HTTP trigger which initiates the Logic App and sends 201 response directly for the received message. 201 response represents that request has been fulfilled and has resulted in one or more new resources being created. Subsequently, sends the order message to the other Logic App (Map order to Canonical order) and to Publish canonical order.</p>
<h3 id="heading-tracked-properties">Tracked properties</h3>
<p>In “Response 201 directly” action, the following properties are tracked</p>
<ul>
<li>Customer Email</li>
<li>Flow</li>
<li>Order ID</li>
<li>Shop ID</li>
</ul>
<h2 id="heading-canonical-order-mapper">Canonical Order Mapper</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/9canonical-order-mapper.png" alt="canonical order mapper" width="600" height="400" loading="lazy"></p>
<p>The Logic App gets triggered by receiving the HTTP request. Then, the message would be passed to Data Operation actions to compose canonical order items and create shop reference data.  Subsequently, composes the canonical order using Data Operation action and sends back the response.</p>
<h2 id="heading-service-bus-explorer">Service Bus Explorer</h2>
<p>For easy management of the entities use Service Bus Explorer. It provides filter option for Service Bus Topic using which the message can be sent to the defined subscriptions (LSP). The message will be filtered based on the properties defined in the Service Bus Topic. <a target="_blank" href="https://www.serverless360.com/compare-service-bus-explorer">Here is how Serverless360 makes a better option for Service Bus Explorer.</a></p>
<h2 id="heading-monitoring">Monitoring</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/10-Log-Analytics.png" alt="Log Analytics" width="600" height="400" loading="lazy"></p>
<p>The above picture shows the Log Analytics dashboard. It provides a graphical representation and monitoring capability for the entities associated with the Log analytics. Inside the Log Analytics, the user can run powerful quires and inspect the database if something goes wrong.</p>
<h2 id="heading-demo-order-paid">Demo – order paid</h2>
<p>To test the new solution architecture, send the test order, use the Postman tool to send a POST message to the Logic App. On sending the successful order, you can see the 201 response at the bottom left corner of the Postman tool. On receiving the order, the Logic Apps gets triggered and finally, the order message would reach any one of the respective LSP.</p>
<h2 id="heading-cicd-pipeline">CI/CD pipeline</h2>
<p><img src="https://www.serverless360.com/wp-content/uploads/2019/06/10-CICD-pipeline.png" alt="CICD pipeline" width="600" height="400" loading="lazy"></p>
<p>The above picture represents the CI/CD pipeline architecture. There are three blocks namely Developer context, Azure DevOps and Azure subscription. The Developer context contains PowerShell, IDE’s, etc. Once the developer checks in the code, it commits to the repository. On switching the Build option, build pipeline deploys the code to the Blob storage. Once Build pipeline is done with the work, Release pipeline kicks off and tells the ARM to reflect the changes in Development, Testing, and Production environment.</p>
<h3 id="heading-benefits-1">Benefits</h3>
<ul>
<li>No manual steps required to deploy the code.</li>
<li>Quality control can be done</li>
<li>The organization can have a bigger development team</li>
</ul>
<h3 id="heading-challenges"><strong>Challenges</strong></h3>
<ul>
<li>A lot of housekeeping is required around ARM templates.</li>
<li>Things get complex if any ARM template goes down. Because the failure can be spotted only during release.</li>
<li>The rhythm of the service changes rapidly</li>
</ul>
<h2 id="heading-key-takeaways-from-the-above-solution">Key Takeaways from the Above Solution</h2>
<ul>
<li>Faster time to market: There were only three developers and they could get the project done within 3 months.</li>
<li>Resilient and scalable: As we saw above the application was highly scalable. It could handle about 73 thousand orders in 20 minutes.</li>
<li>It is best suitable for business-critical systems</li>
</ul>
<p>This blog is an extraction of the session “Black Friday? Logic Apps to the rescue” presented by <a target="_blank" href="https://twitter.com/aarjanmeirink">Aarjan Meirink</a> at MSBuild 2019.</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
