<?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[ Alaran Ayobami - 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[ Alaran Ayobami - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 22:24:00 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/Ayobami6/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Deploy a Restful Web Service on Microsoft Azure App Service ]]>
                </title>
                <description>
                    <![CDATA[ Hey there! 👋, How’s it going? I hope you're doing well. Whether you're a seasoned coder, a curious learner, or just someone browsing through, welcome to my little corner of the internet. In this tutorial, we’ll dive into how you can deploy a web ser... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/deploy-a-restful-web-service-on-microsoft-azure-app-service/</link>
                <guid isPermaLink="false">67e6c180423cd4f90a6350b5</guid>
                
                    <category>
                        <![CDATA[ Azure ]]>
                    </category>
                
                    <category>
                        <![CDATA[ azure-devops ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud Computing ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Cloud ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ deployment ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Azure App Service ]]>
                    </category>
                
                    <category>
                        <![CDATA[ azure-app-services ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alaran Ayobami ]]>
                </dc:creator>
                <pubDate>Fri, 28 Mar 2025 15:34:24 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1743176028047/61eba7a3-5505-4152-9df5-59a1cb8c61ac.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hey there! 👋, How’s it going?</p>
<p>I hope you're doing well. Whether you're a seasoned coder, a curious learner, or just someone browsing through, welcome to my little corner of the internet.</p>
<p>In this tutorial, we’ll dive into how you can deploy a web service on Microsoft Azure app service. It’s a topic I’ve been excited to explore, and I hope you’ll find it insightful and helpful. So grab a coffee, sit back, and let’s get started.</p>
<h3 id="heading-prerequisites">Prerequisites</h3>
<ul>
<li><p>Basic understanding of RESTful web services</p>
</li>
<li><p>Programming knowledge</p>
</li>
<li><p>Docker basics</p>
</li>
<li><p>Docker Hub account</p>
</li>
<li><p>Command Line Interface (CLI) skills</p>
</li>
</ul>
<h3 id="heading-what-well-cover">What we’ll cover:</h3>
<ul>
<li><p><a class="post-section-overview" href="#heading-key-terminologies">Key Terminologies</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-install-docker-and-docker-compose">How to Install Docker and Docker Compose</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-simple-get-client-info-web-service">How to Create a Simple Get Client Info Web Service</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-build-the-apps-docker-image">How to Build the App’s Docker Image</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-run-the-app-in-the-container">How to Run the App in the Container</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-an-azure-resource-group-on-azure-portal">How to Create an Azure Resource Group on Azure Portal.</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-deploy-to-azure-app-service">How to Deploy to Azure App Service</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<p>Before we actually get started, I’d like to go over some key terminologies that I'll be using throughout this tutorial. Understanding these terms will make it easier to follow along and get the most out of what we're discussing. Let’s dive in!</p>
<h2 id="heading-key-terminologies">Key Terminologies</h2>
<h3 id="heading-1-docker"><strong>1. Docker</strong></h3>
<p>Docker is an open-source platform that simplifies application development, shipping, and deployment by using containers. With Docker, there are three key things you can do:</p>
<ul>
<li><p>build once and run anywhere</p>
</li>
<li><p>keep environment consistent, and</p>
</li>
<li><p>easily scale your application with container orchestration tools like Kubernetes.</p>
</li>
</ul>
<h3 id="heading-2-docker-hub"><strong>2. Docker Hub</strong></h3>
<p>Docker Hub is a cloud-based repository where developers can store, share, and manage Docker images. You can think of it as the GitHub for Docker images 😉.</p>
<h3 id="heading-3-docker-image"><strong>3. Docker Image</strong></h3>
<p>A Docker image is a lightweight<strong>,</strong> standalone, and executable package that includes everything needed to run a piece of software. You can also think of it as a blueprint for creating and running a container.</p>
<p>Once built, an image is immutable, meaning it cannot change after creation. Instead, you create a new version when updates are needed. This means that you’ll need to rebuild if you update the code that’s being run in the container.</p>
<h3 id="heading-4-container"><strong>4. Container</strong></h3>
<p>A container is a running instance of a Docker image. It provides an isolated environment where an application runs with all its dependencies, without interfering with the host system or other containers.</p>
<p>Wait, what?! <strong>😕</strong> Well, simply put, a container is like a tiny virtual machine that runs the built Docker image. But unlike traditional VMs, it has no init process (PID 1), meaning it always runs on a host system rather than being fully independent. By now, you should be getting the idea: no image, no container. A container depends on an image to exist. You have to cook before you serve, right? 🍽️</p>
<h3 id="heading-5-azure-resource-group"><strong>5. Azure Resource Group</strong></h3>
<p>An Azure resource group refers to a store or folder containing all related resources for an application you want to deploy to production using MS Azure Cloud. For example, if I want to deploy an eCommerce web app with MS Azure, I could create a resource group called EcommWebAppRG. I’d use this to create all the resources I needed for the web app to go live and be accessible – like VMs, DBs, caches, and other services.</p>
<p>Alrighty, now that all the terms are out of the way, lets get started with the tutorial so you can learn how to deploy a web service on Azure App Service.</p>
<p>Since we are deploying an app, let’s start by creating simple REST API app. I’ll be using Golang for the API development, but you can use any programming language/framework of your choice. If you’d like to follow along with the app for this tutorial, I’ve provided the source code <a target="_blank" href="https://github.com/Ayobami6/client_info_webservice">here</a>.</p>
<h2 id="heading-how-to-install-docker-and-docker-compose">How to Install Docker and Docker Compose</h2>
<p>To install Docker and Docker compose on your PC, for Mac and Windows you’ll need to download Docker desktop for your Operating System <a target="_blank" href="https://hub.docker.com/welcome">here</a>.</p>
<p>For Linux, you can run the following command:</p>
<pre><code class="lang-bash">sudo apt update <span class="hljs-comment"># update apt registry</span>
sudo apt install docker.io <span class="hljs-comment"># for docker engine</span>
sudo apt install docker-compose-plugin
</code></pre>
<p>After downloading the Docker desktop for your application, open your terminal and enter the following command to verify that Docker and Docker Compose have been successfully installed on your machine:</p>
<pre><code class="lang-bash">docker-compose -v <span class="hljs-comment"># this should show the version of docker compose cli you have on your PC</span>
</code></pre>
<p>My Docker Compose version is:</p>
<pre><code class="lang-bash">Docker Compose version v2.31.0-desktop.2
</code></pre>
<pre><code class="lang-bash">docker -v
</code></pre>
<p>You should see something similar if Docker has successfully been installed on your machine:</p>
<pre><code class="lang-bash">Docker version 27.4.0, build bde2b89
</code></pre>
<h2 id="heading-how-to-create-a-simple-get-client-info-web-service">How to Create a Simple Get Client Info Web Service</h2>
<p>Alright, I’ll use this handy tool called <code>sparky_generate</code> to generate the app code template. <code>sparky_generate</code> is a command line tool used to generate boilerplate code for backend development using various backend languages and frameworks.</p>
<p>Use this command to install and setup the tool on your Mac or Linux machine. If you are on Windows, you can use WSL.</p>
<pre><code class="lang-bash">wget https://raw.githubusercontent.com/Ayobami6/sparky_generate/refs/heads/main/install.sh
</code></pre>
<pre><code class="lang-bash">chmod 711 install.sh
./install.sh <span class="hljs-comment"># run the install command like so</span>
</code></pre>
<pre><code class="lang-bash">sparky <span class="hljs-comment"># run the sparky command like so</span>
</code></pre>
<p>You should see something similar to the below. Select whatever framework you want to use for your backend service.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741520002226/b696a376-527b-412a-a8c7-967aca35217a.png" alt="Choose a project type in sparky" class="image--center mx-auto" width="1458" height="1408" loading="lazy"></p>
<p>I will select Go, because I’m using Go for this tutorial. You should have your project template ready once you’ve selected your framework. I won’t go through how to code the web service since it’s out of scope for this tutorial. The goal here is to deploy on Azure using Azure App Service.</p>
<h2 id="heading-how-to-build-the-apps-docker-image">How to Build the App’s Docker Image</h2>
<p>To build the Docker image for our app, we first need to create a Docker file that will include all the steps needed to build the image.</p>
<pre><code class="lang-bash">touch Dockerfile
</code></pre>
<p>We will be using a multistage Docker build to reduce the size of our Docker image. We need something as light as possible.</p>
<p>The multistage Docker build helps reduce size because we use different stages for different concerns. This helps ensure that only what’s needed runs the application in the final stage. For example, we might need certain artifacts to build the application, but we don’t need them to run the application. This is why we have the builder and runner stages in the Docker file below.</p>
<p>Our first stage (build) is concerned with building and bundling the application. The second stage (runner) is just used to run the executable we built in the first stage. So basically all files, modules, and so on used in the build process will be discarded in the runner since they’ve already served their purposes.</p>
<pre><code class="lang-dockerfile"><span class="hljs-comment"># using the first stage as build</span>
<span class="hljs-keyword">FROM</span> golang:<span class="hljs-number">1.23</span>-alpine AS build <span class="hljs-comment"># using alpine base image to reduce size</span>

<span class="hljs-comment"># install git on the machine</span>
<span class="hljs-keyword">RUN</span><span class="bash"> apk add --no-cache git</span>

<span class="hljs-comment"># setting the current work directory on the vm to be /app</span>
<span class="hljs-keyword">WORKDIR</span><span class="bash"> /app</span>

<span class="hljs-comment"># Copying all go dependency files to the working directory</span>
<span class="hljs-keyword">COPY</span><span class="bash"> go.mod go.sum ./</span>

<span class="hljs-comment"># Install go dependencies</span>
<span class="hljs-keyword">RUN</span><span class="bash"> go mod download</span>

<span class="hljs-comment"># copy all remaining files to the working directory</span>
<span class="hljs-keyword">COPY</span><span class="bash"> . .</span>
<span class="hljs-comment"># build the execuatable</span>

<span class="hljs-comment"># build the go program</span>
<span class="hljs-keyword">RUN</span><span class="bash"> go build -o api cmd/main.go</span>

<span class="hljs-comment"># stage 2 AKA the runner</span>
<span class="hljs-keyword">FROM</span> alpine:<span class="hljs-number">3.18</span>

<span class="hljs-keyword">RUN</span><span class="bash">  apk add --no-cache ca-certificates</span>

<span class="hljs-comment"># copy the go executable to the working directory</span>
<span class="hljs-keyword">COPY</span><span class="bash"> --from=build /app/api .</span>

<span class="hljs-comment"># expose the service running port</span>
<span class="hljs-keyword">EXPOSE</span> <span class="hljs-number">6080</span>
</code></pre>
<p>This Dockerfile outlines all the steps for building a Docker image for our app. Lets go through all these steps line by line. Because we are using a multistage build here, our stages are <code>build</code> and <code>runner</code>.</p>
<ul>
<li><p>The first stage build starts from the first <code>FROM golang:1.23-alpine AS build</code>. It initializes a stage with all the steps in the stage. It states that the base image to be used for all the steps in this stage should use a pre-existing golang:1.23 image using an Alpine Linux distro to run all the steps in the stage.</p>
</li>
<li><p>Next, we have <code>RUN</code>, which is used to run the command <code>apk add git</code>, followed by setting the working directory to the /app folder.</p>
</li>
<li><p>Then we have the <code>COPY</code> command that copies all the Go dependencies that will run the Go program.</p>
</li>
<li><p>Following that is <code>RUN go mod download</code> which is used to install all the dependencies.</p>
</li>
<li><p>We then have the command <code>COPY . .</code> to copy all the files to the working directory /app of the image</p>
</li>
<li><p>Then the last step in the build stage, <code>RUN go build -o api cmd/main.go</code>, builds the app code main.go to an executable API. The second stage “runner“ uses an <code>alpine:3.18</code> base image, and also uses the <code>RUN</code> directive to add ca-certificates to the Alpine base image. The <code>COPY</code> is used here to copy just the built executable file from the builder image to the runner image.</p>
</li>
<li><p>We then expose port 6080 so our built container can accept an HTTP connection from port 6080.</p>
</li>
</ul>
<p>Now, let’s write our <code>docker-compose.yml</code> file to define and run our containerized service::</p>
<pre><code class="lang-yaml"><span class="hljs-attr">services:</span>

  <span class="hljs-attr">client_info_app:</span>
    <span class="hljs-attr">build:</span> 
      <span class="hljs-attr">context:</span> <span class="hljs-string">.</span>
      <span class="hljs-attr">dockerfile:</span> <span class="hljs-string">Dockerfile</span>
    <span class="hljs-attr">container_name:</span> <span class="hljs-string">info_app</span>

    <span class="hljs-attr">ports:</span>
      <span class="hljs-bullet">-</span> <span class="hljs-string">"6080:6080"</span>

    <span class="hljs-attr">command:</span> <span class="hljs-string">"./api"</span>
</code></pre>
<h3 id="heading-understanding-the-yaml-structure">Understanding the YAML Structure</h3>
<p>YAML follows a key-value structure similar to a dictionary or hashmap. In our file, the top-level key is <code>services</code>, which acts as the parent key. Within <code>services</code>, we define individual service configurations.</p>
<p>In this case, we have a single service named <code>client_info_app</code>, which contains the necessary properties for Docker to build and run it.</p>
<ul>
<li><p><code>build</code>: This specifies how to build the Docker image for the service. The <code>context: .</code> tells Docker to look for the <code>Dockerfile</code> in the same directory as the <code>docker-compose.yml</code> file.</p>
</li>
<li><p><code>container_name</code>: This assigns a custom name (<code>info_app</code>) to the running container, making it easier to reference.</p>
</li>
<li><p><code>ports</code>: Defines the port mappings between the host and the container. The <code>-</code> before <code>"6080:6080"</code> indicates that multiple mappings could be listed. Here, port <code>6080</code> on the host is mapped to port <code>6080</code> inside the container.</p>
</li>
<li><p><code>command</code>: Specifies the command to execute inside the container once it starts. In this case, it runs <code>./api</code>.</p>
</li>
</ul>
<p>This structure allows us to define and configure multiple services within the <code>services</code> key if needed, but for now, we are only defining <code>client_info_app</code>.</p>
<h2 id="heading-how-to-run-the-app-in-the-container">How to Run the App in the Container</h2>
<p>You can use this command to start the container:</p>
<pre><code class="lang-bash">docker-compose up client_info_app
</code></pre>
<p>The above command will first build the image if it doesn’t exist. Then it runs it, because remember: <strong>no image, no container.</strong></p>
<p>If all looks good, you should have something similar to this, depending on your application framework:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741708248802/0c0e25a0-fa8c-4eea-adaa-5f4986b5fda6.png" alt="Go running webserver" class="image--center mx-auto" width="2424" height="658" loading="lazy"></p>
<p>You should also verify that your Docker image has been built as well. To do that, run the following:</p>
<pre><code class="lang-bash">docker images
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741708480967/dbb033eb-d336-4f22-934b-8d50333b6344.png" alt="Verify that Docker is successfully built" class="image--center mx-auto" width="2386" height="122" loading="lazy"></p>
<p>Voilà! You now have your Docker image built and ready for deployment on Azure App Service.</p>
<p>Let’s go on to the Azure Portal to deploy the app.</p>
<p><strong>Note:</strong> if you don’t have an active Azure Subscription, that’s fine – you can still follow along. If you want to get a trial account, you can <a target="_blank" href="https://azure.microsoft.com/en-us/pricing/purchase-options/azure-account">get one here</a>.</p>
<h2 id="heading-how-to-create-an-azure-resource-group-on-azure-portal">How to Create an Azure Resource Group on Azure Portal.</h2>
<p>As a reminder, an Azure resource group refers to a store or folder containing all related resources for an application you want to deploy to production using MS Azure Cloud. Now let’s go about creating one.</p>
<p>When you login to the Azure portal, you should see some like this, the dashboard:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741709173044/1ab78dd4-97ac-43da-8599-d7b1d790eb13.png" alt="Azure dashboard" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p>Search for Resource group using the search bar:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741709263175/7946270b-11c6-4fef-9abc-996b1efc6f52.png" alt="Search for resource group" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741709619363/5cfce825-0af6-4d64-ae4e-e929ba03d919.png" alt="Resource group control pane" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p>Click on Create to create a new resource group:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741709715096/e519fe55-0ac3-4e9f-8b98-3f34cecfcd43.png" alt="Create a resource group" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p>Give your resource group a name and select a region for it. Here I will use the default East US 2, but you can use any you want. Then click on Review + create.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741770354937/253c33d2-d7b2-44b5-84df-9cb4977aec3b.png" alt="Review resource group creation" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741770386424/0a97c949-5c31-466b-be7f-a43f0783e125.png" alt="Resource group overview" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p>You should see something like the above after creating the resource group.</p>
<h2 id="heading-how-to-deploy-to-azure-app-service">How to Deploy to Azure App Service</h2>
<p>Ok now that we’ve created the resource group, let’s go ahead and create the Azure App Service. To do this, navigate back to the dashboard and click on Create a resource.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741772709338/2c353749-7e0a-42b0-894e-25b1f08cad15.png" alt="Azure dashboard" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741773327784/536358ff-241b-4ea1-876d-575abf12a27b.png" alt="Azure resources view" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p>You can search for Web App if you don’t see it in the list there. Then click on the Create Web App option:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741855971071/8c120d54-1df1-41f3-85b2-c03d9fd709f1.png" alt="Create a web app" class="image--center mx-auto" width="2398" height="1464" loading="lazy"></p>
<p>Here, select the resource group you created earlier, give the app a name, then select Container for the Publish option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741882867790/bed19e70-726d-4696-b88f-754e36511f0a.png" alt="Web app creation configuration" class="image--center mx-auto" width="2384" height="1476" loading="lazy"></p>
<p>Before you click on Create, go back to your dev workspace (VS Code or whatever IDE you are using) to push your Docker image to Docker Hub so you can add it there before proceeding to the next steps.</p>
<p>But why do you need to push to Docker Hub? Well, first of all, for accessibility – so we can easily share it with others or have other services access it (which is what we need here).</p>
<p>Remember how I compared Docker Hub with Github earlier? Docker Hub helps you host your Docker image on the internet and make it available for others or for various services on the internet to access if you make it public. Otherwise it’s limited to only authorized services.</p>
<p>To push the Docker image to Docker Hub, you first need to tag the Docker image with your Docker Hub username. Go to Docker <a target="_blank" href="https://hub.docker.com/">Docker Hub</a> to register and get your username if you don’t have one.</p>
<p>Run the following:</p>
<pre><code class="lang-bash">docker tag client_info_webservice-client_info_app:latest ayobami6/client_info_webservice-client_info_app:latest
<span class="hljs-comment"># this adds the latest tag to your docker image</span>
</code></pre>
<p>This shows that you successfully tagged your image with the latest tag.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741941521765/f624e0d1-2380-41cc-8bbf-f05e55d0b0ad.png" alt="Tagged Docker images" class="image--center mx-auto" width="2340" height="78" loading="lazy"></p>
<p>Before you actually push the image to Docker Hub, go ahead and login to it with the Docker CLI.</p>
<pre><code class="lang-bash">docker login <span class="hljs-comment"># this will prompt for browser authetication, for the prompt and login your account with your usernam and password</span>
</code></pre>
<p>Push the image to Docker Hub like this:</p>
<pre><code class="lang-bash">docker push ayobami6/client_info_webservice-client_info_app:latest
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741941723747/5947d1eb-82fe-4bf3-a0d7-e20bbc9d7de4.png" alt="Push Docker image to Docker Hub" class="image--center mx-auto" width="2358" height="130" loading="lazy"></p>
<p>You should see something like the below once you enter the push command on Docker Hub.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741941947561/7050ed8b-b7bf-4e07-91a6-765549b5d715.png" alt="Verify Docker image on Docker Hub" class="image--center mx-auto" width="2146" height="544" loading="lazy"></p>
<p>Alright, now that you have the Docker image on Docker Hub, you can go ahead and deploy it using Microsoft Azure App Service.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741944017329/32080357-e214-4864-b5cb-0fc8ad77a71f.png" alt="Create web container selection for publish" class="image--right mx-auto mr-0" width="2448" height="1722" loading="lazy"></p>
<p>Click on the container on the top menu bar to configure the container settings.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741944418747/6f9092e9-e6fc-4098-86d0-ba79eda37a58.png" alt="Container section of Azure web app" class="image--center mx-auto" width="2428" height="1284" loading="lazy"></p>
<p>Here, select Other container registries.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741944507676/d4c3d17e-e3fa-4c43-99b5-b768fd900309.png" alt="Other registry selection for Azure web app" class="image--center mx-auto" width="2418" height="1634" loading="lazy"></p>
<p>Select public, because your pushed image is public (meaning it’s publicly accessible over the internet).</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743071959687/48cc5a78-4b72-4c8f-9ffb-d32c065e1a63.jpeg" alt="Docker image access type selection" class="image--center mx-auto" width="1080" height="729" loading="lazy"></p>
<p>Add your Docker image and tag. You can get this when you run the command <code>docker images</code>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743072606918/d17f7a31-bee3-41b9-a685-d7de0c0f6b39.jpeg" alt="Image and tag selection" class="image--center mx-auto" width="1080" height="729" loading="lazy"></p>
<pre><code class="lang-bash">λ MACs-MacBook-Pro ~ → docker images
REPOSITORY                                        TAG         IMAGE ID       CREATED         SIZE
ayobami6/client_info_webservice-client_info_app   latest      a14f2a5b3bd4   2 weeks ago     30.8MB
postgres                                          13-alpine   236985828131   4 weeks ago     383MB
glint_pm_frontend-nextjs                          latest      424233ceaa4b   4 weeks ago     1.72GB
flask_app-flask_app                               latest      ff6ecfc4ba5a   5 weeks ago     203MB
nginx                                             latest      124b44bfc9cc   7 weeks ago     279MB
encoredotdev/postgres                             15          58b55b0e1fc7   10 months ago   878MB
λ MACs-MacBook-Pro ~ →
</code></pre>
<p>Copy the repository name and tag – in my case I have <code>ayobami6/client_info_webservice-client_info_app</code> and tag <code>latest</code> → <code>ayobami6/client_info_webservice-client_info_app:latest</code>.</p>
<p>Then add your startup command. If you are not using Go for the development like I am, your startup command will be different – so just use the command you added to your Docker compose command key, like so <code>command: "./api"</code>. Copy just the value (mine is .<code>/api</code>) don’t add the double quotes, and add it to the startup command.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1743072910308/a208c0a1-718b-4725-99b5-47bf33691fca.jpeg" alt="Add startup command to the web app container configuration" class="image--center mx-auto" width="1080" height="729" loading="lazy"></p>
<p>This start up command is the command that will start the application from the container and get the container running.</p>
<p>Click on review and create to create the service.</p>
<p>Once the deployment is complete you’ll be redirected here:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741944994364/31e051a6-2da1-46fa-a748-c2bdd20528be.png" alt="Web app overview" class="image--center mx-auto" width="2880" height="1634" loading="lazy"></p>
<p>Congratulations! You’ve successfully deployed your web service to Azure App Service. You can visit your app using the default domain from the overview. Mine is <a target="_blank" href="http://clientinfoapp-hdgcdmgjdyd5ecfy.canadacentral-01.azurewebsites.net">here</a>.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741945313388/19c73507-0b48-49ef-9885-515784cb0f9b.png" alt="Deployed service test on Postman" class="image--center mx-auto" width="1686" height="1376" loading="lazy"></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741945461019/30a668c7-0552-4905-bbb0-c9db0b587387.png" alt="Deployed service test on web browser" class="image--center mx-auto" width="1674" height="1514" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Deploying a RESTful web service on Microsoft Azure App Service is a powerful way to leverage cloud technology for scalable and efficient application hosting.</p>
<p>Understanding key terms like Docker, Docker Hub, and Azure Resource Groups will help you streamline the deployment process.</p>
<p>This guide walked you through creating a simple web service, building a Docker image, and deploying it on Azure. By following these steps, you can confidently deploy your applications, ensuring they are accessible and performant.</p>
<p>Thank you for following along, and I hope this tutorial has been insightful and helpful in your cloud deployment journey. If you found it useful, feel free to share it with others who might benefit from it. Happy coding and deploying!</p>
<p>Stay tuned for more insightful content, and let's continue learning and growing together. Cheers to building smarter, more efficient solutions with Azure.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How To Set Up TypeORM DataSource in Your NestJS Project ]]>
                </title>
                <description>
                    <![CDATA[ Hey there! 👋 Ever since I started working with NestJS, I've been looking for a reliable way to manage my database with TypeORM. Today, I'll share my journey and the steps I took to get it all set up. Alright, before we dive in, let's try to understa... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-setup-typeorm-datasource-nestjs-app/</link>
                <guid isPermaLink="false">66ba5a830013ba5d5012bca1</guid>
                
                    <category>
                        <![CDATA[ nestjs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Alaran Ayobami ]]>
                </dc:creator>
                <pubDate>Thu, 25 Apr 2024 11:22:53 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/hq720-1-1.jpg" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Hey there! 👋 Ever since I started working with NestJS, I've been looking for a reliable way to manage my database with TypeORM. Today, I'll share my journey and the steps I took to get it all set up.</p>
<p>Alright, before we dive in, let's try to understand what TypeORM and NestJS are.</p>
<h3 id="heading-table-of-contents">Table of contents:</h3>
<ul>
<li><a class="post-section-overview" href="#heading-what-is-typeorm">What is TypeORM?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-nestjs">What is NestJS?</a></li>
<li><a class="post-section-overview" href="#heading-tutorial-prerequisites">Tutorial Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-a-nestjs-project">How to Set Up a NestJS Project</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-typeorm-datasource-for-data-persistency">How to Set Up TypeORM DataSource for Data Persistency</a></li>
<li><a class="post-section-overview" href="#heading-extending-the-datasource-repository-for-custom-methods">Extending The DataSource Repository For Custom Methods</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
<li><a class="post-section-overview" href="#heading-resources">Resources</a></li>
</ul>
<h2 id="heading-what-is-typeorm">What is TypeORM?</h2>
<p>TypeORM is an <a target="_blank" href="https://www.freecodecamp.org/news/what-is-an-orm-the-meaning-of-object-relational-mapping-database-tools/">Object-Relational Mapping (ORM)</a> tool that simplifies working with databases in Node.js and TypeScript applications. It supports various databases like MySQL, PostgreSQL, SQLite, and more, allowing developers to use object-oriented programming concepts instead of dealing with low-level SQL queries. </p>
<p>TypeORM also provides features like schema migrations, query building, and managing relationships between tables.</p>
<h2 id="heading-what-is-nestjs">What is NestJS?</h2>
<p>NestJS is a progressive Node.js framework designed for building efficient, reliable, and scalable server-side applications. It leverages TypeScript's features to enable developers to write structured, maintainable code. </p>
<p>NestJS adopts a modular architecture pattern, allowing you to organize your code into modules, controllers, services, and providers. It provides built-in support for features like dependency injection, middleware, and GraphQL, making it a popular choice for building modern web applications and APIs. </p>
<p>Additionally, NestJS integrates seamlessly with other libraries and frameworks, including TypeORM, to streamline development workflows. Under the hood, it uses a robust HTTP server framework like Express (default) and can be configured to use other Node.js HTTP server frameworks. </p>
<p>Alright, that's a lot, right? Well, before we move on, let's try to break down the phrase, 'NestJS is a progressive Node.js framework,' which simply means that NestJS leverages the latest features of the JavaScript language and server frameworks, thereby providing flexibility for developers to write code in the most suitable language for their projects.<a target="_blank" href="https://docs.nestjs.com/">(Source)</a></p>
<h2 id="heading-tutorial-prerequisites">Tutorial Prerequisites</h2>
<ul>
<li>Node.js. At least version 18</li>
<li>npm. Atleast Version 8</li>
<li>Postgresql. <a target="_blank" href="https://www.postgresql.org/download/">Download Here</a> </li>
<li>Basic familiarity with Typescirpt and Nestjs</li>
<li>Pgadmin 4. <a target="_blank" href="https://www.pgadmin.org/download">Download Here</a></li>
</ul>
<h2 id="heading-how-to-set-up-a-nestjs-project">How to Set Up a NestJS Project</h2>
<p>Run the following commands to install your NestJS project:</p>
<pre><code class="lang-bash">npm i -g @nestjs/cli <span class="hljs-comment"># install nestj cli globally</span>
nest new simple-crm <span class="hljs-comment"># start a new nestjs project</span>
</code></pre>
<p>After installation, run the development server:</p>
<pre><code class="lang-bash">npm run start:dev <span class="hljs-comment"># start the app in watch mode</span>
</code></pre>
<p>Now, let's test our project to see if the <code>nest-cli</code> has properly set up all boiler plate code, by sending a get request to the root URL /</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_18-1.png" alt="init_test" width="600" height="400" loading="lazy">
_init<em>test</em></p>
<p>Nice! Our project is up and running.</p>
<h3 id="heading-how-to-set-up-typeorm-datasource-for-data-persistency">How to Set Up TypeORM DataSource for Data Persistency</h3>
<pre><code class="lang-bash">npm install --save @nestjs/typeorm typeorm <span class="hljs-comment"># nestjs typeorm drivers</span>
npm install --save pg <span class="hljs-comment"># typeorm postgressql driver</span>
</code></pre>
<p>Let's create the database for the project from Pgadmin 4 interface</p>
<p>Open the Pgadmin 4 interface and right click on the Databases tab to create new database, like so 👇.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_18-2.png" alt="create_db-1" width="600" height="400" loading="lazy">
_create<em>db-1</em></p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_18-3.png" alt="create_db-2" width="600" height="400" loading="lazy">
_create<em>db-2</em></p>
<p>Confirm your database has been created successfully.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_18-4.png" alt="confirm_db" width="600" height="400" loading="lazy">
_confirm<em>db</em></p>
<p>Great, it's time to add the database to our NestJS app using TypeORM.</p>
<p>Create new folder, <strong>datasource</strong> in the <strong>src/</strong> folder of your app, like so 👇</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_18-5.png" alt="datasource_folder" width="600" height="400" loading="lazy">
_confirm<em>folder</em></p>
<p>Create a  new file <strong>typeorm.module.ts</strong>, in the <strong>datasource</strong> folder, and add the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { DataSource } <span class="hljs-keyword">from</span> <span class="hljs-string">'typeorm'</span>;
<span class="hljs-keyword">import</span> { Global, Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;

<span class="hljs-meta">@Global</span>() <span class="hljs-comment">// makes the module available globally for other modules once imported in the app modules</span>
<span class="hljs-meta">@Module</span>({
  imports: [],
  providers: [
    {
      provide: DataSource, <span class="hljs-comment">// add the datasource as a provider</span>
      inject: [],
      useFactory: <span class="hljs-keyword">async</span> () =&gt; {
        <span class="hljs-comment">// using the factory function to create the datasource instance</span>
        <span class="hljs-keyword">try</span> {
          <span class="hljs-keyword">const</span> dataSource = <span class="hljs-keyword">new</span> DataSource({
            <span class="hljs-keyword">type</span>: <span class="hljs-string">'postgres'</span>,
            host: <span class="hljs-string">'localhost'</span>,
            port: <span class="hljs-number">5432</span>,
            username: <span class="hljs-string">'ayo'</span>,
            password: <span class="hljs-string">'haywon'</span>,
            database: <span class="hljs-string">'simple-crm_db'</span>,
            synchronize: <span class="hljs-literal">true</span>,
            entities: [<span class="hljs-string">`<span class="hljs-subst">${__dirname}</span>/../**/**.entity{.ts,.js}`</span>], <span class="hljs-comment">// this will automatically load all entity file in the src folder</span>
          });
          <span class="hljs-keyword">await</span> dataSource.initialize(); <span class="hljs-comment">// initialize the data source</span>
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Database connected successfully'</span>);
          <span class="hljs-keyword">return</span> dataSource;
        } <span class="hljs-keyword">catch</span> (error) {
          <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Error connecting to database'</span>);
          <span class="hljs-keyword">throw</span> error;
        }
      },
    },
  ],
  <span class="hljs-built_in">exports</span>: [DataSource],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> TypeOrmModule {}
</code></pre>
<p>Add the TypeORM module to the App module imports array, like so 👇</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { AppController } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.controller'</span>;
<span class="hljs-keyword">import</span> { AppService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.service'</span>;
<span class="hljs-keyword">import</span> { TypeOrmModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./datasource/typeorm.module'</span>;

<span class="hljs-meta">@Module</span>({
  imports: [TypeOrmModule],
  controllers: [AppController],
  providers: [AppService],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> AppModule {}
</code></pre>
<p>Then save and confirm from your console if the database has been connected successfully.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_19-1.png" alt="db_conn_success" width="600" height="400" loading="lazy">
_show_db_success<em>conn</em></p>
<p>If you see the database connected successfully, good job! Otherwise, go back to the previous steps to see if you followed the configurations correctly.</p>
<p>Now, we can continue to consume our <code>datasource</code> service leveraging the TypeORM.</p>
<p>Let's create <code>users</code> module, controller, provider and entity to interact with our newly connected database.</p>
<pre><code class="lang-bash">nest g module users &amp;&amp; nest g service users &amp;&amp; nest g controller users
</code></pre>
<p>The above command will generate the <code>users</code> module, service and controller and update the <strong>app.module.ts</strong> with the <code>users</code> module.</p>
<p>Add the following code inside the <strong>users.entity.ts</strong> file and restart your development server to create the <code>user</code> table in the database.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Column, Entity, PrimaryGeneratedColumn } <span class="hljs-keyword">from</span> <span class="hljs-string">'typeorm'</span>;

<span class="hljs-meta">@Entity</span>(<span class="hljs-string">'user'</span>)
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> UserEntity {
  <span class="hljs-meta">@PrimaryGeneratedColumn</span>()
  id: <span class="hljs-built_in">number</span>;

  <span class="hljs-meta">@Column</span>({ unique: <span class="hljs-literal">true</span> })
  username: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@Column</span>()
  password: <span class="hljs-built_in">string</span>;
}
</code></pre>
<p>Check your Pgadmin 4 interface and confirm that TypeORM has automatically loaded the <code>UserEntity</code> and created the <code>user</code> table in your database, like so 👇.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_19-2.png" alt="confirm_user_table" width="600" height="400" loading="lazy">
_confirm_user<em>table</em></p>
<p>You might want to refresh the database if you don't see it at first.</p>
<p>Now let's implement our first <code>users</code> service handler, add the following code to your <strong>users.service.ts</strong> file:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> {
  HttpException,
  HttpStatus,
  Injectable,
  InternalServerErrorException,
  Logger,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { DataSource } <span class="hljs-keyword">from</span> <span class="hljs-string">'typeorm'</span>;
<span class="hljs-keyword">import</span> { UserEntity } <span class="hljs-keyword">from</span> <span class="hljs-string">'./users.entity'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> CreateUser {
  username: <span class="hljs-built_in">string</span>;
  password: <span class="hljs-built_in">string</span>;
}

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> UsersService {
  <span class="hljs-keyword">private</span> userRepository;
  <span class="hljs-keyword">private</span> logger = <span class="hljs-keyword">new</span> Logger();
  <span class="hljs-comment">//   inject the Datasource provider</span>
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> dataSource: DataSource</span>) {
    <span class="hljs-comment">// get users table repository to interact with the database</span>
    <span class="hljs-built_in">this</span>.userRepository = <span class="hljs-built_in">this</span>.dataSource.getRepository(UserEntity);
  }
  <span class="hljs-comment">//  create handler to create new user and save to the database</span>
  <span class="hljs-keyword">async</span> createUser(createUser: CreateUser): <span class="hljs-built_in">Promise</span>&lt;UserEntity&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.userRepository.create(createUser);
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.userRepository.save(user);
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-keyword">if</span> (err.code == <span class="hljs-number">23505</span>) {
        <span class="hljs-built_in">this</span>.logger.error(err.message, err.stack);
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> HttpException(<span class="hljs-string">'Username already exists'</span>, HttpStatus.CONFLICT);
      }
      <span class="hljs-built_in">this</span>.logger.error(err.message, err.stack);
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InternalServerErrorException(
        <span class="hljs-string">'Something went wrong, Try again!'</span>,
      );
    }
  }
}
</code></pre>
<p>We've added the <code>createUser</code> method to handle creating a user when a POST request is sent with the required request body to the endpoint controller that utilizes the <code>createUser</code> service method. </p>
<p>The function takes an object <code>createUser</code> as an argument of type <code>CreateUser</code> interface. Usually, this should be a DTO (Data Transfer Object) for the data type structure and validation, but since it is out of the scope of this tutorial, we're using the interface just for the data shape. </p>
<p>We called the <code>create</code> method of the <code>userRepository</code> then assigned it's return to the <code>user</code> variable to hold the newly created user object. We then called the <code>save</code> method to save the object to the database.</p>
<p>Now, let's utilize the <code>createUser</code> service handler in our <code>users</code> controller that handles the POST request to create new user.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { Body, Controller, Post } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { CreateUser, UsersService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./users.service'</span>;

<span class="hljs-meta">@Controller</span>(<span class="hljs-string">'users'</span>)
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> UsersController {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> userService: UsersService</span>) {}

  <span class="hljs-meta">@Post</span>(<span class="hljs-string">'/create'</span>)
  <span class="hljs-comment">//   handles the post request to /users/create endpoint to create new user</span>
  <span class="hljs-keyword">async</span> signUp(<span class="hljs-meta">@Body</span>() user: CreateUser) {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.userService.createUser(user);
  }
}
</code></pre>
<p>Test the newly created endpoint, by sending a POST request to <code>http://localhost:3000/users/create</code> with the username and password as the request body.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_19-3.png" alt="test_user_create" width="600" height="400" loading="lazy">
_test_user_create<em>endpoint</em></p>
<p>Alright, let's check the database just to be sure that's all, because we already got a 201 response status code which should be enough to know that our application is smoothly interacting with our database using the TypeORM Datasource.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_19-4.png" alt="confirm_user_db" width="600" height="400" loading="lazy">
_confirm_user<em>db</em></p>
<h3 id="heading-extending-the-datasource-repository-for-custom-methods">Extending The DataSource Repository For Custom Methods</h3>
<p>Whether you're looking to optimize database queries, introduce new data manipulation operations, or integrate with third-party services, extending the DataSource repository with custom methods can be a game-changer interacting with the database seamlessly. </p>
<p>Here, we'll explore the benefits of custom methods, and provide a step-by-step guide to implementing them in your NestJS applications. So, let's dive in and unlock the full potential of the DataSource repository!</p>
<p>Some of the basic benefits of repository custom methods are:</p>
<p><strong>Tailored Functionality:</strong> Custom methods allow developers to introduce specific functionalities that are not available in the standard DataSource repository. By tailoring the DataSource repository with custom methods, developers can address unique use cases, data manipulation operations and aggregations, or optimizations that are essential for their project requirements.</p>
<p><strong>Optimized Performance:</strong> Custom methods can be designed to optimize database queries, data retrieval, and data manipulation operations, leading to improved performance and efficiency. By leveraging custom methods, developers can implement optimized algorithms, caching mechanisms, or query optimizations tailored to the specific needs and characteristics of their applications.</p>
<p><strong>Improved Code Reusability and Maintainability:</strong> Custom methods promote code reusability by encapsulating specific logic, algorithms, or operations within reusable components. By modularizing the custom methods, developers can maintain cleaner, more organized, and maintainable codebases, making it easier to manage, debug, and enhance the DataSource repository in the long run.</p>
<p>Ok, That's that, let's move to the action. So, we have a simple CRM application that has to do with user management. Let's add a custom repository method that can help us filter users by username.</p>
<p>To implement this, let's create our <code>datasource</code> module and <code>datasource</code> service. We're going to create these files to to align with the modularity principles of the NestJS architectural pattern.</p>
<p>Create the files inside your previously created <strong>datasource</strong> folder and add the following code:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// datasource.module.ts</span>
<span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { TypeOrmModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./typeorm.module'</span>;
<span class="hljs-keyword">import</span> { DataSourceService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./datasource.service'</span>;

<span class="hljs-meta">@Module</span>({
  imports: [TypeOrmModule],
  providers: [DataSourceService],
  <span class="hljs-built_in">exports</span>: [DataSourceService],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DataSourceModule {}
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// datasource.service.ts</span>
<span class="hljs-keyword">import</span> { Injectable } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { UserEntity } <span class="hljs-keyword">from</span> <span class="hljs-string">'src/users/users.entity'</span>;
<span class="hljs-keyword">import</span> { DataSource } <span class="hljs-keyword">from</span> <span class="hljs-string">'typeorm'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> UsernameQuery {
  username: <span class="hljs-built_in">string</span>;
}

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> DataSourceService {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> dataSource: DataSource</span>) {}

  <span class="hljs-comment">//   extend userRepository to add custom methods</span>
  userCustomRepository = <span class="hljs-built_in">this</span>.dataSource.getRepository(UserEntity).extend({
    <span class="hljs-keyword">async</span> filterUser(usernameQuery: UsernameQuery): <span class="hljs-built_in">Promise</span>&lt;UserEntity[]&gt; {
      <span class="hljs-keyword">const</span> { username } = usernameQuery;
      <span class="hljs-built_in">console</span>.log(username);
      <span class="hljs-comment">// initialize a query builder for the userrepository</span>
      <span class="hljs-keyword">const</span> query = <span class="hljs-built_in">this</span>.createQueryBuilder(<span class="hljs-string">'user'</span>);
      <span class="hljs-comment">//   filter user where username is like the passed username</span>
      query.where(<span class="hljs-string">'(LOWER(user.username) LIKE LOWER(:username))'</span>, {
        username: <span class="hljs-string">`%<span class="hljs-subst">${username}</span>%`</span>,
      });
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> query.getMany();
    },
  });
}
</code></pre>
<p>From the above <strong>datasource.service.ts</strong> code, we've extended the <code>UserRepository</code>, by calling the <code>getRepository</code> method on the <code>dataSource</code> service and passing <code>UserEntity</code> as an argument to get the repository for the particular table.</p>
<p>Then we called the <code>extend</code> method on the <code>userRepository</code> we got back from our <code>getRepository</code> to add our custom method. In our <code>extend</code> method, we passed an object that will contain all our custom methods for the custom repository we've assigned to the <code>userCustomRepository</code>.  Here, we've simply added just one custom method to our custom user repository which is <code>filterUser</code>. It runs a filter query on the user table by the username provided.</p>
<p>Since our <code>DataSourseService</code> is an injectable, we can inject it in our <code>UserService</code> and consume the newly created <code>filterUser</code> method after adding the <code>DataSourceModule</code> to the imports array of the user module like so 👇</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// users.module.ts</span>
<span class="hljs-keyword">import</span> { Module } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { UsersController } <span class="hljs-keyword">from</span> <span class="hljs-string">'./users.controller'</span>;
<span class="hljs-keyword">import</span> { UsersService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./users.service'</span>;
<span class="hljs-keyword">import</span> { DataSourceModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'src/datasource/datasource.module'</span>;

<span class="hljs-meta">@Module</span>({
  imports: [DataSourceModule], <span class="hljs-comment">// add the DataSourceModule to the import array </span>
  providers: [UsersService],
  controllers: [UsersController],
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> UsersModule {}
</code></pre>
<p>Let's consume the filter method from <code>CustomUserRepository</code> in our <code>UserService</code> to filter users by any username passed as our query argument when sending the request.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// users.service.ts</span>
<span class="hljs-keyword">import</span> {
  HttpException,
  HttpStatus,
  Injectable,
  InternalServerErrorException,
  Logger,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { DataSource } <span class="hljs-keyword">from</span> <span class="hljs-string">'typeorm'</span>;
<span class="hljs-keyword">import</span> { UserEntity } <span class="hljs-keyword">from</span> <span class="hljs-string">'./users.entity'</span>;
<span class="hljs-keyword">import</span> {
  DataSourceService,
  UsernameQuery,
} <span class="hljs-keyword">from</span> <span class="hljs-string">'src/datasource/datasource.service'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">interface</span> CreateUser {
  username: <span class="hljs-built_in">string</span>;
  password: <span class="hljs-built_in">string</span>;
}

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> UsersService {
  <span class="hljs-keyword">private</span> userRepository;
  <span class="hljs-keyword">private</span> customUserRepository;
  <span class="hljs-keyword">private</span> logger = <span class="hljs-keyword">new</span> Logger();
  <span class="hljs-comment">//   inject the Datasource provider</span>
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">
    <span class="hljs-keyword">private</span> dataSource: DataSource,
    <span class="hljs-keyword">private</span> dataSourceService: DataSourceService, <span class="hljs-comment">// inject our datasource service</span>
  </span>) {
    <span class="hljs-comment">// get users table repository to interact with the database</span>
    <span class="hljs-built_in">this</span>.userRepository = <span class="hljs-built_in">this</span>.dataSource.getRepository(UserEntity);
    <span class="hljs-comment">// assigning the dataSourceService userCustomRepository to the class customUserRepository</span>
    <span class="hljs-built_in">this</span>.customUserRepository = <span class="hljs-built_in">this</span>.dataSourceService.userCustomRepository;
  }
  <span class="hljs-comment">//  create handler to create new user and save to the database</span>
  <span class="hljs-keyword">async</span> createUser(createUser: CreateUser): <span class="hljs-built_in">Promise</span>&lt;UserEntity&gt; {
    <span class="hljs-keyword">try</span> {
      <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.userRepository.create(createUser);
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.userRepository.save(user);
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-keyword">if</span> (err.code == <span class="hljs-number">23505</span>) {
        <span class="hljs-built_in">this</span>.logger.error(err.message, err.stack);
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> HttpException(<span class="hljs-string">'Username already exists'</span>, HttpStatus.CONFLICT);
      }
      <span class="hljs-built_in">this</span>.logger.error(err.message, err.stack);
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InternalServerErrorException(
        <span class="hljs-string">'Something went wrong, Try again!'</span>,
      );
    }
  }
  <span class="hljs-comment">// the userService filterByUsername handler</span>
  <span class="hljs-keyword">async</span> filterByUsername(usernameQuery: UsernameQuery): <span class="hljs-built_in">Promise</span>&lt;UserEntity[]&gt; {
    <span class="hljs-keyword">try</span> {
    <span class="hljs-comment">// calling the customUserRepository filterUser custom method</span>
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.customUserRepository.filterUser(usernameQuery);
    } <span class="hljs-keyword">catch</span> (err) {
      <span class="hljs-built_in">this</span>.logger.error(err.message, err.stack);
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InternalServerErrorException(
        <span class="hljs-string">'Something went wrong, Try again!'</span>,
      );
    }
  }
}
</code></pre>
<p>From the above, code we've injected our custom <code>DataSourceService</code> by adding the following to the class constructor <code>private dataSourceService: DataSourceService,</code>.</p>
<p>The <code>filterByUsername</code> service handles the request we consume in our custom <code>filterUser</code> method <code>await _this_.customUserRepository.filterUser(usernameQuery);</code>, which will return a promise.</p>
<p>Now, let's utilize this service handler in our user controller to filter users by their username.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// users.controller.ts</span>
<span class="hljs-keyword">import</span> { Body, Controller, Get, Post, Query } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { CreateUser, UsersService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./users.service'</span>;
<span class="hljs-keyword">import</span> { UserEntity } <span class="hljs-keyword">from</span> <span class="hljs-string">'./users.entity'</span>;
<span class="hljs-keyword">import</span> { UsernameQuery } <span class="hljs-keyword">from</span> <span class="hljs-string">'src/datasource/datasource.service'</span>;

<span class="hljs-meta">@Controller</span>(<span class="hljs-string">'users'</span>)
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> UsersController {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> userService: UsersService</span>) {}

  <span class="hljs-meta">@Post</span>(<span class="hljs-string">'/create'</span>)
  <span class="hljs-comment">//   handles the post request to /users/create endpoint to create new user</span>
  <span class="hljs-keyword">async</span> signUp(<span class="hljs-meta">@Body</span>() user: CreateUser): <span class="hljs-built_in">Promise</span>&lt;UserEntity&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.userService.createUser(user);
  }

  <span class="hljs-meta">@Get</span>(<span class="hljs-string">''</span>) <span class="hljs-comment">// get request handler that returns the filtered results of the users table</span>
  <span class="hljs-keyword">async</span> filterUser(
    <span class="hljs-meta">@Query</span>() usernameQuery: UsernameQuery <span class="hljs-comment">// extracts the username query param for the endpoint url,</span>
  ): <span class="hljs-built_in">Promise</span>&lt;UserEntity[]&gt; {
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.userService.filterByUsername(usernameQuery);
  }
}
</code></pre>
<p>Test our filter endpoint,</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Screenshot_2024_04_19-5.png" alt="test-filter" width="600" height="400" loading="lazy">
_test_filter<em>endpoint</em></p>
<p>Here, we got back a list with one user object with username like the username we passed as a query.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Voila! That's it, now you ready to start working with NestJS, TypeORM, and DataSource.</p>
<p>Thanks for reading!</p>
<p>If you've found it helpful, please share it with your friends and colleagues! Stay tuned for more insightful content, and let's continue learning and growing together. Cheers to building smarter, more efficient solutions with NestJS!</p>
<h3 id="heading-resources">Resources</h3>
<ul>
<li><a target="_blank" href="https://docs.nestjs.com/">NestJS Docs Page</a> </li>
<li><a target="_blank" href="https://typeorm.io/">TypeORM Docs Page</a></li>
<li><a target="_blank" href="https://www.youtube.com/watch?v=sFnAHC9lLaw&amp;t=935s">Learn NestJS Complete Course</a></li>
</ul>
<h3 id="heading-contact-links">Contact Links</h3>
<ul>
<li><a target="_blank" href="https://twitter.com/ayobamialaran">Twitter</a></li>
<li><a target="_blank" href="https://www.linkedin.com/in/ayobami-alaran/">LinkedIn</a></li>
<li><a target="_blank" href="https://github.com/Ayobami6">GitHub</a></li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
