<?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[ Isaiah Clifford Opoku - 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[ Isaiah Clifford Opoku - freeCodeCamp.org ]]>
            </title>
            <link>https://www.freecodecamp.org/news/</link>
        </image>
        <generator>Eleventy</generator>
        <lastBuildDate>Sun, 24 May 2026 16:29:45 +0000</lastBuildDate>
        <atom:link href="https://www.freecodecamp.org/news/author/Clifftech/rss.xml" rel="self" type="application/rss+xml" />
        <ttl>60</ttl>
        
            <item>
                <title>
                    <![CDATA[ How to Get Started with ASP.NET Core and gRPC: A Handbook for Developers ]]>
                </title>
                <description>
                    <![CDATA[ In today's distributed computing landscape, efficient service-to-service communication is crucial for building scalable, high-performance applications. gRPC (Google Remote Procedure Call) has emerged as one of the most powerful frameworks for creatin... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/get-started-with-aspnet-core-and-grpc-handbook/</link>
                <guid isPermaLink="false">689ca3344cac10c21b1f670c</guid>
                
                    <category>
                        <![CDATA[ .NET ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Csharhp ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Wed, 13 Aug 2025 14:37:40 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1755043329753/f5ff4a61-79b7-44f0-9871-9dfef9f8d08a.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>In today's distributed computing landscape, efficient service-to-service communication is crucial for building scalable, high-performance applications. gRPC (Google Remote Procedure Call) has emerged as one of the most powerful frameworks for creating robust, type-safe APIs that can handle thousands of requests per second with minimal latency.</p>
<p>gRPC is a modern, open-source RPC framework that leverages HTTP/2, Protocol Buffers, and advanced streaming capabilities to deliver exceptional performance. Unlike traditional REST APIs, gRPC offers strongly-typed contracts, automatic code generation, and built-in support for multiple programming languages. This makes it an ideal choice for microservices architectures and cross-platform development.</p>
<p>In this handbook, I’ll take you on a journey from absolute beginner to building production-ready gRPC services with <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core. Whether you're migrating from REST APIs or starting fresh with gRPC, this guide will provide you with practical, hands-on experience and real-world examples.</p>
<p><strong>What you'll learn:</strong></p>
<ul>
<li><p>How to set up your first gRPC service in .NET</p>
</li>
<li><p>How to define service contracts with Protocol Buffers</p>
</li>
<li><p>How to implement unary, server streaming, and client streaming operations</p>
</li>
<li><p>How to build CRUD (Create, Read, Update, Delete) operations</p>
</li>
</ul>
<p>Let's dive in and discover how gRPC can revolutionize your API development experience!</p>
<p>You can find all the code in this <a target="_blank" href="https://github.com/Clifftech123/IsaiahCliffordOpokuBlog"><strong>GitHub Repository</strong></a><strong>.</strong></p>
<h3 id="heading-table-of-contents">Table of Contents</h3>
<ol>
<li><p><a class="post-section-overview" href="#heading-grpc-overview-and-how-it-works-with-net">gRPC Overview and How It Works with .NET</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-grpc-with-net">How to Set Up gRPC with .NET</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-the-product-model">How to Create the Product Model</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-set-up-the-sqlite-database">How to Set Up the SQLite Database</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-product-protocol-buffers">How to Create Product Protocol Buffers</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-crud-operations-services-with-grpc">How to Implement CRUD Operations Services with gRPC</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-implement-grpc-crud-database-operations-with-sqlite">How to Implement gRPC CRUD Database Operations With SQLite</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-test-grpc-services-with-postman">How to Test gRPC Services with Postman</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-test-product-creation">How to Test Product Creation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-test-all-product-operations">How to Test All Product Operations</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h3 id="heading-perquisites">Perquisites</h3>
<p>Before we start, make sure you have the following installed:</p>
<ul>
<li><p><a target="_blank" href="https://dotnet.microsoft.com/download">.NET SDK</a></p>
</li>
<li><p><a target="_blank" href="https://code.visualstudio.com/download">Visual Studio Code</a></p>
</li>
<li><p><a target="_blank" href="https://www.postman.com/downloads/">Postman</a></p>
</li>
</ul>
<h2 id="heading-grpc-overview-and-how-it-works-with-net">gRPC Overview and How It Works with .NET</h2>
<p>gRPC is a high-performance, cross-platform framework that works seamlessly with many technologies, including .NET Core.</p>
<h3 id="heading-why-choose-grpc-with-net">Why choose gRPC with .NET?</h3>
<p>There are many reasons why this is a good combination. First, of all, this combo is up to 8x faster than using REST APIs with JSON. Its strongly-typed contracts also help prevent runtime errors.</p>
<p>It also has built-in support for client, server, and bidirectional streaming, as well as seamless integration across different languages and platforms. Finally, it leverages HTTP/2 for multiplexing and header compression – so as you can see, these two tools are a super effective pair.</p>
<p>To understand in more detail why gRPC is so valuable, let's explore a common real-world scenario.</p>
<h3 id="heading-the-challenge-microservices-communication">The Challenge: Microservices Communication</h3>
<p>Imagine you're building a large e-commerce application. For better maintainability and scalability, you decide to split your monolithic application into smaller, focused services:</p>
<ul>
<li><p><strong>Product Service</strong> – Handles product catalog, inventory, and product management</p>
</li>
<li><p><strong>Authentication Service</strong> – Manages user authentication, authorization, and user profiles</p>
</li>
</ul>
<p>These services need to communicate with each other frequently. For example, before a user can add a product to their cart, the Product Service must verify with the Authentication Service that the user is logged in and has the proper permissions.</p>
<h3 id="heading-traditional-approach-http-rest-apis">Traditional Approach: HTTP REST APIs</h3>
<p>Traditionally, in .NET applications, we solve this inter-service communication using <code>HttpClient</code> to make REST API calls between services. While this works, it comes with several challenges:</p>
<ul>
<li><p>Network failures: API calls can fail unexpectedly, even when everything appears correct</p>
</li>
<li><p>Performance bottlenecks: JSON serialization/deserialization adds overhead</p>
</li>
<li><p>Slow response times: HTTP/1.1 limitations affect performance under high load</p>
</li>
<li><p>Type safety: No compile-time contract validation between services</p>
</li>
<li><p>Verbose payloads: JSON can be bulky compared to binary formats</p>
</li>
</ul>
<h3 id="heading-the-grpc-solution">The gRPC Solution</h3>
<p>This is where gRPC shines. It addresses these challenges by providing some really helpful features in addition to the ones we’ve already discussed above like protocol buffers, code generation for client and server, and more.</p>
<h3 id="heading-when-to-use-grpc-in-net">When to Use gRPC in .NET</h3>
<p>gRPC is particularly beneficial in certain scenarios, but it’s not a great choice in others. Here are some example use cases, as well as some to avoid:</p>
<p><strong>✅ Perfect for:</strong></p>
<ul>
<li><p><strong>Microservices architecture</strong>: High-frequency service-to-service communication</p>
</li>
<li><p><strong>Real-time applications</strong>: Chat applications, live updates, gaming</p>
</li>
<li><p><strong>High-performance APIs</strong>: When speed and efficiency are critical</p>
</li>
<li><p><strong>Polyglot environments</strong>: Services written in different programming languages</p>
</li>
<li><p><strong>Internal APIs</strong>: Backend services that don't need browser compatibility</p>
</li>
</ul>
<p><strong>❌ Consider Alternatives When:</strong></p>
<ul>
<li><p><strong>Browser-based applications</strong>: Limited browser support (use gRPC-Web instead)</p>
</li>
<li><p><strong>Public APIs</strong>: REST might be more familiar to external developers</p>
</li>
<li><p><strong>Simple CRUD operations</strong>: Where REST's simplicity is sufficient</p>
</li>
<li><p><strong>Legacy system integration</strong>: When existing systems only support HTTP/1.1</p>
</li>
</ul>
<h3 id="heading-grpc-vs-rest-a-quick-comparison">gRPC vs REST: A Quick Comparison</h3>
<p>Here’s a quick side-by-side comparison of their main features:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>gRPC</td><td>REST</td></tr>
</thead>
<tbody>
<tr>
<td>Protocol</td><td>HTTP/2</td><td>HTTP/1.1</td></tr>
<tr>
<td>Data Format</td><td>Protocol Buffers (Binary)</td><td>JSON (Text)</td></tr>
<tr>
<td>Performance</td><td>High</td><td>Moderate</td></tr>
<tr>
<td>Browser Support</td><td>Limited (needs gRPC-Web)</td><td>Full</td></tr>
<tr>
<td>Streaming</td><td>Built-in</td><td>Limited</td></tr>
<tr>
<td>Code Generation</td><td>Automatic</td><td>Manual</td></tr>
</tbody>
</table>
</div><p>In this handbook, we'll build a complete Product Management system using gRPC with .NET, demonstrating how to implement efficient service-to-service communication with full CRUD operations.</p>
<h2 id="heading-how-to-set-up-grpc-with-net">How to Set Up gRPC with .NET</h2>
<p>In this tutorial, we'll use Visual Studio Code to build our complete gRPC application. Let's start by creating a new gRPC project using the .NET CLI.</p>
<h3 id="heading-creating-your-first-grpc-project">Creating Your First gRPC Project</h3>
<p>Start by opening your terminal (you can use VS Code's integrated terminal or your system terminal) and navigate to your desired directory where you want to create the project.</p>
<p>Run the following command to create a new gRPC project:</p>
<pre><code class="lang-bash">dotnet new grpc -o ProductGrpc
</code></pre>
<p><strong>What this command does:</strong></p>
<ul>
<li><p><code>dotnet new grpc</code> creates a new project using the gRPC template</p>
</li>
<li><p><code>-o ProductGrpc</code> specifies the output directory name for our project</p>
</li>
</ul>
<p>Next, navigate into the project directory:</p>
<pre><code class="lang-bash"><span class="hljs-built_in">cd</span> ProductGrpc
</code></pre>
<p>Then open the project in Visual Studio Code:</p>
<pre><code class="lang-bash">code .
</code></pre>
<h3 id="heading-understanding-the-project-structure">Understanding the Project Structure</h3>
<p>After running the command, you should see output similar to the following in your terminal, confirming that the project was created successfully:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753873861602/6d135358-2065-40eb-9fe9-9a58bd8dc2eb.png" alt="Vs Code  Initial  Project Structure" width="1971" height="987" loading="lazy"></p>
<p>Let's explore what the .NET gRPC template has generated for us:</p>
<pre><code class="lang-makefile">ProductGrpc/
├── Protos/
│   └── greet.proto          <span class="hljs-comment"># Protocol Buffer definition file</span>
├── Services/
│   └── GreeterService.cs    <span class="hljs-comment"># Sample gRPC service implementation</span>
├── Program.cs               <span class="hljs-comment"># Application entry point</span>
├── ProductGrpc.csproj       <span class="hljs-comment"># Project file</span>
└── appsettings.json         <span class="hljs-comment"># Configuration file</span>
</code></pre>
<p>Key files:</p>
<ul>
<li><p><code>Protos/greet.proto</code>: Defines the service contract using Protocol Buffers</p>
</li>
<li><p><code>Services/GreeterService.cs</code>: Contains the actual service implementation</p>
</li>
<li><p><code>Program.cs</code>: Configures and starts the gRPC server</p>
</li>
<li><p><code>ProductGrpc.csproj</code>: Contains project dependencies and build settings</p>
</li>
</ul>
<h3 id="heading-verifying-the-setup">Verifying the Setup</h3>
<p>Let's make sure everything is working correctly by running the default application:</p>
<pre><code class="lang-yaml"><span class="hljs-string">dotnet</span> <span class="hljs-string">run</span>
</code></pre>
<p>You should see output indicating that the gRPC server is running:</p>
<pre><code class="lang-json">info: Microsoft.Hosting.Lifetime[<span class="hljs-number">14</span>]
      Now listening on: https:<span class="hljs-comment">//localhost:7042</span>
info: Microsoft.Hosting.Lifetime[<span class="hljs-number">0</span>]
      Application started. Press Ctrl+C to shut down.
</code></pre>
<p><strong>🎉 Congratulations!</strong> You've successfully created your first gRPC application using the .NET CLI. The server is now running and ready to accept gRPC requests.</p>
<p>Let's move on to the next section, where we'll start building our Product Management system.</p>
<h2 id="heading-how-to-create-the-product-model">How to Create the Product Model</h2>
<p>Now that we have our gRPC project set up, let's create our Product model. In .NET applications, models represent the data structure and business entities that our application will work with. Think of models as blueprints that define what properties our data objects should have.</p>
<h3 id="heading-understanding-models-in-grpc-applications">Understanding Models in gRPC Applications</h3>
<p>Models serve several important purposes:</p>
<ul>
<li><p><strong>Data structure</strong>: They define the shape and properties of our business entities.</p>
</li>
<li><p><strong>Type safety</strong>: They ensure compile-time validation of our data.</p>
</li>
<li><p><strong>Business logic</strong>: They represent real-world objects in our application.</p>
</li>
<li><p><strong>Database mapping</strong>: They serve as entities for database operations.</p>
</li>
</ul>
<h3 id="heading-creating-the-models-folder">Creating the Models Folder</h3>
<p>Let’s organize our code by creating a dedicated folder for our models called <code>Models</code> in your project root directory.</p>
<p>Inside the Models folder, create a new file called <code>Product.cs</code>.</p>
<p>Your project structure should now look like this:</p>
<pre><code class="lang-yaml"><span class="hljs-string">ProductGrpc/</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Models/</span>
<span class="hljs-string">│</span>   <span class="hljs-string">└──</span> <span class="hljs-string">Product.cs</span>           <span class="hljs-comment"># Our new Product model</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Protos/</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Services/</span>
<span class="hljs-string">└──</span> <span class="hljs-string">...</span>
</code></pre>
<h3 id="heading-implementing-the-product-model">Implementing the Product Model</h3>
<p>Add the following code to your <code>Product.cs</code> file:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Models/Product.cs</span>
<span class="hljs-keyword">using</span> System.ComponentModel.DataAnnotations;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">ProductGrpc.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Product</span>
    {

        <span class="hljs-keyword">public</span> Guid Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> required <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> required <span class="hljs-keyword">string</span> Description { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">decimal</span> Price { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

        <span class="hljs-keyword">public</span> DateTime Created { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = DateTime.UtcNow;

        <span class="hljs-keyword">public</span> DateTime Updated { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; } = DateTime.UtcNow;
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span>? Tags { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Modern C# features:</p>
<ul>
<li><p><code>required</code> keyword: Ensures properties must be initialized when creating an object</p>
</li>
<li><p><code>string?</code>: Nullable reference type for optional properties</p>
</li>
<li><p>Default values: <code>Created</code> and <code>Updated</code> automatically set to the current UTC</p>
</li>
</ul>
<h3 id="heading-why-use-guid-for-id">Why Use Guid for ID?</h3>
<p>We're using <code>Guid</code> instead of <code>int</code> for our primary key for a few reasons:</p>
<ul>
<li><p><strong>Uniqueness</strong>: Guaranteed to be unique across different systems</p>
</li>
<li><p><strong>Security</strong>: Harder to guess than sequential integers</p>
</li>
<li><p><strong>Distributed systems</strong>: No need for centralized ID generation</p>
</li>
<li><p><strong>Scalability</strong>: Perfect for microservices architecture</p>
</li>
</ul>
<h3 id="heading-namespace-considerations">Namespace Considerations</h3>
<p><strong>Important Note:</strong> If you changed your project name when creating it, make sure your namespace matches your project name. For example:</p>
<ul>
<li><p>If your project is named <code>MyProductService</code>, use <code>namespace MyProductService.Models</code></p>
</li>
<li><p>If your project is named <code>ProductGrpc</code>, use <code>namespace ProductGrpc.Models</code></p>
</li>
</ul>
<p>🎉 <strong>Excellent work!</strong> You've successfully created your first business model that will serve as the foundation for our entire gRPC application.</p>
<h3 id="heading-next-steps">Next Steps</h3>
<p>Now that we have our Product model ready, let's move on to setting up SQLite as our database and configuring Entity Framework Core to handle our data persistence. This will allow us to store and retrieve our Product data efficiently.</p>
<h2 id="heading-how-to-set-up-the-sqlite-database">How to Set Up the SQLite Database</h2>
<p>To persist our product data, we need a database that can handle our CRUD (Create, Read, Update, Delete) operations efficiently. We'll use <strong>SQLite</strong> for this tutorial because it's lightweight, requires no separate server installation, and works perfectly for developing small-to-medium applications.</p>
<h3 id="heading-installing-the-required-packages">Installing the Required Packages</h3>
<p>Before we create our database context, we need to install the necessary Entity Framework Core packages. Open your terminal and make sure you're in the root directory of your project, then run these commands:</p>
<pre><code class="lang-powershell">dotnet add package Microsoft.EntityFrameworkCore.Design
</code></pre>
<pre><code class="lang-powershell">dotnet add package Microsoft.EntityFrameworkCore.Sqlite
</code></pre>
<p>What these packages do:</p>
<ul>
<li><p><strong>Microsoft.EntityFrameworkCore.Design</strong> provides design-time tools for EF Core (migrations, scaffolding)</p>
</li>
<li><p><strong>Microsoft.EntityFrameworkCore.SQLite</strong> is a SQLite database provider for Entity Framework Core</p>
</li>
</ul>
<p>You should see output confirming the packages were added successfully:</p>
<pre><code class="lang-bash">info : PackageReference <span class="hljs-keyword">for</span> <span class="hljs-string">'Microsoft.EntityFrameworkCore.Design'</span> version <span class="hljs-string">'x.x.x'</span> added to file <span class="hljs-string">'ProductGrpc.csproj'</span>.
info : PackageReference <span class="hljs-keyword">for</span> <span class="hljs-string">'Microsoft.EntityFrameworkCore.Sqlite'</span> version <span class="hljs-string">'x.x.x'</span> added to file <span class="hljs-string">'ProductGrpc.csproj'</span>.
</code></pre>
<h3 id="heading-creating-the-database-context">Creating the Database Context</h3>
<p>Now let's create our database context, which acts as a bridge between our .NET objects and the database.</p>
<p>First, create a new folder called <code>Data</code> In your project root. Inside the Data folder, create a file called <code>AppDbContext.cs</code>.</p>
<p>Your project structure should now look like this:</p>
<pre><code class="lang-yaml"><span class="hljs-string">ProductGrpc/</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Data/</span>
<span class="hljs-string">│</span>   <span class="hljs-string">└──</span> <span class="hljs-string">AppDbContext.cs</span>      <span class="hljs-comment"># Our new database context</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Models/</span>
<span class="hljs-string">│</span>   <span class="hljs-string">└──</span> <span class="hljs-string">Product.cs</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Protos/</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Services/</span>
<span class="hljs-string">└──</span> <span class="hljs-string">...</span>
</code></pre>
<p>Add the following code to your <code>AppDbContext.cs</code> file:</p>
<pre><code class="lang-cs">
<span class="hljs-comment">// Data/AppDbContext.cs</span>
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> ProductGrpc.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">ProductGrpc.Data</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AppDbContext</span> : <span class="hljs-title">DbContext</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AppDbContext</span>(<span class="hljs-params">DbContextOptions&lt;AppDbContext&gt; options</span>) : <span class="hljs-title">base</span>(<span class="hljs-params">options</span>)</span>
        {
        }

        <span class="hljs-keyword">public</span> DbSet&lt;Product&gt; Products { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>Let’s understand the key components of DbContext:</p>
<ul>
<li><p><strong>Constructor</strong>: Accepts <code>DbContextOptions</code> for configuration (connection string, provider, and so on)</p>
</li>
<li><p><strong>DbSet Products</strong>: Represents the Products table in our database</p>
</li>
</ul>
<h3 id="heading-registering-the-database-context">Registering the Database Context</h3>
<p>Now we need to register our <code>AppDbContext</code> With the dependency injection container so our application can use it.</p>
<p>Open your <code>Program.cs</code> file and add the database configuration:</p>
<pre><code class="lang-cs"><span class="hljs-comment">// Program.cs</span>

<span class="hljs-keyword">using</span> ProductGrpc.Data;
<span class="hljs-keyword">using</span> ProductGrpc.Services;

<span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);

builder.Services.AddDbContext&lt;AppDbContext&gt;(opt=&gt; 
    opt.UseSqlite(<span class="hljs-string">"Data Source=ProductGrpc.db "</span>));
<span class="hljs-comment">// Add services to the container.</span>
builder.Services.AddGrpc();

<span class="hljs-keyword">var</span> app = builder.Build();

<span class="hljs-comment">// Configure the HTTP request pipeline.</span>
app.MapGrpcService&lt;GreeterService&gt;();
app.MapGet(<span class="hljs-string">"/"</span>, () =&gt; <span class="hljs-string">"Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"</span>);

app.Run();


app.Run();
</code></pre>
<p><code>Data Source=ProductGrpc.db</code> creates a SQLite database file named <code>ProductGrpc.db</code> in your project directory.</p>
<h3 id="heading-creating-and-running-migrations">Creating and Running Migrations</h3>
<p>Now we need to create a migration to generate the database schema based on our Product model.</p>
<p>Start by creating the initial migration:</p>
<pre><code class="lang-powershell">dotnet ef migrations add InitialCreate
</code></pre>
<p>This command will:</p>
<ul>
<li><p>Analyze your models and DbContext</p>
</li>
<li><p>Generate migration files in a <code>Migrations</code> folder</p>
</li>
<li><p>Create SQL commands needed to build your database schema</p>
</li>
</ul>
<p>You should see output like this:</p>
<pre><code class="lang-powershell">Build succeeded.
Done. To undo this action, use <span class="hljs-string">'dotnet ef migrations remove'</span>
</code></pre>
<p>Apply the migration to create the database:</p>
<pre><code class="lang-powershell">dotnet ef database update
</code></pre>
<p>This command will:</p>
<ul>
<li><p>Execute the migration SQL commands</p>
</li>
<li><p>Create the <code>ProductGrpc.db</code> file in your project directory</p>
</li>
<li><p>Set up the Products table with all the correct columns</p>
</li>
</ul>
<p>You should see output confirming the database was created:</p>
<pre><code class="lang-powershell">Build succeeded.
Applying migration <span class="hljs-string">'20240101000000_InitialCreate'</span>.
Done.
</code></pre>
<h3 id="heading-verifying-the-setup-1">Verifying the Setup</h3>
<p>After running the migration, you should see:</p>
<ol>
<li><p>A new <code>Migrations</code> folder in your project with migration files</p>
</li>
<li><p>A <code>ProductGrpc.db</code> file in your project root (this is your SQLite database)</p>
</li>
<li><p>No errors in the terminal output</p>
</li>
</ol>
<p>Your project structure should now look like this:</p>
<pre><code class="lang-yaml"><span class="hljs-string">ProductGrpc/</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Data/</span>
<span class="hljs-string">│</span>   <span class="hljs-string">└──</span> <span class="hljs-string">AppDbContext.cs</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Migrations/</span>
<span class="hljs-string">│</span>   <span class="hljs-string">├──</span> <span class="hljs-string">20240101000000_InitialCreate.cs</span>
<span class="hljs-string">│</span>   <span class="hljs-string">└──</span> <span class="hljs-string">AppDbContextModelSnapshot.cs</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Models/</span>
<span class="hljs-string">│</span>   <span class="hljs-string">└──</span> <span class="hljs-string">Product.cs</span>
<span class="hljs-string">├──</span> <span class="hljs-string">ProductGrpc.db</span>            <span class="hljs-comment"># Your SQLite database file</span>
<span class="hljs-string">└──</span> <span class="hljs-string">...</span>
</code></pre>
<p>Congratulations! You've successfully installed Entity Framework Core packages, created a database context, registered the context with dependency injection, generated and applied your first migration, and created a working SQLite database. Whew!</p>
<h3 id="heading-whats-next">What's Next?</h3>
<p>Now that our database is set up and ready, we can move on to creating our Protocol Buffer definitions (<code>.proto</code> files) and implementing our gRPC services for CRUD operations.</p>
<h2 id="heading-how-to-create-product-protocol-buffers">How to Create Product Protocol Buffers</h2>
<p>Protocol Buffers (protobuf) are the heart of gRPC communication. They define the structure of your data and services in a language-neutral way, which then gets compiled into native C# code. Protocol Buffers use the efficient <strong>HTTP/2</strong> protocol, making service-to-service communication fast and reliable.</p>
<h3 id="heading-understanding-protocol-buffers-vs-rest-apis">Understanding Protocol Buffers vs REST APIs</h3>
<p>To better understand Protocol Buffers, let's compare them to what you might already know from REST API development.</p>
<p>In REST API development, you typically define your API endpoints using controllers and action methods. The contract between client and server is often documented separately (like with OpenAPI/Swagger), and there's no compile-time guarantee that your documentation matches your actual implementation.</p>
<pre><code class="lang-csharp">[<span class="hljs-meta">ApiController</span>]
[<span class="hljs-meta">Route(<span class="hljs-meta-string">"api/[controller]"</span>)</span>]
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ProductsController</span> : <span class="hljs-title">ControllerBase</span>
{
    [<span class="hljs-meta">HttpGet(<span class="hljs-meta-string">"{id}"</span>)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;ActionResult&lt;ProductDto&gt;&gt; GetProduct(<span class="hljs-keyword">int</span> id) { ... }
</code></pre>
<p>With <strong>gRPC,</strong> the service contract is defined first in the <code>.proto</code> file using the <code>service</code> keyword. This contract becomes the single source of truth, and both client and server code are generated from it, ensuring they're always in sync.</p>
<pre><code class="lang-csharp">service ProductService {
  <span class="hljs-function">rpc <span class="hljs-title">GetProduct</span>(<span class="hljs-params">GetProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">GetProductResponse</span>)</span>;
}
</code></pre>
<h3 id="heading-data-transfer-and-serialization">Data Transfer and Serialization</h3>
<p>REST APIs typically use JSON for data transfer, which is human-readable and widely supported. But JSON is text-based, which has a few negatives. First, it has larger payload sizes due to text encoding. It also comes with some runtime parsing overhead. It doesn’t have any built-in schema validation, and there’s a high potential for typos in field names</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"id"</span>: <span class="hljs-string">"123e4567-e89b-12d3-a456-426614174000"</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"Wireless Headphones"</span>,
  <span class="hljs-attr">"price"</span>: <span class="hljs-number">99.99</span>
}
</code></pre>
<p>gRPC instead uses Protocol Buffers, which serialize data into a compact binary format. This provides significantly smaller payloads (up to 6x smaller than JSON), faster serialization/deserialization, strong typing with compile-time validation, and schema evolution without breaking changes.</p>
<h4 id="heading-transport-protocol-differences">Transport Protocol Differences</h4>
<p>REST APIs run over <strong>HTTP/1.1</strong>, which has some limitations:</p>
<ul>
<li><p>One request-response cycle per connection</p>
</li>
<li><p>Text-based headers (larger overhead)</p>
</li>
<li><p>No built-in multiplexing</p>
</li>
<li><p>Limited streaming capabilities</p>
</li>
</ul>
<p>gRPC leverages <strong>HTTP/2</strong>, which offers some advantages:</p>
<ul>
<li><p><strong>Multiplexing</strong>: Multiple requests over a single connection</p>
</li>
<li><p><strong>Header compression</strong>: Reduced overhead with HPACK</p>
</li>
<li><p><strong>Server push</strong>: The Server can initiate streams to clients</p>
</li>
<li><p><strong>Flow control</strong>: Better handling of slow consumers</p>
</li>
</ul>
<h4 id="heading-data-structure-definitions">Data Structure Definitions</h4>
<p>In REST APIs, you define <strong>DTOs (Data Transfer Objects)</strong> as regular classes:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ProductDto</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">decimal</span> Price { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}
</code></pre>
<p>These DTOs exist only in your specific language and need manual synchronization across different services or languages.</p>
<p>In gRPC, you define <strong>Messages</strong> in the proto file:</p>
<pre><code class="lang-csharp">message ProductModel {
  <span class="hljs-keyword">string</span> id = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> name = <span class="hljs-number">2</span>;
  <span class="hljs-keyword">double</span> price = <span class="hljs-number">3</span>;
}
</code></pre>
<p>These message definitions are language-agnostic and automatically generate equivalent classes in any supported programming language.</p>
<p>Here's a quick comparison table to summarize these differences:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Service Contracts and Interfaces Service Contracts and Interfaces REST API Concept</td><td>gRPC Equivalent</td><td>Purpose</td></tr>
</thead>
<tbody>
<tr>
<td>Interface</td><td>Service</td><td>Defines available operations</td></tr>
<tr>
<td>DTO (Data Transfer Object)</td><td>Message</td><td>Defines a data structure</td></tr>
<tr>
<td>JSON Request/Response</td><td>Binary Protocol Buffer</td><td>Data serialization format</td></tr>
<tr>
<td>HTTP/1.1</td><td>HTTP/2</td><td>Transport protocol</td></tr>
</tbody>
</table>
</div><h3 id="heading-creating-the-product-proto-file">Creating the Product Proto File</h3>
<p>Navigate to the <code>Protos</code> folder in your project and create a new file called <code>product.proto</code>. Make sure the file extension is <code>.proto</code>.</p>
<p>Your project structure should look like this:</p>
<pre><code class="lang-yaml"><span class="hljs-string">ProductGrpc/</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Protos/</span>
<span class="hljs-string">│</span>   <span class="hljs-string">├──</span> <span class="hljs-string">greet.proto</span>          <span class="hljs-comment"># Default template file</span>
<span class="hljs-string">│</span>   <span class="hljs-string">└──</span> <span class="hljs-string">product.proto</span>        <span class="hljs-comment"># Our new proto file</span>
<span class="hljs-string">└──</span> <span class="hljs-string">...</span>
</code></pre>
<h3 id="heading-setting-up-the-proto-file-header">Setting Up the Proto File Header</h3>
<p>Add the following header to your <code>product.proto</code> file:</p>
<pre><code class="lang-cs">
<span class="hljs-comment">//  Protos/product.proto</span>
syntax = <span class="hljs-string">"proto3"</span>;

option csharp_namespace = <span class="hljs-string">"ProductGrpc"</span>;

package product;
</code></pre>
<p>Here’s what’s going on:</p>
<ul>
<li><p><code>syntax = "proto3"</code>: Specifies that we're using Protocol Buffers version 3</p>
</li>
<li><p><code>option csharp_namespace = "ProductGrpc"</code>: Sets the C# namespace for generated code</p>
</li>
<li><p><code>package product</code>: Defines the protobuf package name</p>
</li>
</ul>
<p><strong>Note:</strong> If you named your project differently, make sure the <code>csharp_namespace</code> matches your project name.</p>
<h3 id="heading-defining-the-product-service">Defining the Product Service</h3>
<p>In gRPC, services define the available operations (similar to interfaces in REST APIs). Add the following service definition:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// :Protos/product.proto</span>
service  ProductsServiceProto {
  <span class="hljs-function">rpc <span class="hljs-title">CreateProduct</span>(<span class="hljs-params">CreateProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">CreateProductResponse</span>)</span>;
  <span class="hljs-function">rpc <span class="hljs-title">GetProduct</span>(<span class="hljs-params">GetProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">GetProductResponse</span>)</span>;
  <span class="hljs-function">rpc <span class="hljs-title">ListProducts</span>(<span class="hljs-params">ListProductsRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">ListProductsResponse</span>)</span>;
  <span class="hljs-function">rpc <span class="hljs-title">UpdateProduct</span>(<span class="hljs-params">UpdateProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">UpdateProductResponse</span>)</span>;
  <span class="hljs-function">rpc <span class="hljs-title">DeleteProduct</span>(<span class="hljs-params">DeleteProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">DeleteProductResponse</span>)</span>;
}
</code></pre>
<p>Service methods explained:</p>
<ul>
<li><p><code>rpc</code>: Defines a remote procedure call</p>
</li>
<li><p><code>CreateProduct</code>: Method name</p>
</li>
<li><p><code>(CreateProductRequest)</code>: Input message type</p>
</li>
<li><p><code>returns (CreateProductResponse)</code>: Output message type</p>
</li>
</ul>
<h3 id="heading-defining-protocol-buffer-messages">Defining Protocol Buffer Messages</h3>
<p>Messages in gRPC are equivalent to DTOs in REST APIs. They define the structure of data being exchanged. Let's create all the messages we need:</p>
<h4 id="heading-product-model-message">Product Model Message:</h4>
<pre><code class="lang-yaml"><span class="hljs-string">//</span> <span class="hljs-string">product.proto</span>
<span class="hljs-string">message</span> <span class="hljs-string">ProductModel</span> {
  <span class="hljs-string">string</span> <span class="hljs-string">id</span> <span class="hljs-string">=</span> <span class="hljs-number">1</span><span class="hljs-string">;</span>
  <span class="hljs-string">string</span> <span class="hljs-string">name</span> <span class="hljs-string">=</span> <span class="hljs-number">2</span><span class="hljs-string">;</span>
  <span class="hljs-string">string</span> <span class="hljs-string">description</span> <span class="hljs-string">=</span> <span class="hljs-number">3</span><span class="hljs-string">;</span>
  <span class="hljs-string">double</span> <span class="hljs-string">price</span> <span class="hljs-string">=</span> <span class="hljs-number">4</span><span class="hljs-string">;</span>
  <span class="hljs-string">string</span> <span class="hljs-string">created_at</span> <span class="hljs-string">=</span> <span class="hljs-number">5</span><span class="hljs-string">;</span>
  <span class="hljs-string">string</span> <span class="hljs-string">updated_at</span> <span class="hljs-string">=</span> <span class="hljs-number">6</span><span class="hljs-string">;</span>
  <span class="hljs-string">string</span> <span class="hljs-string">tags</span> <span class="hljs-string">=</span> <span class="hljs-number">7</span><span class="hljs-string">;</span>
}
</code></pre>
<h4 id="heading-create-operation-messages">Create Operation Messages:</h4>
<pre><code class="lang-cs"><span class="hljs-comment">// Protos/product.proto</span>
message CreateProductRequest {
  <span class="hljs-keyword">string</span> name = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> description = <span class="hljs-number">2</span>;
  <span class="hljs-keyword">double</span> price = <span class="hljs-number">3</span>;
  <span class="hljs-keyword">string</span> tags = <span class="hljs-number">4</span>;
}

message CreateProductResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
  ProductModel product = <span class="hljs-number">3</span>;
}
</code></pre>
<h4 id="heading-read-operation-messages">Read Operation Messages:</h4>
<pre><code class="lang-cs"><span class="hljs-comment">// Protos/product.proto</span>
message GetProductRequest {
  <span class="hljs-keyword">string</span> id = <span class="hljs-number">1</span>;
}

message GetProductResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
  ProductModel product = <span class="hljs-number">3</span>;
}

message ListProductsRequest {
  int32 page = <span class="hljs-number">1</span>;
  int32 page_size = <span class="hljs-number">2</span>;
}

message ListProductsResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
  repeated ProductModel products = <span class="hljs-number">3</span>;
  int32 total_count = <span class="hljs-number">4</span>;
}
</code></pre>
<h4 id="heading-update-operation-messages">Update Operation Messages:</h4>
<pre><code class="lang-cs"> <span class="hljs-comment">// Protos/product.proto</span>
message UpdateProductRequest {
  <span class="hljs-keyword">string</span> id = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> name = <span class="hljs-number">2</span>;
  <span class="hljs-keyword">string</span> description = <span class="hljs-number">3</span>;
  <span class="hljs-keyword">double</span> price = <span class="hljs-number">4</span>;
  <span class="hljs-keyword">string</span> tags = <span class="hljs-number">5</span>;
}

message UpdateProductResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
  ProductModel product = <span class="hljs-number">3</span>;
}
</code></pre>
<h4 id="heading-delete-operation-messages">Delete Operation Messages:</h4>
<pre><code class="lang-cs"><span class="hljs-comment">// Protos/product.proto</span>
message DeleteProductRequest {
  <span class="hljs-keyword">string</span> id = <span class="hljs-number">1</span>;
}

message DeleteProductResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
}
</code></pre>
<h3 id="heading-understanding-protocol-buffer-syntax">Understanding Protocol Buffer Syntax</h3>
<p>There are a few key concepts you should understand about how protocol buffers work:</p>
<ul>
<li><p><strong>Field Numbers</strong>: Each field has a unique number (for example, <code>= 1</code>, <code>= 2</code>) used for binary encoding</p>
</li>
<li><p><strong>Field Types</strong>: <code>string</code>, <code>int32</code>, <code>double</code>, <code>bool</code> are common scalar types</p>
</li>
<li><p><strong>repeated</strong>: Indicates an array/list (for example, <code>repeated ProductModel products</code>)</p>
</li>
<li><p><strong>Message Nesting</strong>: Messages can contain other messages (for example, <code>ProductModel product</code>)</p>
</li>
</ul>
<p>Keep in mind that field numbers must be unique within a message, field numbers 1-15 use 1 byte encoding (more efficient), and you should never reuse field numbers (for backward compatibility).</p>
<h3 id="heading-complete-product-proto-file">Complete Product Proto File</h3>
<p>Here's your complete <code>product.proto</code> file:</p>
<pre><code class="lang-cs"><span class="hljs-comment">// Protos/product.proto</span>
syntax = <span class="hljs-string">"proto3"</span>;

option csharp_namespace = <span class="hljs-string">"ProductGrpc"</span>;

package product;

<span class="hljs-comment">// Product service definition</span>
service  ProductsServiceProto {
  <span class="hljs-function">rpc <span class="hljs-title">CreateProduct</span>(<span class="hljs-params">CreateProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">CreateProductResponse</span>)</span>;
  <span class="hljs-function">rpc <span class="hljs-title">GetProduct</span>(<span class="hljs-params">GetProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">GetProductResponse</span>)</span>;
  <span class="hljs-function">rpc <span class="hljs-title">ListProducts</span>(<span class="hljs-params">ListProductsRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">ListProductsResponse</span>)</span>;
  <span class="hljs-function">rpc <span class="hljs-title">UpdateProduct</span>(<span class="hljs-params">UpdateProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">UpdateProductResponse</span>)</span>;
  <span class="hljs-function">rpc <span class="hljs-title">DeleteProduct</span>(<span class="hljs-params">DeleteProductRequest</span>) <span class="hljs-title">returns</span> (<span class="hljs-params">DeleteProductResponse</span>)</span>;
}

<span class="hljs-comment">// Product model message</span>
message ProductModel {
  <span class="hljs-keyword">string</span> id = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> name = <span class="hljs-number">2</span>;
  <span class="hljs-keyword">string</span> description = <span class="hljs-number">3</span>;
  <span class="hljs-keyword">double</span> price = <span class="hljs-number">4</span>;
  <span class="hljs-keyword">string</span> created_at = <span class="hljs-number">5</span>;
  <span class="hljs-keyword">string</span> updated_at = <span class="hljs-number">6</span>;
  <span class="hljs-keyword">string</span> tags = <span class="hljs-number">7</span>;
}

<span class="hljs-comment">// Create operation messages</span>
message CreateProductRequest {
  <span class="hljs-keyword">string</span> name = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> description = <span class="hljs-number">2</span>;
  <span class="hljs-keyword">double</span> price = <span class="hljs-number">3</span>;
  <span class="hljs-keyword">string</span> tags = <span class="hljs-number">4</span>;
}

message CreateProductResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
  ProductModel product = <span class="hljs-number">3</span>;
}

<span class="hljs-comment">// Read operation messages</span>
message GetProductRequest {
  <span class="hljs-keyword">string</span> id = <span class="hljs-number">1</span>;
}

message GetProductResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
  ProductModel product = <span class="hljs-number">3</span>;
}

message ListProductsRequest {
  int32 page = <span class="hljs-number">1</span>;
  int32 page_size = <span class="hljs-number">2</span>;
}

message ListProductsResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
  repeated ProductModel products = <span class="hljs-number">3</span>;
  int32 total_count = <span class="hljs-number">4</span>;
}

<span class="hljs-comment">// Update operation messages</span>
message UpdateProductRequest {
  <span class="hljs-keyword">string</span> id = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> name = <span class="hljs-number">2</span>;
  <span class="hljs-keyword">string</span> description = <span class="hljs-number">3</span>;
  <span class="hljs-keyword">double</span> price = <span class="hljs-number">4</span>;
  <span class="hljs-keyword">string</span> tags = <span class="hljs-number">5</span>;
}

message UpdateProductResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
  ProductModel product = <span class="hljs-number">3</span>;
}

<span class="hljs-comment">// Delete operation messages</span>
message DeleteProductRequest {
  <span class="hljs-keyword">string</span> id = <span class="hljs-number">1</span>;
}

message DeleteProductResponse {
  <span class="hljs-keyword">bool</span> success = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> message = <span class="hljs-number">2</span>;
}
</code></pre>
<h3 id="heading-building-the-project-to-generate-c-code">Building the Project to Generate C# Code</h3>
<p>Now that we've defined our Protocol Buffer contract, we need to build the project to generate the corresponding C# code:</p>
<pre><code class="lang-bash">dotnet build
</code></pre>
<p>This command will compile your <code>.proto</code> files into C# classes, generate client and server code, and create strongly-typed request/response classes.</p>
<p>You should see output confirming the build was successful:</p>
<pre><code class="lang-bash">Restore complete (0.6s)
  ProductGrpc succeeded (9.5s) → bin\Debug\net9.0\ProductGrpc.dll

Build succeeded <span class="hljs-keyword">in</span> 11.1s
</code></pre>
<h3 id="heading-what-gets-generated">What Gets Generated?</h3>
<p>After building, the Protocol Buffer compiler generates several C# files (you won't see them directly, but they're available in your code):</p>
<ul>
<li><p><strong>ProductModel</strong>: C# class representing your product data</p>
</li>
<li><p><strong>CreateProductRequest/Response</strong>: Request and response classes for create operations</p>
</li>
<li><p><strong>ProductService.ProductServiceBase</strong>: Base class for implementing your service</p>
</li>
<li><p><strong>ProductService.ProductServiceClient</strong>: Client class for calling the service</p>
</li>
</ul>
<p>Congratulations! You've successfully created a comprehensive Protocol Buffer definition, defined a complete CRUD service contract, set up a strongly-typed message structure, and generated C# code from your proto file.</p>
<h3 id="heading-whats-next-1">What's Next?</h3>
<p>Now that we have our Protocol Buffer contract defined, we can start implementing the actual gRPC service methods. In the next section, we'll create the <code>ProductService</code> Class and implement each CRUD operation.</p>
<p><strong>Remember:</strong> Protocol Buffers are language-agnostic, so this same <code>.proto</code> file could be used to generate client code in Python, Java, Go, or any other supported language.</p>
<h2 id="heading-how-to-implement-crud-operations-services-with-grpc">How to Implement CRUD Operations Services with gRPC</h2>
<p>Now that we have our database set up and Protocol Buffer contracts defined, it's time to implement the actual CRUD (Create, Read, Update, Delete) functionality. We'll create a gRPC service that brings together our database models and Protocol Buffer definitions.</p>
<h3 id="heading-understanding-the-implementation-architecture">Understanding the Implementation Architecture</h3>
<p>Before we start coding, let's understand how the pieces fit together:</p>
<pre><code class="lang-bash">Protocol Buffer (.proto) → Generated C<span class="hljs-comment"># Code → Our Service Implementation → Database</span>
</code></pre>
<p>Key concepts in this code:</p>
<ul>
<li><p><strong>Proto Service:</strong> Interface (defines what methods are available)</p>
</li>
<li><p><strong>Proto Messages</strong>: DTOs (define data structure)</p>
</li>
<li><p><strong>Service Implementation</strong>: Business logic (what happens)</p>
</li>
<li><p><strong>Database Context</strong>: Data persistence layer</p>
</li>
</ul>
<h3 id="heading-configuring-proto-file-build">Configuring Proto File Build</h3>
<p>First, we need to ensure our <code>product.proto</code> file gets compiled into C# code during the build process.</p>
<p>Open your <code>ProductGrpc.csproj</code> file and locate the <code>&lt;ItemGroup&gt;</code> section that references proto files:</p>
<pre><code class="lang-xml">  <span class="hljs-comment">&lt;!-- ProductGrpc.csproj --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">Project</span> <span class="hljs-attr">Sdk</span>=<span class="hljs-string">"Microsoft.NET.Sdk.Web"</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">TargetFramework</span>&gt;</span>net9.0<span class="hljs-tag">&lt;/<span class="hljs-name">TargetFramework</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Nullable</span>&gt;</span>enable<span class="hljs-tag">&lt;/<span class="hljs-name">Nullable</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ImplicitUsings</span>&gt;</span>enable<span class="hljs-tag">&lt;/<span class="hljs-name">ImplicitUsings</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Protobuf</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Protos\greet.proto"</span> <span class="hljs-attr">GrpcServices</span>=<span class="hljs-string">"Server"</span> /&gt;</span>
    <span class="hljs-comment">&lt;!-- Add this line to include our product.proto file --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Protobuf</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Protos\product.proto"</span> <span class="hljs-attr">GrpcServices</span>=<span class="hljs-string">"Server"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Grpc.AspNetCore"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"2.64.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.Design"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"9.0.6"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">IncludeAssets</span>&gt;</span>runtime; build; native; contentfiles; analyzers; buildtransitive<span class="hljs-tag">&lt;/<span class="hljs-name">IncludeAssets</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PrivateAssets</span>&gt;</span>all<span class="hljs-tag">&lt;/<span class="hljs-name">PrivateAssets</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">PackageReference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.Sqlite"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"9.0.6"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">Project</span>&gt;</span>
</code></pre>
<p>What this configuration does:</p>
<ul>
<li><p><code>Include="Protos\product.proto"</code> tells .NET to process our proto file</p>
</li>
<li><p><code>GrpcServices="Server"</code> generates server-side code (service base classes)</p>
</li>
</ul>
<h3 id="heading-building-the-project">Building the Project</h3>
<p>Now let's build the project to generate the C# code from our proto file:</p>
<pre><code class="lang-bash">dotnet build
</code></pre>
<p>This command will compile your <code>.proto</code> files into C# classes, generate the <code>ProductsServiceProto. ProductsServiceProtoBase</code> class we'll inherit from, create all the request/response message classes, and validate that everything compiles correctly.</p>
<p>You should see output like:</p>
<pre><code class="lang-yaml"><span class="hljs-string">Build</span> <span class="hljs-string">succeeded.</span>
    <span class="hljs-number">0</span> <span class="hljs-string">Warning(s)</span>
    <span class="hljs-number">0</span> <span class="hljs-string">Error(s)</span>
</code></pre>
<h3 id="heading-creating-the-productservice-class">Creating the ProductService Class</h3>
<p>Navigate to the <code>Services</code> folder and create a new file called <code>ProductService.cs</code>. This will contain our gRPC service implementation.</p>
<p>Your project structure should now look like this:</p>
<pre><code class="lang-yaml"><span class="hljs-string">ProductGrpc/</span>
<span class="hljs-string">├──</span> <span class="hljs-string">Services/</span>
<span class="hljs-string">│</span>   <span class="hljs-string">├──</span> <span class="hljs-string">GreeterService.cs</span>    <span class="hljs-comment"># Default template service</span>
<span class="hljs-string">│</span>   <span class="hljs-string">└──</span> <span class="hljs-string">ProductService.cs</span>    <span class="hljs-comment"># Our new product service</span>
<span class="hljs-string">└──</span> <span class="hljs-string">...</span>
</code></pre>
<h3 id="heading-setting-up-the-service-foundation">Setting Up the Service Foundation</h3>
<p>Start by creating the basic service class structure:</p>
<pre><code class="lang-csharp">
 <span class="hljs-comment">// Services/ProductService.cs</span>
<span class="hljs-keyword">using</span> Grpc.Core;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> ProductGrpc.Data;
<span class="hljs-keyword">using</span> ProductGrpc.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">ProductGrpc.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ProductService</span> :  <span class="hljs-title">ProductsServiceProto</span> .<span class="hljs-title">ProductsServiceProtoBase</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> AppDbContext _dbContext;
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;ProductService&gt; _logger;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ProductService</span>(<span class="hljs-params">AppDbContext dbContext, ILogger&lt;ProductService&gt; logger</span>)</span>
        {
            _dbContext = dbContext;
            _logger = logger;
        }

        <span class="hljs-comment">// CRUD methods will be implemented here</span>
    }
}
</code></pre>
<p>Key components of this code:</p>
<ul>
<li><p><strong>Inheritance</strong>: <code>ProductsServiceProto .ProductsServiceProtoBase</code> is generated from our proto file</p>
</li>
<li><p><strong>Dependency injection</strong>: We inject <code>AppDbContext</code> for database operations and <code>ILogger</code> for logging</p>
</li>
<li><p><strong>Constructor</strong>: Initializes our dependencies</p>
</li>
</ul>
<h3 id="heading-implementing-method-signatures">Implementing Method Signatures</h3>
<p>Now let's add all the method signatures that we defined in our proto file. These methods override the virtual methods from the base class:</p>
<pre><code class="lang-csharp"> <span class="hljs-comment">//Services/ProductService.cs</span>
<span class="hljs-keyword">using</span> Grpc.Core;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> ProductGrpc.Data;
<span class="hljs-keyword">using</span> ProductGrpc.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">ProductGrpc.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ProductService</span> :  <span class="hljs-title">ProductsServiceProto</span> .<span class="hljs-title">ProductsServiceProtoBase</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> AppDbContext _dbContext;
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;ProductService&gt; _logger;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ProductService</span>(<span class="hljs-params">AppDbContext dbContext, ILogger&lt;ProductService&gt; logger</span>)</span>
        {
            _dbContext = dbContext;
            _logger = logger;
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;CreateProductResponse&gt; <span class="hljs-title">CreateProduct</span>(<span class="hljs-params">
            CreateProductRequest request, 
            ServerCallContext context</span>)</span>
        {
            <span class="hljs-comment">// Implementation will go here</span>
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;GetProductResponse&gt; <span class="hljs-title">GetProduct</span>(<span class="hljs-params">
            GetProductRequest request, 
            ServerCallContext context</span>)</span>
        {
            <span class="hljs-comment">// Implementation will go here</span>
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;ListProductsResponse&gt; <span class="hljs-title">ListProducts</span>(<span class="hljs-params">
            ListProductsRequest request, 
            ServerCallContext context</span>)</span>
        {
            <span class="hljs-comment">// Implementation will go here</span>
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;UpdateProductResponse&gt; <span class="hljs-title">UpdateProduct</span>(<span class="hljs-params">
            UpdateProductRequest request, 
            ServerCallContext context</span>)</span>
        {
            <span class="hljs-comment">// Implementation will go here</span>
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;DeleteProductResponse&gt; <span class="hljs-title">DeleteProduct</span>(<span class="hljs-params">
            DeleteProductRequest request, 
            ServerCallContext context</span>)</span>
        {
            <span class="hljs-comment">// Implementation will go here</span>
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }
    }
}
</code></pre>
<h3 id="heading-understanding-method-parameters">Understanding Method Parameters</h3>
<p>Each gRPC method receives two parameters:</p>
<ol>
<li><p><strong>Request parameter</strong>: Contains the data sent by the client (for example, <code>CreateProductRequest</code>)</p>
</li>
<li><p><strong>ServerCallContext</strong>: Provides access to request metadata, cancellation tokens, and response headers</p>
</li>
</ol>
<p><strong>Method Signature Pattern:</strong></p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;ResponseType&gt; <span class="hljs-title">MethodName</span>(<span class="hljs-params">
    RequestType request, 
    ServerCallContext context</span>)</span>
</code></pre>
<h3 id="heading-registering-the-service">Registering the Service</h3>
<p>Before we implement the methods, we need to register our service with the application. Open <code>Program.cs</code> and add the service:</p>
<pre><code class="lang-cs">
 <span class="hljs-comment">// Program.cs</span>
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> ProductGrpc.Data;
<span class="hljs-keyword">using</span> ProductGrpc.Services; <span class="hljs-comment">// Add this using statement</span>

<span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);

<span class="hljs-comment">// Add services to the container.</span>
builder.Services.AddGrpc();

<span class="hljs-comment">// Register our database context</span>
builder.Services.AddDbContext&lt;AppDbContext&gt;(options =&gt;
    options.UseSqlite(<span class="hljs-string">"Data Source=ProductGrpc.db"</span>));

<span class="hljs-keyword">var</span> app = builder.Build();

<span class="hljs-comment">// Configure the HTTP request pipeline.</span>
app.MapGrpcService&lt;GreeterService&gt;();
app.MapGrpcService&lt;ProductService&gt;(); <span class="hljs-comment">// Add this line</span>

app.MapGet(<span class="hljs-string">"/"</span>, () =&gt; <span class="hljs-string">"Communication with gRPC endpoints must be made through a gRPC client. To learn how to create a client, visit: https://go.microsoft.com/fwlink/?linkid=2086909"</span>);

app.Run();
</code></pre>
<h3 id="heading-handling-compiler-warnings">Handling Compiler Warnings</h3>
<p>You might see warnings like:</p>
<pre><code class="lang-bash">This async method lacks <span class="hljs-string">'await'</span> operators and will run synchronously.
</code></pre>
<p>This is expected since we haven't implemented the actual logic yet. These warnings will disappear once we add the implementation in the following sections.</p>
<h3 id="heading-creating-helper-methods">Creating Helper Methods</h3>
<p>Before implementing CRUD operations, let's add some helper methods for converting between our database models and Protocol Buffer messages:</p>
<pre><code class="lang-cs">:Services/ProductService.cs
<span class="hljs-comment">// Add these helper methods to your ProductService class</span>


 <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ProductModel <span class="hljs-title">MapToProductModel</span>(<span class="hljs-params">Product product</span>)</span>
{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ProductModel
    {
        Id = product.Id.ToString(),
        Name = product.Name,
        Description = product.Description,
        Price = (<span class="hljs-keyword">double</span>)product.Price,
        CreatedAt = product.Created.ToString(<span class="hljs-string">"yyyy-MM-ddTHH:mm:ssZ"</span>),
        UpdatedAt = product.Updated.ToString(<span class="hljs-string">"yyyy-MM-ddTHH:mm:ssZ"</span>),
        Tag = product.Tags ?? <span class="hljs-keyword">string</span>.Empty
    };
}
</code></pre>
<p>Excellent work! You've successfully:</p>
<ul>
<li><p>Configured proto file compilation</p>
</li>
<li><p>Created the ProductService class structure</p>
</li>
<li><p>Set up dependency injection</p>
</li>
<li><p>Defined all CRUD method signatures</p>
</li>
<li><p>Registered the service with the application</p>
</li>
<li><p>Created helper methods for data mapping</p>
</li>
</ul>
<h3 id="heading-whats-next-2">What's Next?</h3>
<p>Now that we have our service foundation ready, we'll implement each CRUD operation one by one:</p>
<ol>
<li><p><strong>CreateProduct</strong>: Add new products to the database</p>
</li>
<li><p><strong>GetProduct</strong>: Retrieve a single product by ID</p>
</li>
<li><p><strong>ListProducts</strong>: Get a paginated list of products</p>
</li>
<li><p><strong>UpdateProduct</strong>: Modify existing products</p>
</li>
<li><p><strong>DeleteProduct</strong>: Remove products from the database</p>
</li>
</ol>
<p>In the next sections, we'll dive deep into each implementation, handling error cases, validation, and best practices.</p>
<p><strong>💡 Pro Tip:</strong> The <code>ServerCallContext</code> parameter provides useful information like request cancellation tokens, client metadata, and response headers. We'll use these in our implementations for better error handling and logging.</p>
<p><strong>Note:</strong> The <code>override</code> keyword is crucial – it tells C# that we're implementing the virtual methods defined in the generated base class from our proto file.</p>
<h2 id="heading-how-to-implement-grpc-crud-database-operations-with-sqlite">How to Implement gRPC CRUD Database Operations With SQLite</h2>
<p>Now that we have our service foundation ready, let's implement each CRUD operation. Each method will handle database operations, error handling, and return appropriate responses using our Protocol Buffer messages.</p>
<h3 id="heading-understanding-the-implementation-pattern">Understanding the Implementation Pattern</h3>
<p>Each CRUD operation follows a consistent pattern:</p>
<ol>
<li><p><strong>Input Validation</strong>: Validate request parameters</p>
</li>
<li><p><strong>Database Operation</strong>: Perform the actual database work</p>
</li>
<li><p><strong>Response Mapping</strong>: Convert database models to Protocol Buffer messages</p>
</li>
<li><p><strong>Error Handling</strong>: Catch and handle exceptions gracefully</p>
</li>
</ol>
<h3 id="heading-creating-the-createproduct-service">Creating the <code>CreateProduct</code> Service</h3>
<p>The <code>CreateProduct</code> method handles adding new products to our database. This is the <strong>"C"</strong> in CRUD (Create).</p>
<pre><code class="lang-cs"><span class="hljs-comment">//Services/ProductService.cs</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;CreateProductResponse&gt; <span class="hljs-title">CreateProduct</span>(<span class="hljs-params">
    CreateProductRequest request, 
    ServerCallContext context</span>)</span>
{
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-comment">// Input validation</span>
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(request.Name))
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> CreateProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Product name is required"</span>
            };
        }

        <span class="hljs-keyword">if</span> (request.Price &lt;= <span class="hljs-number">0</span>)
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> CreateProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Product price must be greater than zero"</span>
            };
        }

        <span class="hljs-comment">// Create new product entity</span>
        <span class="hljs-keyword">var</span> productItem = <span class="hljs-keyword">new</span> Product
        {
            Id = Guid.NewGuid(),
            Name = request.Name,
            Description = request.Description,
            Price = Convert.ToDecimal(request.Price),
            Created = DateTime.UtcNow,
            Updated = DateTime.UtcNow,
            Tags = request.Tags
        };

        <span class="hljs-comment">// Add to database</span>
        _dbContext.Products.Add(productItem);
        <span class="hljs-keyword">await</span> _dbContext.SaveChangesAsync();

        _logger.LogInformation(<span class="hljs-string">"Product created successfully with ID: {ProductId}"</span>, productItem.Id);

        <span class="hljs-comment">// Return success response</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> CreateProductResponse
        {
            Success = <span class="hljs-literal">true</span>,
            Message = <span class="hljs-string">"Product created successfully"</span>,
            Product = MapToProductModel(productItem)
        };
    }
    <span class="hljs-keyword">catch</span> (Exception ex)
    {
        _logger.LogError(ex, <span class="hljs-string">"Error creating product"</span>);

        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> CreateProductResponse
        {
            Success = <span class="hljs-literal">false</span>,
            Message = <span class="hljs-string">$"Error creating product: <span class="hljs-subst">{ex.Message}</span>"</span>
        };
    }
}
</code></pre>
<p>These are the important implementation details:</p>
<ul>
<li><p><strong>Unique ID generation</strong>: <code>Guid.NewGuid()</code> Creates a unique identifier</p>
</li>
<li><p><strong>Timestamp management</strong>: <code>DateTime.UtcNow</code> Ensures consistent timezone handling</p>
</li>
<li><p><strong>Type conversion</strong>: <code>Convert.ToDecimal()</code> converts double to decimal for database storage</p>
</li>
<li><p><strong>Input validation</strong>: Checks for required fields and valid values</p>
</li>
<li><p><strong>Logging</strong>: Records successful operations and errors for debugging</p>
</li>
</ul>
<h3 id="heading-creating-the-getproduct-service">Creating the <code>GetProduct</code> Service</h3>
<p>The <code>GetProduct</code> method retrieves a single product by its ID. This is the <strong>"R"</strong> in CRUD (Read).</p>
<pre><code class="lang-cs"><span class="hljs-comment">//Services/ProductService.cs</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;GetProductResponse&gt; <span class="hljs-title">GetProduct</span>(<span class="hljs-params">
    GetProductRequest request, 
    ServerCallContext context</span>)</span>
{
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-comment">// Validate and parse the product ID</span>
        <span class="hljs-keyword">if</span> (!Guid.TryParse(request.Id, <span class="hljs-keyword">out</span> <span class="hljs-keyword">var</span> productId))
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> GetProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Invalid product ID format. Please provide a valid GUID."</span>
            };
        }

        <span class="hljs-comment">// Find product in database</span>
        <span class="hljs-keyword">var</span> product = <span class="hljs-keyword">await</span> _dbContext.Products.FindAsync(productId);

        <span class="hljs-keyword">if</span> (product == <span class="hljs-literal">null</span>)
        {
            _logger.LogWarning(<span class="hljs-string">"Product not found with ID: {ProductId}"</span>, productId);

            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> GetProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Product not found"</span>
            };
        }

        _logger.LogInformation(<span class="hljs-string">"Product retrieved successfully with ID: {ProductId}"</span>, productId);

        <span class="hljs-comment">// Return success response with product data</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> GetProductResponse
        {
            Success = <span class="hljs-literal">true</span>,
            Message = <span class="hljs-string">"Product retrieved successfully"</span>,
            Product = MapToProductModel(product)
        };
    }
    <span class="hljs-keyword">catch</span> (Exception ex)
    {
        _logger.LogError(ex, <span class="hljs-string">"Error retrieving product with ID: {ProductId}"</span>, request.Id);

        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> GetProductResponse
        {
            Success = <span class="hljs-literal">false</span>,
            Message = <span class="hljs-string">$"Error retrieving product: <span class="hljs-subst">{ex.Message}</span>"</span>
        };
    }
}
</code></pre>
<p>Important implementation details:</p>
<ul>
<li><p><strong>ID validation</strong>: <code>Guid.TryParse()</code> safely validates the ID format</p>
</li>
<li><p><strong>Database query</strong>: <code>FindAsync()</code> efficiently finds records by primary key</p>
</li>
<li><p><strong>Null checking</strong>: Handles cases where the product doesn't exist</p>
</li>
<li><p><strong>Detailed logging</strong>: Tracks both successful retrievals and missing products</p>
</li>
</ul>
<h3 id="heading-creating-the-listproducts-service">Creating the <code>ListProducts</code> Service</h3>
<p>The <code>ListProducts</code> method retrieves multiple products with pagination support. This is also part of the <strong>"R"</strong> in CRUD (Read).</p>
<pre><code class="lang-cs"><span class="hljs-comment">// Services/ProductService.cs</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;ListProductsResponse&gt; <span class="hljs-title">ListProducts</span>(<span class="hljs-params">
    ListProductsRequest request, 
    ServerCallContext context</span>)</span>
{
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-comment">// Set default pagination values</span>
        <span class="hljs-keyword">var</span> pageSize = request.PageSize &lt;= <span class="hljs-number">0</span> ? <span class="hljs-number">10</span> : Math.Min(request.PageSize, <span class="hljs-number">100</span>); <span class="hljs-comment">// Max 100 items per page</span>
        <span class="hljs-keyword">var</span> page = request.Page &lt;= <span class="hljs-number">0</span> ? <span class="hljs-number">1</span> : request.Page;

        <span class="hljs-comment">// Calculate skip amount for pagination</span>
        <span class="hljs-keyword">var</span> skip = (page - <span class="hljs-number">1</span>) * pageSize;

        <span class="hljs-comment">// Get total count for pagination metadata</span>
        <span class="hljs-keyword">var</span> totalCount = <span class="hljs-keyword">await</span> _dbContext.Products.CountAsync();

        <span class="hljs-comment">// Retrieve paginated products</span>
        <span class="hljs-keyword">var</span> products = <span class="hljs-keyword">await</span> _dbContext.Products
            .OrderBy(p =&gt; p.Created) <span class="hljs-comment">// Consistent ordering</span>
            .Skip(skip)
            .Take(pageSize)
            .ToListAsync();

        <span class="hljs-comment">// Create response</span>
        <span class="hljs-keyword">var</span> response = <span class="hljs-keyword">new</span> ListProductsResponse
        {
            Success = <span class="hljs-literal">true</span>,
            Message = products.Any() 
                ? <span class="hljs-string">$"Retrieved <span class="hljs-subst">{products.Count}</span> products (Page <span class="hljs-subst">{page}</span> of <span class="hljs-subst">{Math.Ceiling((<span class="hljs-keyword">double</span>)totalCount / pageSize)}</span>)"</span>
                : <span class="hljs-string">"No products found"</span>,
            TotalCount = totalCount
        };

        <span class="hljs-comment">// Add products to response</span>
        response.Products.AddRange(products.Select(MapToProductModel));

        _logger.LogInformation(<span class="hljs-string">"Listed {ProductCount} products for page {Page}"</span>, products.Count, page);

        <span class="hljs-keyword">return</span> response;
    }
    <span class="hljs-keyword">catch</span> (Exception ex)
    {
        _logger.LogError(ex, <span class="hljs-string">"Error retrieving products list"</span>);

        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ListProductsResponse
        {
            Success = <span class="hljs-literal">false</span>,
            Message = <span class="hljs-string">$"Error retrieving products: <span class="hljs-subst">{ex.Message}</span>"</span>,
            TotalCount = <span class="hljs-number">0</span>
        };
    }
}
</code></pre>
<p>Here are the key implementation details:</p>
<ul>
<li><p><strong>Pagination logic</strong>: Calculates <code>skip</code> and <code>take</code> values for efficient data retrieval</p>
</li>
<li><p><strong>Default values</strong>: Sets sensible defaults for page size and page number</p>
</li>
<li><p><strong>Performance optimization</strong>: Uses <code>Skip()</code> and <code>Take()</code> for database-level pagination</p>
</li>
<li><p><strong>Consistent ordering</strong>: <code>OrderBy()</code> ensures predictable results across requests</p>
</li>
<li><p><strong>Metadata</strong>: Returns total count for client-side pagination UI</p>
</li>
</ul>
<h3 id="heading-creating-the-updateproduct-service">Creating the <code>UpdateProduct</code> Service</h3>
<p>The <code>UpdateProduct</code> method modifies existing products. This is the <strong>"U"</strong> in CRUD (Update).</p>
<pre><code class="lang-cs"><span class="hljs-comment">// Services/ProductService.cs</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;UpdateProductResponse&gt; <span class="hljs-title">UpdateProduct</span>(<span class="hljs-params">
    UpdateProductRequest request, 
    ServerCallContext context</span>)</span>
{
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-comment">// Validate product ID</span>
        <span class="hljs-keyword">if</span> (!Guid.TryParse(request.Id, <span class="hljs-keyword">out</span> <span class="hljs-keyword">var</span> productId))
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> UpdateProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Invalid product ID format. Please provide a valid GUID."</span>
            };
        }

        <span class="hljs-comment">// Input validation</span>
        <span class="hljs-keyword">if</span> (<span class="hljs-keyword">string</span>.IsNullOrWhiteSpace(request.Name))
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> UpdateProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Product name is required"</span>
            };
        }

        <span class="hljs-keyword">if</span> (request.Price &lt;= <span class="hljs-number">0</span>)
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> UpdateProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Product price must be greater than zero"</span>
            };
        }

        <span class="hljs-comment">// Find existing product</span>
        <span class="hljs-keyword">var</span> existingProduct = <span class="hljs-keyword">await</span> _dbContext.Products.FindAsync(productId);

        <span class="hljs-keyword">if</span> (existingProduct == <span class="hljs-literal">null</span>)
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> UpdateProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Product not found"</span>
            };
        }

        <span class="hljs-comment">// Update product properties</span>
        existingProduct.Name = request.Name;
        existingProduct.Description = request.Description;
        existingProduct.Price = Convert.ToDecimal(request.Price);
        existingProduct.Tags = request.Tags;
        existingProduct.Updated = DateTime.UtcNow; <span class="hljs-comment">// Track when updated</span>

        <span class="hljs-comment">// Save changes to database</span>
        <span class="hljs-keyword">await</span> _dbContext.SaveChangesAsync();

        _logger.LogInformation(<span class="hljs-string">"Product updated successfully with ID: {ProductId}"</span>, productId);

        <span class="hljs-comment">// Return success response with updated product</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> UpdateProductResponse
        {
            Success = <span class="hljs-literal">true</span>,
            Message = <span class="hljs-string">"Product updated successfully"</span>,
            Product = MapToProductModel(existingProduct)
        };
    }
    <span class="hljs-keyword">catch</span> (Exception ex)
    {
        _logger.LogError(ex, <span class="hljs-string">"Error updating product with ID: {ProductId}"</span>, request.Id);

        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> UpdateProductResponse
        {
            Success = <span class="hljs-literal">false</span>,
            Message = <span class="hljs-string">$"Error updating product: <span class="hljs-subst">{ex.Message}</span>"</span>
        };
    }
}
</code></pre>
<p>Key details:</p>
<ul>
<li><p><strong>Existence check</strong>: Verifies the product exists before attempting updates</p>
</li>
<li><p><strong>Selective updates</strong>: Only updates the fields provided in the request</p>
</li>
<li><p><strong>Timestamp tracking</strong>: Updates the <code>Updated</code> field to track modification time</p>
</li>
<li><p><strong>Input validation</strong>: Ensures data integrity before saving</p>
</li>
<li><p><strong>Atomic operation</strong>: All changes are saved together or not at all</p>
</li>
</ul>
<h3 id="heading-creating-the-deleteproduct-service">Creating the <code>DeleteProduct</code> Service</h3>
<p>The <code>DeleteProduct</code> method removes products from the database. This is the <strong>"D"</strong> in CRUD (Delete).</p>
<pre><code class="lang-cs"> <span class="hljs-comment">// Services/ProductService.cs</span>
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">async</span> Task&lt;DeleteProductResponse&gt; <span class="hljs-title">DeleteProduct</span>(<span class="hljs-params">
    DeleteProductRequest request, 
    ServerCallContext context</span>)</span>
{
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-comment">// Validate product ID</span>
        <span class="hljs-keyword">if</span> (!Guid.TryParse(request.Id, <span class="hljs-keyword">out</span> <span class="hljs-keyword">var</span> productId))
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> DeleteProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Invalid product ID format. Please provide a valid GUID."</span>
            };
        }

        <span class="hljs-comment">// Find the product to delete</span>
        <span class="hljs-keyword">var</span> product = <span class="hljs-keyword">await</span> _dbContext.Products.FindAsync(productId);

        <span class="hljs-keyword">if</span> (product == <span class="hljs-literal">null</span>)
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> DeleteProductResponse
            {
                Success = <span class="hljs-literal">false</span>,
                Message = <span class="hljs-string">"Product not found"</span>
            };
        }

        <span class="hljs-comment">// Remove product from database</span>
        _dbContext.Products.Remove(product);
        <span class="hljs-keyword">await</span> _dbContext.SaveChangesAsync();

        _logger.LogInformation(<span class="hljs-string">"Product deleted successfully with ID: {ProductId}"</span>, productId);

        <span class="hljs-comment">// Return success response</span>
        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> DeleteProductResponse
        {
            Success = <span class="hljs-literal">true</span>,
            Message = <span class="hljs-string">"Product deleted successfully"</span>
        };
    }
    <span class="hljs-keyword">catch</span> (Exception ex)
    {
        _logger.LogError(ex, <span class="hljs-string">"Error deleting product with ID: {ProductId}"</span>, request.Id);

        <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> DeleteProductResponse
        {
            Success = <span class="hljs-literal">false</span>,
            Message = <span class="hljs-string">$"Error deleting product: <span class="hljs-subst">{ex.Message}</span>"</span>
        };
    }
}
</code></pre>
<p>Key details:</p>
<ul>
<li><p><strong>Soft vs hard delete</strong>: This implements hard delete (permanent removal)</p>
</li>
<li><p><strong>Existence verification</strong>: Checks if the product exists before deletion</p>
</li>
<li><p><strong>Clean removal</strong>: Uses Entity Framework's <code>Remove()</code> method</p>
</li>
<li><p><strong>Confirmation</strong>: Returns a success message confirming deletion</p>
</li>
</ul>
<h3 id="heading-complete-productservice-implementation">Complete ProductService Implementation</h3>
<p>Here's your complete <code>ProductService.cs</code> file with all CRUD operations:</p>
<pre><code class="lang-cs"><span class="hljs-comment">// Services/ProductService.cs</span>
<span class="hljs-keyword">using</span> Grpc.Core;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> ProductGrpc.Data;
<span class="hljs-keyword">using</span> ProductGrpc.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">ProductGrpc.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ProductService</span> : <span class="hljs-title">Product.ProductServiceBase</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> AppDbContext _dbContext;
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;ProductService&gt; _logger;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ProductService</span>(<span class="hljs-params">AppDbContext dbContext, ILogger&lt;ProductService&gt; logger</span>)</span>
        {
            _dbContext = dbContext;
            _logger = logger;
        }

        <span class="hljs-comment">// Helper method to map Product entity to ProductModel message</span>
        <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ProductModel <span class="hljs-title">MapToProductModel</span>(<span class="hljs-params">Product product</span>)</span>
        {
            <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> ProductModel
            {
                Id = product.Id.ToString(),
                Name = product.Name,
                Description = product.Description,
                Price = (<span class="hljs-keyword">double</span>)product.Price,
                CreatedAt = product.Created.ToString(<span class="hljs-string">"yyyy-MM-ddTHH:mm:ssZ"</span>),
                UpdatedAt = product.Updated.ToString(<span class="hljs-string">"yyyy-MM-ddTHH:mm:ssZ"</span>),
                Tags = product.Tags ?? <span class="hljs-keyword">string</span>.Empty
            };
        }

        <span class="hljs-comment">// All CRUD methods go here (as implemented above)</span>
        <span class="hljs-comment">// CreateProduct, GetProduct, ListProducts, UpdateProduct, DeleteProduct</span>
    }
}
</code></pre>
<p>Excellent work! You've successfully implemented all CRUD operations:</p>
<ul>
<li><p><strong>Create</strong>: Add new products with validation</p>
</li>
<li><p><strong>Read</strong>: Retrieve single products and paginated lists</p>
</li>
<li><p><strong>Update</strong>: Modify existing products with validation</p>
</li>
<li><p><strong>Delete</strong>: Remove products safely</p>
</li>
</ul>
<h3 id="heading-whats-next-3">What's Next?</h3>
<p>Now that our gRPC service is fully implemented, we need to test it! In the next section, we'll learn how to test our gRPC endpoints using Postman.</p>
<h2 id="heading-how-to-test-grpc-services-with-postman">How to Test gRPC Services with Postman</h2>
<p>Testing gRPC services requires different tools and approaches compared to traditional REST APIs. While REST APIs use HTTP/1.1 with JSON payloads, gRPC uses HTTP/2 with binary Protocol Buffer messages. Fortunately, Postman provides excellent support for gRPC testing, making it easy to test our service without writing client code.</p>
<h3 id="heading-why-grpc-testing-is-different">Why gRPC Testing is Different</h3>
<p>Here are the important differences between gRPC and REST API testing summarized:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Aspect</td><td>REST API</td><td>gRPC</td></tr>
</thead>
<tbody>
<tr>
<td><strong>Protocol</strong></td><td>HTTP/1.1</td><td>HTTP/2</td></tr>
<tr>
<td><strong>Data Format</strong></td><td>JSON/XML</td><td>Protocol Buffers (Binary)</td></tr>
<tr>
<td><strong>Schema</strong></td><td>Optional (OpenAPI/Swagger)</td><td>Required (.proto files)</td></tr>
<tr>
<td><strong>Content-Type</strong></td><td>application/json</td><td>application/grpc</td></tr>
<tr>
<td><strong>Testing Tools</strong></td><td>Any HTTP client</td><td>Specialized gRPC clients</td></tr>
</tbody>
</table>
</div><p>Why we need the proto file:</p>
<ul>
<li><p>gRPC requires the service contract (.proto file) to understand available methods</p>
</li>
<li><p>Protocol Buffers need schema definition for serialization/deserialization</p>
</li>
<li><p>Postman uses the proto file to generate the correct request/response structure</p>
</li>
</ul>
<h3 id="heading-setting-up-postman-for-grpc-testing">Setting Up Postman for gRPC Testing</h3>
<h4 id="heading-step-1-launch-postman">Step 1: Launch Postman</h4>
<p>Open Postman on your machine. You should see the main dashboard similar to this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753879108777/a98c6fa4-08c7-49f1-94a4-9138b69ad0a1.png" alt="Postman main dashboard showing the workspace interface" width="1908" height="1040" loading="lazy"></p>
<h4 id="heading-step-2-create-a-new-grpc-request">Step 2: Create a New gRPC Request</h4>
<p>Click on "New" in the top-left corner or use the "+" button. Then select "gRPC Request" from the available options.</p>
<p>You should see a modal dialog with different request types:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753879545910/840f2004-73c5-4c1e-97a6-62b39eb278f9.png" alt="Postman's new request modal showing gRPC option" width="2560" height="1371" loading="lazy"></p>
<p>Click on "gRPC Request" to create a new gRPC request.</p>
<h4 id="heading-step-3-configure-the-grpc-request-interface">Step 3: Configure the gRPC Request Interface</h4>
<p>After creating a gRPC request, you'll see the gRPC request interface:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753879652894/b339e198-27e9-4618-8cdb-54718da65841.png" alt="Postman gRPC request interface with service definition section" width="2560" height="1388" loading="lazy"></p>
<p>These are the notable components of the gRPC interface:</p>
<ul>
<li><p><strong>Server URL</strong>: Where your gRPC service is running</p>
</li>
<li><p><strong>Service definition</strong>: Where you import your .proto file</p>
</li>
<li><p><strong>Method selection</strong>: Choose which RPC method to call</p>
</li>
<li><p><strong>Message body</strong>: Request payload based on proto definitions</p>
</li>
</ul>
<h3 id="heading-importing-the-proto-file">Importing the Proto File</h3>
<h4 id="heading-step-4-access-service-definition">Step 4: Access Service Definition</h4>
<p>Locate the "Service definition" section in the gRPC request interface. Then click on "Import .proto file" or a similar option.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753879690499/b2d53cab-3d0c-4c84-8a12-7777480e6860.png" alt="Service definition section where proto files are imported" width="2560" height="1393" loading="lazy"></p>
<h4 id="heading-step-5-import-your-proto-file">Step 5: Import Your Proto File</h4>
<ol>
<li><p>Click "Select Files" or "Import" button</p>
</li>
<li><p>Navigate to your project directory</p>
</li>
<li><p>Go to the <code>Protos</code> folder</p>
</li>
<li><p>Select <code>product.proto</code> file</p>
</li>
<li><p>Click "Open" to import</p>
</li>
</ol>
<p><strong>File Path Structure:</strong></p>
<pre><code class="lang-bash">YourProject/
├── Protos/
│   ├── greet.proto
│   └── product.proto    ← Select this file
└── ...
</code></pre>
<h4 id="heading-step-6-configure-import-settings">Step 6: Configure Import Settings</h4>
<p>When importing, you'll see options like:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753879892390/625b1fbd-cdd6-4437-af9e-441a39780c5e.png" alt="Proto file import configuration in Postman" width="2560" height="1393" loading="lazy"></p>
<p><strong>Import Configuration:</strong></p>
<ul>
<li><p><strong>Import as</strong>: Select "API"</p>
</li>
<li><p><strong>API name</strong>: Choose a descriptive name (for example, "ProductGrpc API")</p>
</li>
<li><p><strong>Import location</strong>: Select your workspace</p>
</li>
</ul>
<p>You want to import as an API because it creates a reusable API definition, allows multiple team members to use the same proto definitions, and provides better organization for multiple services.</p>
<h4 id="heading-step-7-verify-successful-import">Step 7: Verify Successful Import</h4>
<p>After successful import, you should see:</p>
<ol>
<li><p><strong>API Collection</strong>: Your named API appears in the left sidebar under "APIs."</p>
</li>
<li><p><strong>Available Methods</strong>: All RPC methods from your proto file are listed</p>
</li>
<li><p><strong>Request/Response Schemas</strong>: Postman understands your message structures</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753879919558/a9c264a6-b021-4c7a-8221-557350c07f53.png" alt="Successfully imported proto file showing available methods" width="2560" height="1393" loading="lazy"></p>
<h3 id="heading-understanding-the-grpc-request-interface">Understanding the gRPC Request Interface</h3>
<p>Once connected, you'll see a method selection dropdown with the following:</p>
<ul>
<li><p>CreateProduct</p>
</li>
<li><p>GetProduct</p>
</li>
<li><p>ListProducts</p>
</li>
<li><p>UpdateProduct</p>
</li>
<li><p>DeleteProduct</p>
</li>
</ul>
<p>Excellent! You've successfully created a gRPC request in Postman, imported your proto file, configured the server connection, and set up the API collection for reuse.</p>
<h3 id="heading-whats-next-4">What's Next?</h3>
<p>Now that Postman is configured with your proto file, you're ready to test each CRUD operation:</p>
<ol>
<li><p><strong>CreateProduct</strong>: Test adding new products</p>
</li>
<li><p><strong>GetProduct</strong>: Test retrieving single products</p>
</li>
<li><p><strong>ListProducts</strong>: Test pagination and listing</p>
</li>
<li><p><strong>UpdateProduct</strong>: Test modifying existing products</p>
</li>
<li><p><strong>DeleteProduct</strong>: Test removing products</p>
</li>
</ol>
<p>In the next section, we'll walk through testing each operation with sample data and expected responses.</p>
<h2 id="heading-how-to-test-product-creation">How to Test Product Creation</h2>
<p>Now that we have Postman configured with our proto file, it's time to test our gRPC service! We'll start by testing the <code>CreateProduct</code> Method to add a new product to our database.</p>
<h3 id="heading-request-structure">Request Structure</h3>
<p>Before sending your first request in Postman, select the RPC method from the dropdown. The request body’s shape comes directly from the Protocol Buffer definitions in your <code>.proto</code> file. Postman renders those proto messages as JSON for easier editing, but the proto types still apply: each field must match the type defined in the schema (including nested messages, enums, and repeated fields).</p>
<h3 id="heading-step-1-select-the-createproduct-method">Step 1: Select the CreateProduct Method</h3>
<p>Open your gRPC request in Postman and click the method dropdown (should show available methods). Select "CreateProduct" from the list.</p>
<p>You should see all the methods we defined in our proto file:</p>
<ul>
<li><p>CreateProduct</p>
</li>
<li><p>GetProduct</p>
</li>
<li><p>ListProducts</p>
</li>
<li><p>UpdateProduct</p>
</li>
<li><p>DeleteProduct</p>
</li>
</ul>
<h3 id="heading-step-2-request-schema">Step 2: Request Schema</h3>
<p>When you select <code>CreateProduct</code>, Postman automatically generates the request structure based on our <code>CreateProductRequest</code> message from the proto file:</p>
<p><strong>Proto Definition Reminder:</strong></p>
<pre><code class="lang-csharp">message CreateProductRequest {
  <span class="hljs-keyword">string</span> name = <span class="hljs-number">1</span>;
  <span class="hljs-keyword">string</span> description = <span class="hljs-number">2</span>;
  <span class="hljs-keyword">double</span> price = <span class="hljs-number">3</span>;
  <span class="hljs-keyword">string</span> tags = <span class="hljs-number">4</span>;
}
</code></pre>
<p><strong>Postman JSON Representation:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">""</span>,
  <span class="hljs-attr">"price"</span>: <span class="hljs-number">0</span>,
  <span class="hljs-attr">"tags"</span>: <span class="hljs-string">""</span>
}
</code></pre>
<h3 id="heading-step-3-prepare-test-data">Step 3: Prepare Test Data</h3>
<p>Let's create our first product with meaningful test data. In the request body, enter:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"MacBook Pro 16-inch"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Apple MacBook Pro with M2 Pro chip, 16GB RAM, 512GB SSD"</span>,
  <span class="hljs-attr">"price"</span>: <span class="hljs-number">2499.99</span>,
  <span class="hljs-attr">"tags"</span>: <span class="hljs-string">"laptop, apple, professional"</span>
}
</code></pre>
<p>So what are these fields?</p>
<ul>
<li><p><strong>name</strong>: Product title (required, string)</p>
</li>
<li><p><strong>description</strong>: Detailed product information (string)</p>
</li>
<li><p><strong>price</strong>: Product cost (double/number, must be &gt; 0)</p>
</li>
<li><p><strong>tags</strong>: Comma-separated keywords (string)</p>
</li>
</ul>
<h3 id="heading-step-4-send-the-request">Step 4: Send the Request</h3>
<p>Click the "Invoke" button (or "Send" depending on Postman version) and wait for the response (should be very fast for local testing). Then check the response status (should show success).</p>
<h3 id="heading-step-5-analyze-the-response">Step 5: Analyze the Response</h3>
<p>If everything works correctly, you should receive a response like this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"success"</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Product created successfully"</span>,
  <span class="hljs-attr">"product"</span>: {
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"920b98d2-4feb-4705-8303-ce6e28bd3694"</span>,
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"MacBook Pro 16-inch"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Apple MacBook Pro with M2 Pro chip, 16GB RAM, 512GB SSD"</span>,
    <span class="hljs-attr">"price"</span>: <span class="hljs-number">2499.99</span>,
    <span class="hljs-attr">"created_at"</span>: <span class="hljs-string">"2024-01-15T16:11:38Z"</span>,
    <span class="hljs-attr">"updated_at"</span>: <span class="hljs-string">"2024-01-15T16:11:38Z"</span>,
    <span class="hljs-attr">"tags"</span>: <span class="hljs-string">"laptop, apple, professional"</span>
  }
}
</code></pre>
<p>Response fields:</p>
<ul>
<li><p><strong>success</strong>: Boolean indicating operation success</p>
</li>
<li><p><strong>message</strong>: Human-readable status message</p>
</li>
<li><p><strong>product</strong>: The created product with generated fields</p>
<ul>
<li><p><strong>id</strong>: Auto-generated GUID</p>
</li>
<li><p><strong>created_at/updated_at</strong>: UTC timestamps</p>
</li>
<li><p><strong>Other fields</strong>: Echo of the input data</p>
</li>
</ul>
</li>
</ul>
<h3 id="heading-visual-confirmation-in-postman">Visual Confirmation in Postman</h3>
<p>Here's how a successful request looks in Postman:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753880143034/f7e81267-8d45-4835-b1d9-ad091563b99c.png" alt="Postman interface showing successful product creation with request and response" width="2511" height="1342" loading="lazy"></p>
<p>Congratulations! You've successfully made your first gRPC request using Postman! You’ve also created a product in the database, received a properly formatted response, and verified the auto-generated ID and timestamps.</p>
<h3 id="heading-whats-next-5">What's Next?</h3>
<p>Now that we've successfully tested product creation, let's test the other CRUD operations:</p>
<ol>
<li><p><strong>GetProduct</strong>: Retrieve the product we just created</p>
</li>
<li><p><strong>ListProducts</strong>: See all products with pagination</p>
</li>
<li><p><strong>UpdateProduct</strong>: Modify the existing product</p>
</li>
<li><p><strong>DeleteProduct</strong>: Remove the product from the database</p>
</li>
</ol>
<p>Each operation will help us verify that our complete gRPC service is working correctly.</p>
<h2 id="heading-how-to-test-all-product-operations">How to Test All Product Operations</h2>
<p>Now that we've successfully created a product, let's test all the remaining CRUD operations to ensure our complete gRPC service works correctly.</p>
<h3 id="heading-get-all-products-listproducts">Get All Products (ListProducts)</h3>
<p>The <code>ListProducts</code> method retrieves all products from our database with pagination support. Since we've created some products, we should be able to see them in the response.</p>
<h4 id="heading-step-1-select-listproducts-method">Step 1: Select ListProducts Method</h4>
<p>Click the method dropdown in your Postman gRPC request. Then select "ListProducts" from the available methods. Notice the request structure – it includes pagination parameters.</p>
<h4 id="heading-step-2-configure-the-request">Step 2: Configure the Request</h4>
<p>The <code>ListProductsRequest</code> supports pagination parameters:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"page"</span>: <span class="hljs-number">1</span>,
  <span class="hljs-attr">"pageSize"</span>: <span class="hljs-number">10</span>
}
</code></pre>
<p>Here’s what’s going on with these parameters:</p>
<ul>
<li><p><strong>page</strong>: Which page of results to retrieve (default: 1)</p>
</li>
<li><p><strong>pageSize</strong>: Number of products per page (default: 10, max: 100)</p>
</li>
</ul>
<h4 id="heading-step-3-send-the-request">Step 3: Send the Request</h4>
<p>Click "Invoke" to send the request and wait for the response containing all your products.</p>
<h4 id="heading-step-4-response">Step 4: Response</h4>
<p>You should receive a response like this:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"success"</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Retrieved 2 products (Page 1 of 1)"</span>,
  <span class="hljs-attr">"totalCount"</span>: <span class="hljs-number">2</span>,
  <span class="hljs-attr">"products"</span>: [
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"920b98d2-4feb-4705-8303-ce6e28bd3694"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"MacBook Pro 16-inch"</span>,
      <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Apple MacBook Pro with M2 Pro chip, 16GB RAM, 512GB SSD"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">2499.99</span>,
      <span class="hljs-attr">"created_at"</span>: <span class="hljs-string">"2024-01-15T16:11:38Z"</span>,
      <span class="hljs-attr">"updated_at"</span>: <span class="hljs-string">"2024-01-15T16:11:38Z"</span>,
      <span class="hljs-attr">"tags"</span>: <span class="hljs-string">"laptop, apple, professional"</span>
    },
    {
      <span class="hljs-attr">"id"</span>: <span class="hljs-string">"a1b2c3d4-5e6f-7890-abcd-ef1234567890"</span>,
      <span class="hljs-attr">"name"</span>: <span class="hljs-string">"iPhone 15 Pro"</span>,
      <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Latest iPhone with titanium design"</span>,
      <span class="hljs-attr">"price"</span>: <span class="hljs-number">999.99</span>,
      <span class="hljs-attr">"created_at"</span>: <span class="hljs-string">"2024-01-15T16:15:22Z"</span>,
      <span class="hljs-attr">"updated_at"</span>: <span class="hljs-string">"2024-01-15T16:15:22Z"</span>,
      <span class="hljs-attr">"tags"</span>: <span class="hljs-string">"smartphone, apple, premium"</span>
    }
  ]
}
</code></pre>
<p>Response structure:</p>
<ul>
<li><p><strong>success</strong>: Operation status</p>
</li>
<li><p><strong>message</strong>: Descriptive message with pagination info</p>
</li>
<li><p><strong>totalCount</strong>: Total number of products in the database</p>
</li>
<li><p><strong>products</strong>: Array of product objects</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753880306062/af0bd1d4-24d0-4be8-96a1-f59404f36672.png" alt="Postman showing successful retrieval of all products with pagination" width="2469" height="1384" loading="lazy"></p>
<h3 id="heading-testing-pagination">Testing Pagination</h3>
<p>Let’s now test some different pagination scenarios:</p>
<p><strong>Get the first 5 products:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"page"</span>: <span class="hljs-number">1</span>,
  <span class="hljs-attr">"pageSize"</span>: <span class="hljs-number">5</span>
}
</code></pre>
<p><strong>Get the second page:</strong></p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"page"</span>: <span class="hljs-number">2</span>,
  <span class="hljs-attr">"pageSize"</span>: <span class="hljs-number">5</span>
}
</code></pre>
<h3 id="heading-get-product-by-id-getproduct">Get Product By ID (GetProduct)</h3>
<p>The <code>GetProduct</code> method retrieves a single product using its unique ID. Unlike REST APIs, where the ID is part of the URL path, gRPC passes the ID in the message body.</p>
<h4 id="heading-step-1-select-the-getproduct-method">Step 1: Select the GetProduct Method</h4>
<p>Select "GetProduct" from the method dropdown. Notice that the request structure requires an ID field.</p>
<h4 id="heading-step-2-prepare-the-request">Step 2: Prepare the Request</h4>
<p>Copy a product ID from your previous <code>ListProducts</code> response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"id"</span>: <span class="hljs-string">"920b98d2-4feb-4705-8303-ce6e28bd3694"</span>
}
</code></pre>
<p>Important notes:</p>
<ul>
<li><p><strong>ID Format</strong>: Must be a valid GUID string</p>
</li>
<li><p><strong>Case Sensitivity</strong>: GUIDs are case-insensitive</p>
</li>
<li><p><strong>Validation</strong>: Invalid GUIDs will return an error</p>
</li>
</ul>
<h4 id="heading-step-3-send-the-request-1">Step 3: Send the Request</h4>
<p>Paste a valid product ID from your ListProducts response. Click "Invoke" to send the request.</p>
<h4 id="heading-step-4-analyze-the-response">Step 4: Analyze the Response</h4>
<p>Successful response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"success"</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Product retrieved successfully"</span>,
  <span class="hljs-attr">"product"</span>: {
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"920b98d2-4feb-4705-8303-ce6e28bd3694"</span>,
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"MacBook Pro 16-inch"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Apple MacBook Pro with M2 Pro chip, 16GB RAM, 512GB SSD"</span>,
    <span class="hljs-attr">"price"</span>: <span class="hljs-number">2499.99</span>,
    <span class="hljs-attr">"created_at"</span>: <span class="hljs-string">"2024-01-15T16:11:38Z"</span>,
    <span class="hljs-attr">"updated_at"</span>: <span class="hljs-string">"2024-01-15T16:11:38Z"</span>,
    <span class="hljs-attr">"tags"</span>: <span class="hljs-string">"laptop, apple, professional"</span>
  }
}
</code></pre>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753880592637/ebbacee5-1333-4328-8c46-ab7dd24d824d.png" alt="Postman showing successful retrieval of a single product by ID" width="2550" height="1377" loading="lazy"></p>
<h3 id="heading-update-product-updateproduct">Update Product (UpdateProduct)</h3>
<p>The <code>UpdateProduct</code> method modifies an existing product. You need to provide the product ID and the fields you want to update.</p>
<h4 id="heading-step-1-select-the-updateproduct-method">Step 1: Select the UpdateProduct Method</h4>
<p>Select "UpdateProduct" from the method dropdown. Review the request structure which includes ID and all updatable fields.</p>
<h4 id="heading-step-2-prepare-the-update-request">Step 2: Prepare the Update Request</h4>
<pre><code class="lang-json">{
  <span class="hljs-attr">"id"</span>: <span class="hljs-string">"920b98d2-4feb-4705-8303-ce6e28bd3694"</span>,
  <span class="hljs-attr">"name"</span>: <span class="hljs-string">"MacBook Pro 16-inch (Updated)"</span>,
  <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Apple MacBook Pro with M2 Pro chip, 16GB RAM, 1TB SSD - Updated Storage"</span>,
  <span class="hljs-attr">"price"</span>: <span class="hljs-number">2799.99</span>,
  <span class="hljs-attr">"tags"</span>: <span class="hljs-string">"laptop, apple, professional, updated"</span>
}
</code></pre>
<p>Update guidelines:</p>
<ul>
<li><p><strong>ID</strong>: Must match an existing product</p>
</li>
<li><p><strong>All Fields</strong>: Currently required (not partial updates)</p>
</li>
<li><p><strong>Price</strong>: Must be greater than 0</p>
</li>
<li><p><strong>Name</strong>: Cannot be empty</p>
</li>
</ul>
<h4 id="heading-step-3-send-the-update-request">Step 3: Send the Update Request</h4>
<p>Make sure the ID exists (use one from your ListProducts response). Then click "Invoke" to send the update.</p>
<h4 id="heading-step-4-verify-the-update">Step 4: Verify the Update</h4>
<p>Successful response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"success"</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Product updated successfully"</span>,
  <span class="hljs-attr">"product"</span>: {
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"920b98d2-4feb-4705-8303-ce6e28bd3694"</span>,
    <span class="hljs-attr">"name"</span>: <span class="hljs-string">"MacBook Pro 16-inch (Updated)"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Apple MacBook Pro with M2 Pro chip, 16GB RAM, 1TB SSD - Updated Storage"</span>,
    <span class="hljs-attr">"price"</span>: <span class="hljs-number">2799.99</span>,
    <span class="hljs-attr">"created_at"</span>: <span class="hljs-string">"2024-01-15T16:11:38Z"</span>,
    <span class="hljs-attr">"updated_at"</span>: <span class="hljs-string">"2024-01-15T16:25:14Z"</span>,
    <span class="hljs-attr">"tags"</span>: <span class="hljs-string">"laptop, apple, professional, updated"</span>
  }
}
</code></pre>
<p>Notice the changes:</p>
<ul>
<li><p><strong>updated_at</strong>: Timestamp changed to reflect the update</p>
</li>
<li><p><strong>Modified Fields</strong>: All updated fields reflect new values</p>
</li>
<li><p><strong>created_at</strong>: Remains unchanged (original creation time)</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753880928160/d12e58ff-3c14-49f6-a3dd-1d1d2c452e09.png" alt="Postman showing successful product update with modified fields" width="2524" height="1327" loading="lazy"></p>
<h3 id="heading-delete-product-by-id-deleteproduct">Delete Product By ID (DeleteProduct)</h3>
<p>The <code>DeleteProduct</code> method permanently removes a product from the database using its ID.</p>
<h4 id="heading-step-1-select-deleteproduct-method">Step 1: Select DeleteProduct Method</h4>
<p>Select "DeleteProduct" from the method dropdown. Note the simple request structure – it only requires an ID.</p>
<h4 id="heading-step-2-prepare-the-delete-request">Step 2: Prepare the Delete Request</h4>
<pre><code class="lang-json">{
  <span class="hljs-attr">"id"</span>: <span class="hljs-string">"a1b2c3d4-5e6f-7890-abcd-ef1234567890"</span>
}
</code></pre>
<p><strong>⚠️ Warning</strong>: This operation permanently deletes the product. Make sure you're using the correct ID.</p>
<h4 id="heading-step-3-send-the-delete-request">Step 3: Send the Delete Request</h4>
<p>Double-check the product ID you want to delete. Click "Invoke" to send the delete request.</p>
<h4 id="heading-step-4-confirm-deletion">Step 4: Confirm Deletion</h4>
<p>Successful response:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"success"</span>: <span class="hljs-literal">true</span>,
  <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Product deleted successfully"</span>
}
</code></pre>
<p>Verification steps:</p>
<ol>
<li><p><strong>Try GetProduct</strong> with the same ID – it should return "Product not found"</p>
</li>
<li><p><strong>Run ListProducts</strong> – the product should no longer appear in the list</p>
</li>
<li><p><strong>Check totalCount</strong> – should be reduced by 1</p>
</li>
</ol>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1753880987953/23bb19f0-7ca0-4cec-b9bb-3774737f98c9.png" alt="Postman showing successful product deletion" width="2514" height="1372" loading="lazy"></p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Congratulations! 🎉 You've successfully completed this comprehensive journey into building gRPC services with ASP.NET Core. Throughout this handbook, you've gained hands-on experience with one of the most powerful and efficient communication frameworks available for modern distributed applications.</p>
<h3 id="heading-what-youve-accomplished">What You've Accomplished</h3>
<p>Let's recap the impressive skills and knowledge you've acquired:</p>
<h4 id="heading-foundation-building">Foundation building</h4>
<ul>
<li><p>Set up a complete gRPC project from scratch using .NET CLI</p>
</li>
<li><p>Configured SQLite database with Entity Framework Core</p>
</li>
<li><p>Created robust data models with proper validation</p>
</li>
<li><p>Implemented database migrations and seeding</p>
</li>
</ul>
<h4 id="heading-learning-protocol-buffers">Learning protocol buffers</h4>
<ul>
<li><p>Designed comprehensive .proto files with service definitions</p>
</li>
<li><p>Created strongly-typed message contracts for all CRUD operations</p>
</li>
<li><p>Understood the advantages of binary serialization over JSON</p>
</li>
<li><p>Implemented efficient data transfer objects (DTOs)</p>
</li>
</ul>
<h4 id="heading-service-implementation">Service implementation</h4>
<ul>
<li><p>Built a complete ProductService with all CRUD operations</p>
</li>
<li><p>Implemented proper error handling and validation</p>
</li>
<li><p>Added comprehensive logging for debugging and monitoring</p>
</li>
<li><p>Created efficient pagination for large datasets</p>
</li>
<li><p>Handled data mapping between entities and Protocol Buffer messages</p>
</li>
</ul>
<h4 id="heading-testing-and-validation">Testing and validation</h4>
<ul>
<li><p>Configured Postman for gRPC testing</p>
</li>
<li><p>Tested all CRUD operations with real data</p>
</li>
<li><p>Verified data integrity and proper response formatting</p>
</li>
</ul>
<h3 id="heading-key-technical-skills-gained">Key Technical Skills Gained</h3>
<p><strong>gRPC Expertise:</strong></p>
<ul>
<li><p>Understanding of the HTTP/2 protocol advantages</p>
</li>
<li><p>Protocol Buffer schema design and evolution</p>
</li>
<li><p>Service-to-service communication patterns</p>
</li>
<li><p>Performance optimization techniques</p>
</li>
</ul>
<h4 id="heading-you-can-access-the-code-in-this-github-repositoryhttpsgithubcomclifftech123isaiahcliffordopokublog">🔗 You can access the code <a target="_blank" href="https://github.com/Clifftech123/IsaiahCliffordOpokuBlog">in this GitHub Repository</a>.</h4>
<h3 id="heading-thank-you">Thank You!</h3>
<p>Thank you for following along with this comprehensive tutorial. Your dedication to learning these advanced concepts will serve you well in building the next generation of distributed applications.</p>
<p><strong>Happy coding, and may your services be fast, reliable, and scalable!</strong></p>
<p>If you want to learn more about .NET Core, you can subscribe to my YouTube channel <a target="_blank" href="https://youtube.com/@clifftech?si=QgdE39q4iYIPEN23">here</a>.</p>
<p><strong>🔗 Connect with the author:</strong></p>
<ul>
<li><p>GitHub: <a target="_blank" href="https://github.com/Clifftech123">@CliffTech123</a></p>
</li>
<li><p>Twitter: <a target="_blank" href="https://x.com/Clifftech_Dev">@Clifftech_Dev</a></p>
</li>
<li><p>LinkedIn: <a target="_blank" href="https://www.linkedin.com/in/isaiah-clifford-opoku/">Isaiah Clifford Opoku</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn Async Programming in TypeScript: Promises, Async/Await, and Callbacks [Full Handbook] ]]>
                </title>
                <description>
                    <![CDATA[ Async programming is a programming paradigm that allows you to write code that runs asynchronously. In contrast to synchronous programming, which executes code sequentially, async programming allows code to run in the background while the rest of the... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/learn-async-programming-in-typescript-promises-asyncawait-and-callbacks/</link>
                <guid isPermaLink="false">679ced2e80ebdc55d3ee44c8</guid>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ asynchronous ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Fri, 31 Jan 2025 15:33:02 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1737747600016/f6df015b-cc25-4c37-8c4e-bec9c8c49dc5.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Async programming is a programming paradigm that allows you to write code that runs <code>asynchronously</code>. In contrast to synchronous programming, which executes code sequentially, async programming allows code to run in the background while the rest of the program continues to execute. This is particularly useful for tasks that may take a long time to complete, such as fetching data from a remote API.</p>
<p><code>Async programming</code> is essential for creating responsive and efficient applications in JavaScript. TypeScript, a superset of JavaScript, makes it even easier to work with async programming.</p>
<p>There are several approaches to <code>async programming</code> in TypeScript, including using <code>promises</code>, <code>async/await</code>, and <code>callbacks</code>. We will cover each of these approaches in detail so that you can choose the best one(s) for your use case.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ol>
<li><p><a class="post-section-overview" href="#heading-why-is-async-programming-important">Why is Async Programming Important?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-typescript-makes-async-programming-easier">How TypeScript Makes Async Programming Easier</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-promises-in-typescript">How to Use Promises in TypeScript</a></p>
<ul>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-promise">How to Create a Promise</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-chain-promises">How to Chain Promises</a></p>
</li>
</ul>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-async-await-in-typescript">How to Use Async / Await in TypeScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-use-callbacks-in-typescript">How to Use Callbacks in TypeScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ol>
<h2 id="heading-why-is-async-programming-important">Why is Async Programming Important?</h2>
<p>Async programming is crucial for building responsive and efficient web applications. It allows tasks to run in the background while the rest of the program continues, keeping the user interface responsive to input. Also, async programming can boost overall performance by letting multiple tasks run at the same time.</p>
<p>There are many real-world examples of async programming, such as accessing user cameras and microphones and handling user input events. Even if you don't frequently create asynchronous functions, it's important to know how to use them correctly to make sure your application is reliable and performs well.</p>
<h3 id="heading-how-typescript-makes-async-programming-easier">How TypeScript Makes Async Programming Easier</h3>
<p>TypeScript offers several features that simplify async programming, including <code>type safety</code>, <code>type inference</code>, <code>type checking</code>, and <code>type annotations</code>.</p>
<p>With type safety, you can ensure your code behaves as expected, even when dealing with asynchronous functions. For instance, TypeScript can catch errors related to null and undefined values at compile time, saving you time and effort in debugging.</p>
<p>TypeScript's type inference and checking also reduce the amount of boilerplate code you need to write, making your code more concise and easier to read.</p>
<p>And TypeScript's type annotations provide clarity and documentation for your code, which is especially helpful when working with asynchronous functions that can be complex to understand.</p>
<p>Now let’s dive in and learn about these three key features of asynchronous programming: promises, async/await, and callbacks.</p>
<h2 id="heading-how-to-use-promises-in-typescript">How to Use Promises in TypeScript</h2>
<p><strong>Promises</strong> are a powerful tool for handling asynchronous operations in TypeScript. For instance, you might use a promise to fetch data from an external API or to perform a time-consuming task in the background while your main thread keeps running.</p>
<p>To use a Promise, you create a new instance of the <code>Promise</code> class and pass it a function that carries out the asynchronous operation. This function should call the resolve method with the result when the operation succeeds or the reject method with an error if it fails.</p>
<p>Once the Promise is created, you can attach callbacks to it using the <code>then</code> method. These callbacks will be triggered when the Promise is fulfilled, with the resolved value passed as a parameter. If the Promise is rejected, you can attach an error handler using the catch method, which will be called with the reason for the rejection.</p>
<p>Using Promises offers several advantages over traditional callback-based methods. For example, Promises can help prevent "callback hell," a common issue in asynchronous code where nested callbacks become hard to read and maintain.</p>
<p>Promises also make error handling in asynchronous code easier, as you can use the catch method to manage errors that occur anywhere in the Promise chain.</p>
<p>Finally, Promises can simplify your code by providing a consistent, composable way to handle asynchronous operations, regardless of their underlying implementation.</p>
<h3 id="heading-how-to-create-a-promise">How to Create a Promise</h3>
<p>Promise syntax:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> myPromise = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
  <span class="hljs-comment">// Do some asynchronous operation</span>
  <span class="hljs-comment">// If the operation is successful, call resolve with the result</span>
  <span class="hljs-comment">// If the operation fails, call reject with an error object</span>
});

myPromise
  .then(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
    <span class="hljs-comment">// Handle the successful result</span>
  })
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
    <span class="hljs-comment">// Handle the error</span>
  });
</code></pre>
<pre><code class="lang-typescript"><span class="hljs-comment">// Example 1 on how to create a promise</span>

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">myAsyncFunction</span>(<span class="hljs-params"></span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">string</span>&gt; </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-comment">// Some asynchronous operation</span>
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      <span class="hljs-comment">// Successful operation resolves promiseCheck out my latest blog post on mastering async programming in TypeScript! Learn how to work with Promises, Async/Await, and Callbacks to write efficient and scalable code. Get ready to take your TypeScript skills to the next level!</span>
      <span class="hljs-keyword">const</span> success = <span class="hljs-literal">true</span>;

      <span class="hljs-keyword">if</span> (success) {
        <span class="hljs-comment">// Resolve the promise with the operation result if the operation was successful</span>
        resolve(
          <span class="hljs-string">`The result is success and your operation result is <span class="hljs-subst">${operationResult}</span>`</span>
        );
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">const</span> rejectCode: <span class="hljs-built_in">number</span> = <span class="hljs-number">404</span>;
        <span class="hljs-keyword">const</span> rejectMessage: <span class="hljs-built_in">string</span> = <span class="hljs-string">`The result is failed and your operation result is <span class="hljs-subst">${rejectCode}</span>`</span>;
        <span class="hljs-comment">// Reject the promise with the operation result if the operation failed</span>
        reject(<span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(rejectMessage));
      }
    }, <span class="hljs-number">2000</span>);
  });
}

<span class="hljs-comment">// Use the promise</span>
myAsyncFunction()
  .then(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(result); <span class="hljs-comment">// output : The result is success and your operation result is 4</span>
  })
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(error); <span class="hljs-comment">// output : The result is failed and your operation result is 404</span>
  });
</code></pre>
<p>In the example above, we have a function called <code>myAsyncFunction()</code> that returns a <code>promise</code>. We use the <code>Promise</code> constructor to create the promise, which takes a <code>callback function</code> with <code>resolve</code> and <code>reject</code> arguments. If the asynchronous operation is successful, we call the resolve function. If it fails, we call the reject function.</p>
<p>The promise object returned by the constructor has a <code>then()</code> method, which takes success and failure callback functions. If the promise resolves successfully, the success callback function is called with the result. If the promise is rejected, the failure callback function is called with an error message.</p>
<p>The promise object also has a <code>catch()</code> method used to handle errors that occur during the promise chain. The <code>catch()</code> method takes a callback function, which is called if any error occurs in the promise chain.</p>
<p>Now, let's move on to how to chain promises in TypeScript.</p>
<h3 id="heading-how-to-chain-promises">How to Chain Promises</h3>
<p>Chaining promises allows you to perform <code>multiple asynchronous operations</code> in sequence or in parallel. This is helpful when you need to carry out several async tasks one after another or at the same time. For instance, you might need to fetch data asynchronously and then process it asynchronously.</p>
<p>Let's look at an example of how to chain promises:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Example on how chaining promises works</span>
<span class="hljs-comment">// First promise</span>
<span class="hljs-keyword">const</span> promise1 = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> functionOne: <span class="hljs-built_in">string</span> = <span class="hljs-string">"This is the first promise function"</span>;
  <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
    resolve(functionOne);
  }, <span class="hljs-number">1000</span>);
});

<span class="hljs-comment">// Second promise</span>
<span class="hljs-keyword">const</span> promise2 = <span class="hljs-function">(<span class="hljs-params">data: <span class="hljs-built_in">number</span></span>) =&gt;</span> {
  <span class="hljs-keyword">const</span> functionTwo: <span class="hljs-built_in">string</span> = <span class="hljs-string">"This is the second second promise  function"</span>;
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Promise</span>(<span class="hljs-function">(<span class="hljs-params">resolve, reject</span>) =&gt;</span> {
    <span class="hljs-built_in">setTimeout</span>(<span class="hljs-function">() =&gt;</span> {
      resolve(<span class="hljs-string">` <span class="hljs-subst">${data}</span>  '+'  <span class="hljs-subst">${functionTwo}</span> `</span>);
    }, <span class="hljs-number">1000</span>);
  });
};

<span class="hljs-comment">// Chaining first and second promises together</span>
promise1
  .then(promise2)
  .then(<span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(result); <span class="hljs-comment">// output: This is the first promise function + This is the second second promise function</span>
  })
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(error);
  });
</code></pre>
<p>In the example above, we have two promises: <code>promise1</code> and <code>promise2</code>. <code>promise1</code> resolves after 1 second with the string "This is the first promise function." <code>promise2</code> takes a number as input and returns a promise that resolves after 1 second with a string that combines the input number and the string "This is the second promise function."</p>
<p>We chain the two promises together using the <code>then</code> method. The output <code>promise1</code> is passed as input to <code>promise2</code>. Finally, we use the <code>then</code> method again to log the output of <code>promise2</code> to the console. If either <code>promise1</code> or <code>promise2</code> rejects, the error will be caught by the <code>catch</code> method.</p>
<p>Congratulations! You have learned how to create and chain promises in TypeScript. You can now use promises to perform asynchronous operations in TypeScript. Now, let's explore how <code>Async/Await</code> works in TypeScript.</p>
<h2 id="heading-how-to-use-async-await-in-typescript">How to Use Async / Await in TypeScript</h2>
<p><strong>Async/await</strong> is a syntax introduced in ES2017 to make working with Promises easier. It allows you to write asynchronous code that looks and feels like synchronous code.</p>
<p>In TypeScript, you can define an asynchronous function using the <code>async</code> keyword. This tells the compiler that the function is asynchronous and will return a Promise.</p>
<p>Now, let's see how to use async/await in TypeScript.</p>
<p>Async / Await Syntax:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Async / Await Syntax in TypeScript</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">functionName</span>(<span class="hljs-params"></span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">ReturnType</span>&gt; </span>{
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> promise;
    <span class="hljs-comment">// code to execute after promise resolves</span>
    <span class="hljs-keyword">return</span> result;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-comment">// code to execute if promise rejects</span>
    <span class="hljs-keyword">throw</span> error;
  }
}
</code></pre>
<p>In the example above, <code>functionName</code> is an async function that returns a Promise of <code>ReturnType</code>. The <code>await</code> the keyword is used to wait for the promise to resolve before moving to the next line of code.</p>
<p>The <code>try/catch</code> block is used to handle any errors that occur while running the code inside the async function. If an error happens, it will be caught by the catch block, where you can handle it appropriately.</p>
<h3 id="heading-using-arrow-functions-with-async-await"><strong>Using Arrow Functions with Async / Await</strong></h3>
<p>You can also use arrow functions with async/await syntax in TypeScript:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> functionName = <span class="hljs-keyword">async</span> (): <span class="hljs-built_in">Promise</span>&lt;ReturnType&gt; =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> result = <span class="hljs-keyword">await</span> promise;
    <span class="hljs-comment">// code to execute after promise resolves</span>
    <span class="hljs-keyword">return</span> result;
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-comment">// code to execute if promise rejects</span>
    <span class="hljs-keyword">throw</span> error;
  }
};
</code></pre>
<p>In the example above, <code>functionName</code> is defined as an arrow function that returns a Promise of <code>ReturnType</code>. The async keyword indicates that this is an asynchronous function, and the await keyword is used to wait for the promise to resolve before moving to the next line of code.</p>
<h3 id="heading-async-await-with-an-api-call"><strong>Async / Await with an API Call</strong></h3>
<p>Now, let's go beyond the syntax and fetch some data from an API using async/await.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> User {
  id: <span class="hljs-built_in">number</span>;
  name: <span class="hljs-built_in">string</span>;
  email: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">const</span> fetchApi = <span class="hljs-keyword">async</span> (): <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">void</span>&gt; =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>);

    <span class="hljs-keyword">if</span> (!response.ok) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(
        <span class="hljs-string">`Failed to fetch users (HTTP status code: <span class="hljs-subst">${response.status}</span>)`</span>
      );
    }

    <span class="hljs-keyword">const</span> data: User[] = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-built_in">console</span>.log(data);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(error);
    <span class="hljs-keyword">throw</span> error;
  }
};

fetchApi();
</code></pre>
<p>Here, we’re fetching data from the JSONPlaceholder API, converting it to JSON, and then logging it to the console. This is a real-world example of how to use async/await in TypeScript.</p>
<p>You should see user information in the console. This image shows the output:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737554438217/a1b865ea-0903-4749-a079-c8401be05787.png" alt="a1b865ea-0903-4749-a079-c8401be05787" class="image--center mx-auto" width="2452" height="916" loading="lazy"></p>
<h3 id="heading-asyncawait-with-axios-api-call"><strong>Async/Await with Axios API call</strong></h3>
<pre><code class="lang-typescript"><span class="hljs-comment">// Example 2 on how to use async / await in typescript</span>

<span class="hljs-keyword">const</span> fetchApi = <span class="hljs-keyword">async</span> (): <span class="hljs-built_in">Promise</span>&lt;<span class="hljs-built_in">void</span>&gt; =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> axios.get(
      <span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>
    );
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.data;
    <span class="hljs-built_in">console</span>.log(data);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(error);
  }
};

fetchApi();
</code></pre>
<p>In the example above, we define the <code>fetchApi()</code> function using async/await and the <code>Axios.get()</code> method to make an HTTP GET request to the specified URL. We use await to wait for the response, then extract the data using the data property of the response object. Finally, we log the data to the console with <code>console.log()</code>. Any errors that occur are caught and logged to the console with <code>console.error()</code>.</p>
<p>We can achieve this using Axios, so you should see the same result in the console.</p>
<p>This image shows the output when using Axios in the console:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737554631796/4f85a12d-6a9b-4eaa-9ab9-910a8a463dc6.png" alt="4f85a12d-6a9b-4eaa-9ab9-910a8a463dc6" class="image--center mx-auto" width="2032" height="1047" loading="lazy"></p>
<p>Note: Before you try the code above, you need to install Axios using npm or yarn.</p>
<pre><code class="lang-bash">
npm install axios
</code></pre>
<pre><code class="lang-bash">
yarn add axios
</code></pre>
<p>If you're not familiar with Axios, you can <a target="_blank" href="https://www.npmjs.com/package/axios">learn more about it here</a>.</p>
<p>You can see that we used a <code>try</code> and <code>catch</code> block to handle errors. The <code>try</code> and <code>catch</code> block is a method for managing errors in TypeScript. So, whenever you make API calls like we just did, make sure you use a <code>try</code> and <code>catch</code> block to handle any errors.</p>
<p>Now, let's explore a more advanced use of the <code>try</code> and <code>catch</code> block in TypeScript:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Example 3 on how to use async / await in typescript</span>

<span class="hljs-keyword">interface</span> Recipe {
  id: <span class="hljs-built_in">number</span>;
  name: <span class="hljs-built_in">string</span>;
  ingredients: <span class="hljs-built_in">string</span>[];
  instructions: <span class="hljs-built_in">string</span>[];
  prepTimeMinutes: <span class="hljs-built_in">number</span>;
  cookTimeMinutes: <span class="hljs-built_in">number</span>;
  servings: <span class="hljs-built_in">number</span>;
  difficulty: <span class="hljs-built_in">string</span>;
  cuisine: <span class="hljs-built_in">string</span>;
  caloriesPerServing: <span class="hljs-built_in">number</span>;
  tags: <span class="hljs-built_in">string</span>[];
  userId: <span class="hljs-built_in">number</span>;
  image: <span class="hljs-built_in">string</span>;
  rating: <span class="hljs-built_in">number</span>;
  reviewCount: <span class="hljs-built_in">number</span>;
  mealType: <span class="hljs-built_in">string</span>[];
}

<span class="hljs-keyword">const</span> fetchRecipes = <span class="hljs-keyword">async</span> (): <span class="hljs-built_in">Promise</span>&lt;Recipe[] | <span class="hljs-built_in">string</span>&gt; =&gt; {
  <span class="hljs-keyword">const</span> api = <span class="hljs-string">"https://dummyjson.com/recipes"</span>;
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(api);

    <span class="hljs-keyword">if</span> (!response.ok) {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Failed to fetch recipes: <span class="hljs-subst">${response.statusText}</span>`</span>);
    }

    <span class="hljs-keyword">const</span> { recipes } = <span class="hljs-keyword">await</span> response.json();
    <span class="hljs-keyword">return</span> recipes; <span class="hljs-comment">// Return the recipes array</span>
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error fetching recipes:"</span>, error);
    <span class="hljs-keyword">if</span> (error <span class="hljs-keyword">instanceof</span> <span class="hljs-built_in">Error</span>) {
      <span class="hljs-keyword">return</span> error.message;
    }
    <span class="hljs-keyword">return</span> <span class="hljs-string">"An unknown error occurred."</span>;
  }
};

<span class="hljs-comment">// Fetch and log recipes</span>
fetchRecipes().then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (<span class="hljs-built_in">Array</span>.isArray(data)) {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Recipes fetched successfully:"</span>, data);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.error(<span class="hljs-string">"Error message:"</span>, data);
  }
});
</code></pre>
<p>In the example above, we define an <code>interface Recipe</code> that outlines the structure of the data we expect from the API. We then create the <code>fetchRecipes()</code> function using async/await and the fetch() method to make an HTTP GET request to the specified API endpoint.</p>
<p>We use a <code>try/catch</code> block to handle any errors that might occur during the API request. If the request is successful, we extract the data property from the response using await and return it. If an error occurs, we check for an error message and return it as a string if it exists.</p>
<p>Finally, we call the <code>fetchRecipes()</code> function and use <code>.then()</code> to log the returned data to the console. This example demonstrates how to use <code>async/await</code> with <code>try/catch</code> blocks to handle errors in a more advanced scenario, where we need to extract data from a response object and return a custom error message.</p>
<p>This image shows the output result of the code:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737557515062/922592da-e9a6-4792-9d22-d5f8f8e84889.png" alt="922592da-e9a6-4792-9d22-d5f8f8e84889" class="image--center mx-auto" width="2431" height="1007" loading="lazy"></p>
<h3 id="heading-async-await-with-promiseall"><strong>Async / Await with Promise.all</strong></h3>
<p><code>Promise.all()</code> is a method that takes an array of promises as input (an iterable) and returns a single Promise as output. This Promise resolves when all the input promises have been resolved or if the input iterable contains no promises. It rejects immediately if any of the input promises are rejected or if non-promises throw an error, and it will reject with the first rejection message or error.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Example of using async / await with Promise.all</span>
<span class="hljs-keyword">interface</span> User {
  id: <span class="hljs-built_in">number</span>;
  name: <span class="hljs-built_in">string</span>;
  email: <span class="hljs-built_in">string</span>;
  profilePicture: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">interface</span> Post {
  id: <span class="hljs-built_in">number</span>;
  title: <span class="hljs-built_in">string</span>;
  body: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">interface</span> Comment {
  id: <span class="hljs-built_in">number</span>;
  postId: <span class="hljs-built_in">number</span>;
  name: <span class="hljs-built_in">string</span>;
  email: <span class="hljs-built_in">string</span>;
  body: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">const</span> fetchApi = <span class="hljs-keyword">async</span> &lt;T&gt;(url: <span class="hljs-built_in">string</span>): <span class="hljs-built_in">Promise</span>&lt;T&gt; =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> response = <span class="hljs-keyword">await</span> fetch(url);
    <span class="hljs-keyword">if</span> (response.ok) {
      <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> response.json();
      <span class="hljs-keyword">return</span> data;
    } <span class="hljs-keyword">else</span> {
      <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Network response was not ok for <span class="hljs-subst">${url}</span>`</span>);
    }
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(error);
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">`Error fetching data from <span class="hljs-subst">${url}</span>`</span>);
  }
};

<span class="hljs-keyword">const</span> fetchAllApis = <span class="hljs-keyword">async</span> (): <span class="hljs-built_in">Promise</span>&lt;[User[], Post[], Comment[]]&gt; =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> [users, posts, comments] = <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all([
      fetchApi&lt;User[]&gt;(<span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>),
      fetchApi&lt;Post[]&gt;(<span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>),
      fetchApi&lt;Comment[]&gt;(<span class="hljs-string">"https://jsonplaceholder.typicode.com/comments"</span>),
    ]);
    <span class="hljs-keyword">return</span> [users, posts, comments];
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(error);
    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Error fetching data from one or more APIs"</span>);
  }
};

fetchAllApis()
  .then(<span class="hljs-function">(<span class="hljs-params">[users, posts, comments]</span>) =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Users: "</span>, users);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Posts: "</span>, posts);
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"Comments: "</span>, comments);
  })
  .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> <span class="hljs-built_in">console</span>.error(error));
</code></pre>
<p>In the code above, we used <code>Promise.all</code> to fetch multiple APIs at the same time. If you have several APIs to fetch, you can use <code>Promise.all</code> to get them all at once. As you can see, we used <code>map</code> to loop through the array of APIs and then pass it to <code>Promise.all</code> to fetch them simultaneously.</p>
<p>The image below shows the output from the API calls:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737560380441/14bbecbb-7dad-464e-b412-028f56e9d679.png" alt="14bbecbb-7dad-464e-b412-028f56e9d679" class="image--center mx-auto" width="2442" height="996" loading="lazy"></p>
<p>Let's see how to use <code>Promise.all</code> with Axios:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Example of using async / await with axios and Promise.all</span>

<span class="hljs-keyword">const</span> fetchApi = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">try</span> {
    <span class="hljs-keyword">const</span> urls = [
      <span class="hljs-string">"https://jsonplaceholder.typicode.com/users"</span>,
      <span class="hljs-string">"https://jsonplaceholder.typicode.com/posts"</span>,
    ];
    <span class="hljs-keyword">const</span> responses = <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all(urls.map(<span class="hljs-function">(<span class="hljs-params">url</span>) =&gt;</span> axios.get(url)));
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> <span class="hljs-built_in">Promise</span>.all(responses.map(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> response.data));
    <span class="hljs-built_in">console</span>.log(data);
  } <span class="hljs-keyword">catch</span> (error) {
    <span class="hljs-built_in">console</span>.error(error);
  }
};

fetchApi();
</code></pre>
<p>In the example above, we're using <code>Promise.all</code> to fetch data from two different URLs at the same time. First, we create an array of URLs, then use the map to create an array of Promises from the <code>axios.get</code> calls. We pass this array to <code>Promise.all</code>, which returns an array of responses. Finally, we use the map again to get the data from each response and log it to the console.</p>
<h2 id="heading-how-to-use-callbacks-in-typescript">How to Use Callbacks in TypeScript</h2>
<p>A <strong>callback</strong> is a function passed as an argument to another function. The callback function is executed inside the other function. Callbacks ensure that a function doesn't run before a task is completed – but that it then runs right after the task finishes. They help us write asynchronous JavaScript code and prevent problems and errors.</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Example of using callbacks in typescript</span>

<span class="hljs-keyword">const</span> add = (a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span>, callback: <span class="hljs-function">(<span class="hljs-params">result: <span class="hljs-built_in">number</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>) =&gt; {
  <span class="hljs-keyword">const</span> result = a + b;
  callback(result);
};

add(<span class="hljs-number">10</span>, <span class="hljs-number">20</span>, <span class="hljs-function">(<span class="hljs-params">result</span>) =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(result);
});
</code></pre>
<p>The image below shows the callback function:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737560660649/80203145-d053-49b8-a160-a1d72ed17a7a.png" alt="80203145-d053-49b8-a160-a1d72ed17a7a" class="image--center mx-auto" width="2451" height="545" loading="lazy"></p>
<p>Let's see another example of using callbacks in TypeScript:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Example of using a callback function in TypeScript</span>

<span class="hljs-keyword">type</span> User = {
  name: <span class="hljs-built_in">string</span>;
  email: <span class="hljs-built_in">string</span>;
};

<span class="hljs-keyword">const</span> fetchUserData = (
  id: <span class="hljs-built_in">number</span>,
  callback: <span class="hljs-function">(<span class="hljs-params">error: <span class="hljs-built_in">Error</span> | <span class="hljs-literal">null</span>, user: User | <span class="hljs-literal">null</span></span>) =&gt;</span> <span class="hljs-built_in">void</span>
) =&gt; {
  <span class="hljs-keyword">const</span> api = <span class="hljs-string">`https://jsonplaceholder.typicode.com/users/<span class="hljs-subst">${id}</span>`</span>;
  fetch(api)
    .then(<span class="hljs-function">(<span class="hljs-params">response</span>) =&gt;</span> {
      <span class="hljs-keyword">if</span> (response.ok) {
        <span class="hljs-keyword">return</span> response.json();
      } <span class="hljs-keyword">else</span> {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> <span class="hljs-built_in">Error</span>(<span class="hljs-string">"Network response was not ok."</span>);
      }
    })
    .then(<span class="hljs-function">(<span class="hljs-params">data</span>) =&gt;</span> {
      <span class="hljs-keyword">const</span> user: User = {
        name: data.name,
        email: data.email,
      };
      callback(<span class="hljs-literal">null</span>, user);
    })
    .catch(<span class="hljs-function">(<span class="hljs-params">error</span>) =&gt;</span> {
      callback(error, <span class="hljs-literal">null</span>);
    });
};

<span class="hljs-comment">// Usage of fetchUserData with a callback function</span>
fetchUserData(<span class="hljs-number">1</span>, <span class="hljs-function">(<span class="hljs-params">error, user</span>) =&gt;</span> {
  <span class="hljs-keyword">if</span> (error) {
    <span class="hljs-built_in">console</span>.error(error);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">console</span>.log(user);
  }
});
</code></pre>
<p>In the example above, we have a function called <code>fetchUserData</code> that takes an <code>id</code> and a <code>callback</code> as parameters. This <code>callback</code> is a function with two parameters: an error and a user.</p>
<p>The <code>fetchUserData</code> function retrieves user data from a JSONPlaceholder API endpoint using the <code>id</code>. If the fetch is successful, it creates an <code>User</code> object and passes it to the callback function with a null error. If there's an error during the fetch, it sends the error to the callback function with a null user.</p>
<p>To use the <code>fetchUserData</code> function with a callback, we provide an <code>id</code> and a callback function as arguments. The callback function checks for errors and logs the user data if there are no errors.</p>
<p>The image below shows the output of the API calls:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1737560996613/2b37fa46-1ee4-4dee-8d50-82c09a235aec.png" alt="2b37fa46-1ee4-4dee-8d50-82c09a235aec" class="image--center mx-auto" width="2457" height="1023" loading="lazy"></p>
<h3 id="heading-how-to-use-callbacks-responsibly">How to Use Callbacks Responsibly</h3>
<p>While callbacks are fundamental to asynchronous programming in TypeScript, they require careful management to avoid <strong>"callback hell"</strong> – the pyramid-shaped, deeply nested code that becomes hard to read and maintain. Here's how to use callbacks effectively:</p>
<ol>
<li><p><strong>Avoid deep nesting</strong></p>
<ul>
<li><p>Flatten your code structure by breaking complex operations into named functions</p>
</li>
<li><p>Use promises or async/await for complex async workflows (more on this below)</p>
</li>
</ul>
</li>
<li><p><strong>Error handling first</strong></p>
<ul>
<li><p>Always follow the Node.js convention of <code>(error, result)</code> parameters</p>
</li>
<li><p>Check for errors at every level of nested callbacks</p>
</li>
</ul>
</li>
</ol>
<pre><code class="lang-typescript">    <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">processData</span>(<span class="hljs-params">input: <span class="hljs-built_in">string</span>, callback: (err: <span class="hljs-built_in">Error</span> | <span class="hljs-literal">null</span>, result?: <span class="hljs-built_in">string</span>) =&gt; <span class="hljs-built_in">void</span></span>) </span>{
      <span class="hljs-comment">// ... always call callback with error first</span>
    }
</code></pre>
<ol start="3">
<li><p><strong>Use type annotations</strong></p>
<ul>
<li><p>Leverage TypeScript's type system to enforce callback signatures</p>
</li>
<li><p>Define clear interfaces for callback parameters</p>
</li>
</ul>
</li>
</ol>
<pre><code class="lang-typescript">    <span class="hljs-keyword">type</span> ApiCallback = <span class="hljs-function">(<span class="hljs-params">error: <span class="hljs-built_in">Error</span> | <span class="hljs-literal">null</span>, data?: ApiResponse</span>) =&gt;</span> <span class="hljs-built_in">void</span>;
</code></pre>
<ol start="4">
<li><p><strong>Consider control flow libraries</strong><br> For complex async operations, use utilities like <code>async.js</code> for:</p>
<ul>
<li><p>Parallel execution</p>
</li>
<li><p>Series execution</p>
</li>
<li><p>Error handling pipelines</p>
</li>
</ul>
</li>
</ol>
<h3 id="heading-when-to-use-callbacks-vs-alternatives">When to Use Callbacks vs. Alternatives</h3>
<p>There are times when callbacks are a great choice, and other times when they’re not.</p>
<p>Callbacks are helpful when you’re working with async operations (single completion), interfacing with older libraries or APIs that expect callbacks, handling event listeners (like click listeners or websocket events) or creating lightweight utilities with simple async needs.</p>
<p>In other scenarios where you need to focus on writing maintainable code with a clear async flow, callbacks cause trouble and you should prefer promises or async-await. For example, when you need to chain multiple operations, handle complex error propagation, work with modern APIs (like the Fetch API or FS Promises), or use <code>promise.all()</code> for parallel execution.</p>
<p><strong>Example migration from callbacks to promises:</strong></p>
<pre><code class="lang-typescript"><span class="hljs-comment">// Callback version</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchUser</span>(<span class="hljs-params">id: <span class="hljs-built_in">number</span>, callback: (err: <span class="hljs-built_in">Error</span> | <span class="hljs-literal">null</span>, user?: User) =&gt; <span class="hljs-built_in">void</span></span>) </span>{
  <span class="hljs-comment">// ... </span>
}

<span class="hljs-comment">// Promise version</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">fetchUserAsync</span>(<span class="hljs-params">id: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">Promise</span>&lt;<span class="hljs-title">User</span>&gt; </span>{
  <span class="hljs-comment">// ...</span>
}

<span class="hljs-comment">// Usage with async/await</span>
<span class="hljs-keyword">try</span> {
  <span class="hljs-keyword">const</span> user = <span class="hljs-keyword">await</span> fetchUserAsync(<span class="hljs-number">1</span>);
} <span class="hljs-keyword">catch</span> (error) {
  <span class="hljs-comment">// Handle error</span>
}
</code></pre>
<h3 id="heading-the-evolution-of-async-patterns">The Evolution of Async Patterns</h3>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Pattern</td><td>Pros</td><td>Cons</td></tr>
</thead>
<tbody>
<tr>
<td>Callbacks</td><td>Simple, universal</td><td>Nested complexity</td></tr>
<tr>
<td>Promises</td><td>Chainable, better error flow</td><td>Requires .then() chains</td></tr>
<tr>
<td>Async/Await</td><td>Sync-like readability</td><td>Requires transpilation</td></tr>
</tbody>
</table>
</div><p>Modern TypeScript projects often use a mix: callbacks for event-driven patterns and promises/async-await for complex async logic. The key is choosing the right tool for your specific use case while maintaining code clarity.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, we have learned about the different ways to handle asynchronous code in TypeScript. We have learned about callbacks, promises, async/await, and how to use them in TypeScript. We have also learned about this concept.</p>
<p>If you want to learn more about programming and how to become a better software engineer, you can subscribe to my YouTube channel <a target="_blank" href="https://www.youtube.com/@CliffTech/videos">CliffTech</a>.</p>
<p>Thank you for reading my article. I hope you enjoyed it. If you have any questions, feel free to reach out to me.</p>
<p>Connect with me on social media:</p>
<ul>
<li><p><a target="_blank" href="https://twitter.com/Clifftech_Dev">Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/Clifftech123">Github</a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/isaiah-clifford-opoku-a506a51b2/">Linkedin</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ The C# Class Handbook – Types of Classes with Code Examples ]]>
                </title>
                <description>
                    <![CDATA[ Classes are the fundamental building blocks of object-oriented programming in C#. They allow you to create reusable and modular code by grouping related data and functions. Different types of classes serve various purposes. For instance, organizing y... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/classes-in-c-sharp-handbook-with-examples/</link>
                <guid isPermaLink="false">67659959cfcbe6eba5ecf6dc</guid>
                
                    <category>
                        <![CDATA[ C# ]]>
                    </category>
                
                    <category>
                        <![CDATA[ dotnet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ classes ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Fri, 20 Dec 2024 16:20:41 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1734711601436/b4de90be-1d93-4d8d-a4ed-ae09b192ef5c.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Classes are the fundamental building blocks of object-oriented programming in C#. They allow you to create reusable and modular code by grouping related data and functions.</p>
<p>Different types of classes serve various purposes. For instance, organizing your logic to make your code easier to navigate is helpful when building an application.</p>
<p>You can group or separate your code into classes, and through inheritance, you can utilize different classes as needed. Classes help encapsulate your code, enabling you to reuse your logic in other application parts. Classes have many functionalities, and we will explore some of them in detail.</p>
<p>In this guide, we'll explore various types of classes in C# and how you can use them to create efficient and maintainable code.</p>
<h2 id="heading-prerequisites"><strong>Prerequisites</strong></h2>
<p>Before we proceed, you should have the following:</p>
<ol>
<li><p><strong>Basic knowledge of C#</strong>: you should understand C# syntax and basic programming constructs like variables, loops, and conditionals.</p>
</li>
<li><p><strong>Familiarity with Object-Oriented Programming (OOP) concepts</strong>: you should know how to work with classes, objects, inheritance, polymorphism, encapsulation, and abstraction.</p>
</li>
<li><p><strong>Familiarity with access modifiers</strong>: you should understand public, private, internal, and protected access modifiers.</p>
</li>
<li><p><strong>Experience with C# IDE/Environment</strong>: you should be able to write and run C# programs using an IDE like Visual Studio.</p>
</li>
</ol>
<p>If you want to learn more about C#, you can check out my YouTube channel: <a target="_blank" href="https://www.youtube.com/@CliffTech">CliffTech</a>.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-static-classes-in-c-sharp">Static Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-sealed-classes-in-c-sharp">Sealed Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-concrete-classes-in-c-sharp">Concrete Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-abstract-classes-in-c-sharp">Abstract Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-singleton-classes-in-c-sharp">Singleton Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-generic-classes-in-c-sharp">Generic Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-internal-classes-in-c-sharp">Internal Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-nested-classes-in-c-sharp">Nested Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-partial-classes-in-c-sharp">Partial Classes in C Sharp</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<p>The first type of class we’ll discuss is the Static Class. Let’s dive in.</p>
<h2 id="heading-static-classes-in-c-sharp">Static Classes in C Sharp</h2>
<p>Static classes are a special type of class in C# designed to provide a collection of related utility methods and properties that do not rely on instance data.</p>
<p>Static classes in C# are a unique type of class designed to house a collection of related utility methods and properties that don't depend on instance data.</p>
<p>Unlike regular classes, static classes cannot be instantiated, and they exclusively contain static members. This characteristic means they cannot be inherited, making them perfect for organizing stateless methods that don't require the features of object-oriented programming.</p>
<p>In essence, when we refer to stateless grouping, it implies that there's no need to create an instance to call a static method – you can simply use the class or method name directly. This approach provides a clear and efficient way to manage utility functions, enhancing code organization and accessibility.</p>
<h3 id="heading-example-of-a-static-class-in-c">Example of a Static Class in C</h3>
<p>Here's an example of a static class in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">namespace</span> <span class="hljs-title">StaticClasses</span>
{
<span class="hljs-comment">// Define a static class</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MathUtils</span>
    {
        <span class="hljs-comment">// Static method to add two numbers</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">Add</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b</span>)</span>
        {
            <span class="hljs-keyword">return</span> a + b;
        }

        <span class="hljs-comment">// Static method to subtract two numbers</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">Subtract</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b</span>)</span>
        {
            <span class="hljs-keyword">return</span> a - b;
        }

       <span class="hljs-comment">// Static method to multiply two numbers</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">int</span> <span class="hljs-title">Multiply</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> a, <span class="hljs-keyword">int</span> b</span>)</span>
        {
            <span class="hljs-keyword">return</span> a * b;
        }
    }
}
</code></pre>
<p>In this example:</p>
<ul>
<li><p>The <code>MathUtils</code> class is defined as <code>static</code>, meaning it cannot be instantiated.</p>
</li>
<li><p>It contains three static methods: <code>Add</code>, <code>Subtract</code>, and <code>Multiply</code>.</p>
</li>
<li><p>These methods can be called directly on the <code>MathUtils</code> class without creating an instance.</p>
</li>
</ul>
<p>Before you can use this, you need to call it in your <code>Program.cs</code>. When you create any C# application, the entry point is <code>Program.cs</code>. You’ll need to go there and make sure to call these classes so that you can execute them. This is what we will be doing for the rest of the section.</p>
<h3 id="heading-how-to-use-static-methods-in-programcs">How to Use Static Methods in <code>Program.cs</code></h3>
<p>Now you can use the static methods defined in the <code>MathUtils</code> class as follows:</p>
<pre><code class="lang-csharp">
 <span class="hljs-comment">// program.cs</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">StaticClasses</span>
{
    <span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
        {
             <span class="hljs-comment">// Call static methods from the MathUtils class</span>
            <span class="hljs-keyword">int</span> sum = MathUtils.Add(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>);
            <span class="hljs-comment">// Call the static method Subtract from the MathUtils class</span>
            <span class="hljs-keyword">int</span> difference = MathUtils.Subtract(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>);

            <span class="hljs-comment">// Call the static method Multiply from the MathUtils class</span>
            <span class="hljs-keyword">int</span> product = MathUtils.Multiply(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>);

            <span class="hljs-comment">// Display the results of the sum method</span>
            Console.WriteLine(<span class="hljs-string">$"Sum: <span class="hljs-subst">{sum}</span>"</span>); <span class="hljs-comment">// Output: 8</span>
            <span class="hljs-comment">// Display the results of the difference method</span>
            Console.WriteLine(<span class="hljs-string">$"Difference: <span class="hljs-subst">{difference}</span>"</span>); <span class="hljs-comment">// Output: 2</span>
            <span class="hljs-comment">// Display the results of the product method</span>
            Console.WriteLine(<span class="hljs-string">$"Product: <span class="hljs-subst">{product}</span>"</span>);  <span class="hljs-comment">// Output: 15</span>
        }
    }
}
</code></pre>
<h3 id="heading-when-to-use-statice-classes-vs-methods">When to Use Statice Classes vs Methods</h3>
<p>To decide when to use static classes or methods in C#, consider the following guidelines:</p>
<ol>
<li><p><strong>Use Static Classes when:</strong></p>
<ul>
<li><p>You need a collection of utility or helper methods that do not require any instance data.</p>
</li>
<li><p>The methods and properties are stateless and can be accessed globally without creating an object.</p>
</li>
<li><p>You want to group related functions that are not tied to a specific object state.</p>
</li>
<li><p>You need to ensure that the class cannot be instantiated or inherited.</p>
</li>
</ul>
</li>
<li><p><strong>Use Static Methods when:</strong></p>
<ul>
<li><p>You have a class that is mostly instance-based, but you need a few methods that do not depend on instance data.</p>
</li>
<li><p>The method performs a task that is independent of any object state and can be executed without an instance.</p>
</li>
<li><p>You want to provide a utility function within a class that can be accessed without creating an object of that class.</p>
</li>
</ul>
</li>
</ol>
<p>By using static classes and methods appropriately, you can enhance code organization, improve performance by avoiding unnecessary object creation, and ensure that certain functionalities are easily accessible throughout your application.</p>
<h3 id="heading-key-points-to-remember-about-static-classes-in-c">Key Points to Remember About Static Classes in C</h3>
<ul>
<li><p><strong>Cannot be Instantiated</strong>: You cannot create objects from a static class.</p>
</li>
<li><p><strong>Only static members</strong>: Static classes can only have static members. They do not support instance methods or fields.</p>
</li>
<li><p><strong>Sealed by default</strong>: Static classes are automatically sealed, so they cannot be inherited.</p>
</li>
<li><p><strong>Utility and helper methods</strong>: Static classes are usually used to group related utility or helper methods that don't need an object state.</p>
</li>
</ul>
<p>Static classes help organize and access utility methods and properties clearly and simply, making them important for creating efficient and maintainable code.</p>
<h2 id="heading-sealed-classes-in-c-sharp">Sealed Classes in C Sharp</h2>
<p>Sealed classes are a special type of class in C# that cannot be inherited. You can use them to prevent other classes from deriving from them, which can be useful for creating immutable types or ensuring that a class's behavior remains unchanged.</p>
<p>By sealing a class, you ensure that it cannot be modified or extended, making it useful for scenarios where you want to provide a specific implementation without allowing further alterations.</p>
<h3 id="heading-example-of-a-sealed-class-in-c">Example of a Sealed Class in C</h3>
<p>Here's an example of a sealed class in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">namespace</span> <span class="hljs-title">SealedClasses</span>
{

    <span class="hljs-comment">// Define an abstract class</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Shape</span>
    {
        <span class="hljs-comment">// Abstract method to calculate the area</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateArea</span>(<span class="hljs-params"></span>)</span>;
    }

     <span class="hljs-comment">// Define a sealed class</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">sealed</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Rectangle</span> : <span class="hljs-title">Shape</span>
    {

        <span class="hljs-comment">//  Properties</span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Width { <span class="hljs-keyword">get</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Height { <span class="hljs-keyword">get</span>; }

        <span class="hljs-comment">// Constructor</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Rectangle</span>(<span class="hljs-params"><span class="hljs-keyword">double</span> width, <span class="hljs-keyword">double</span> height</span>)</span>
        {
            Width = width;
            Height = height;
        }

       <span class="hljs-comment">// Implement the CalculateArea method</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">double</span> <span class="hljs-title">CalculateArea</span>(<span class="hljs-params"></span>)</span>
        {
            <span class="hljs-keyword">return</span> Width * Height;
        }
    }
}
</code></pre>
<p>In this example:</p>
<ul>
<li><p>The <code>Shape</code> class is an abstract base class with an abstract method <code>CalculateArea()</code>.</p>
</li>
<li><p>The <code>Rectangle</code> class inherits from <code>Shape</code> and provides an implementation for <code>CalculateArea()</code>.</p>
</li>
<li><p>The <code>Rectangle</code> class is sealed, which means it cannot be inherited from. This ensures that the class's implementation cannot be modified or extended.</p>
</li>
</ul>
<h3 id="heading-how-to-use-the-sealed-rectangle-class-in-the-programcs">How to Use the Sealed Rectangle Class in the Program.cs</h3>
<p>Here's how you can use the <code>Rectangle</code> class in a <code>Program.cs</code> file:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">namespace</span> <span class="hljs-title">SealedClasses</span>
{
    <span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
        {
            Rectangle rectangle = <span class="hljs-keyword">new</span> Rectangle(<span class="hljs-number">5</span>, <span class="hljs-number">3</span>);
            <span class="hljs-keyword">double</span> area = rectangle.CalculateArea();

            Console.WriteLine(<span class="hljs-string">$"Area of the rectangle: <span class="hljs-subst">{area}</span>"</span>); <span class="hljs-comment">// Output: Area of the rectangle: 15</span>
        }
    }
}
</code></pre>
<p>In this example, the <code>Rectangle</code> class is sealed to ensure that its behavior cannot be changed through inheritance. This guarantees that the <code>Rectangle</code> class's implementation of <code>CalculateArea()</code> stays the same, which helps maintain consistent behavior.</p>
<h3 id="heading-when-to-use-sealed-classes">When to Use Sealed Classes</h3>
<p>Sealed classes are particularly useful in the following contexts:</p>
<ol>
<li><p><strong>Framework development</strong>: When developing frameworks or libraries, you might use sealed classes to lock down certain classes that are not intended to be extended by users. This helps maintain control over the framework's behavior and ensures that users cannot introduce bugs or inconsistencies by extending these classes.</p>
</li>
<li><p><strong>Preventing inheritance</strong>: If a class is designed to be a specific implementation with no need for further customization or extension, sealing it prevents other developers from creating subclasses that might alter its intended functionality.</p>
</li>
<li><p><strong>Finalizing class design</strong>: When a class has reached a point where its design is considered complete and no further changes or extensions are anticipated, sealing it can signal to other developers that the class should be used as-is.</p>
</li>
<li><p><strong>Avoiding overriding</strong>: In scenarios where overriding methods could lead to incorrect behavior or security issues, sealing the class ensures that its methods cannot be overridden, preserving the original logic and functionality.</p>
</li>
</ol>
<h3 id="heading-key-points-to-remember-about-sealed-classes">Key Points to Remember About Sealed Classes</h3>
<ul>
<li><p><strong>No inheritance</strong>: Sealed classes cannot be inherited, ensuring their behavior stays the same.</p>
</li>
<li><p><strong>Prevent modification</strong>: They prevent further inheritance, avoiding accidental changes or extensions.</p>
</li>
<li><p><strong>Immutable and specific</strong>: Sealed classes are useful for creating immutable classes or when you need a specific, unchangeable implementation.</p>
</li>
</ul>
<h3 id="heading-sealed-classes-vs-static-classes">Sealed Classes vs. Static Classes</h3>
<p>You might wonder why we need sealed classes if static classes are already sealed. The key differences are:</p>
<ul>
<li><p><strong>Static Classes</strong> are sealed and cannot be instantiated. They are used for grouping static methods and properties.</p>
</li>
<li><p><strong>Sealed Classes</strong> can be instantiated but cannot be inherited. This allows for creating objects that are protected from further subclassing.</p>
</li>
</ul>
<p>Sealed classes offer flexibility in creating classes that can be used directly without the risk of modification through inheritance.</p>
<h2 id="heading-concrete-classes-in-c-sharp">Concrete Classes in C Sharp</h2>
<p>Concrete classes are essential in <code>object-oriented programming</code> in C#. They are fully implemented classes that you can use to create objects directly.</p>
<p>Unlike <code>abstract classes</code> or <code>interfaces</code>, concrete classes have complete implementations of all their methods and properties, making them versatile and fundamental to most C# applications.</p>
<p>A concrete class is not abstract. It includes full implementations of all its members—methods, properties, fields, and so on—and can be used to create objects. These classes represent real-world entities or concepts in your application, encapsulating both data (stored in fields or properties) and behavior (defined by methods).</p>
<h3 id="heading-example-defining-a-concrete-class-in-c">Example: Defining a Concrete Class in C</h3>
<p>Here's a simple example of a concrete class in C#:</p>
<pre><code class="lang-csharp">

<span class="hljs-comment">// Define a concrete class</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Speak</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The animal makes a sound."</span>);
    }
}

<span class="hljs-comment">// Define a derived class that inherits from the Animal class</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> : <span class="hljs-title">Animal</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Bark</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The dog barks."</span>);
    }
}
</code></pre>
<p>In this example, the <code>Animal</code> class is a concrete class with a method <code>Speak</code> that represents a generic sound made by any animal. The <code>Dog</code> class inherits from <code>Animal</code> and adds a <code>Bark</code> method to represent a sound specific to dogs. Both <code>Animal</code> and <code>Dog</code> are concrete classes because they can be instantiated and used to create objects.</p>
<h3 id="heading-how-to-instantiate-and-use-concrete-classes">How to Instantiate and Use Concrete Classes</h3>
<p>Here's how you can use the <code>Dog</code> class in a <code>Program.cs</code> file:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// program.cs</span>
<span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
    {
        <span class="hljs-comment">// Create an instance of the Dog class</span>
        Dog myDog = <span class="hljs-keyword">new</span> Dog();

        <span class="hljs-comment">// Call the inherited method</span>
        myDog.Speak(); <span class="hljs-comment">// Output: The animal makes a sound.</span>

        <span class="hljs-comment">// Call the method defined in the Dog class</span>
        myDog.Bark();  <span class="hljs-comment">// Output: The dog barks.</span>
    }
}
</code></pre>
<p>In this example, we create an instance of the <code>Dog</code> class called <code>myDog</code>. We first call the <code>Speak</code> method, which is inherited from the <code>Animal</code> class, and then the <code>Bark</code> method from the <code>Dog</code> class. This shows how concrete classes can include both inherited and unique behaviors.</p>
<h3 id="heading-real-world-example-concrete-class-for-a-product">Real-World Example: Concrete Class for a Product</h3>
<p>To illustrate the practical application of concrete classes, consider the following example of a <code>Product</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Define a concrete class for a product</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Product</span>
{
    <span class="hljs-comment">// Data properties</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">decimal</span> Price { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-comment">// Method to display product information</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayInfo</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Product: <span class="hljs-subst">{Name}</span>, Price: <span class="hljs-subst">{Price:C}</span>"</span>);
    }
}
</code></pre>
<p>This <code>Product</code> class is a concrete class with properties <code>Name</code> and <code>Price</code> to store information about a product. The <code>DisplayInfo</code> method provides a way to display the product’s details.</p>
<h4 id="heading-how-to-use-the-product-class">How to Use the <code>Product</code> Class</h4>
<p>Here's how you can use the <code>Product</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
    {
        <span class="hljs-comment">// Create an instance of the Product class</span>
        Product product = <span class="hljs-keyword">new</span> Product
        {
            Name = <span class="hljs-string">"Laptop"</span>,
            Price = <span class="hljs-number">1299.99</span>m
        };

        <span class="hljs-comment">// Display product information</span>
        product.DisplayInfo(); <span class="hljs-comment">// Output: Product: Laptop, Price: $1,299.99</span>
    }
}
</code></pre>
<p>In this scenario, the <code>Product</code> class is used to create a <code>product</code> object. The <code>DisplayInfo</code> method is called to show the product's name and price. This demonstrates how concrete classes are used to model and work with real-world data.</p>
<h3 id="heading-key-points-to-remember-about-concrete-classes">Key Points to Remember About Concrete Classes</h3>
<ul>
<li><p><strong>Instantiable</strong>: Concrete classes can be instantiated, allowing you to create objects that represent specific entities or concepts in your application.</p>
</li>
<li><p><strong>Complete implementation</strong>: Concrete classes provide full implementations of all methods and properties, unlike abstract classes or interfaces.</p>
</li>
<li><p><strong>Common use</strong>: They are the most common type of class in C#, used to define objects with specific behavior and data.</p>
</li>
</ul>
<p>Concrete classes are essential for C# development, enabling you to define and work with objects that model real-world entities within your applications. Understanding how to effectively use concrete classes is crucial for building robust, object-oriented software.</p>
<h2 id="heading-abstract-classes-in-c-sharp">Abstract Classes in C Sharp</h2>
<p>In C#, abstract classes are a powerful feature that allow you to define a blueprint for other classes without providing complete implementations. They serve as base classes that cannot be instantiated directly but can be inherited by other classes that will provide specific implementations for the abstract methods defined within them. This design helps enforce consistency across related classes while allowing flexibility in how certain behaviors are implemented.</p>
<h3 id="heading-what-does-instantiated-mean">What Does "Instantiated" Mean?</h3>
<p>Before exploring abstract classes, let's clarify what it means to instantiate a class. Instantiation is the process of creating an object from a class. When you use the <code>new</code> keyword in C#, you are creating an instance (or object) of that class.</p>
<p>But abstract classes cannot be instantiated directly. They must be inherited by a non-abstract (concrete) class that provides implementations for the abstract methods.</p>
<h3 id="heading-understanding-abstract-classes-and-abstract-methods">Understanding Abstract Classes and Abstract Methods</h3>
<p><strong>Abstract classes</strong> are classes you can't create objects from directly. They act as templates for other classes. They can have both complete methods and methods without a body (abstract methods). Abstract classes help set up a common interface and shared behavior for related classes.</p>
<p><strong>Abstract methods</strong>, on the other hand, are methods in an abstract class that don't have a body. Any non-abstract class that inherits from the abstract class must provide a body for these methods. This ensures all subclasses have a consistent interface.</p>
<h3 id="heading-real-world-example-bank-account-management">Real-World Example: Bank Account Management</h3>
<p>Let's explore a real-world example to illustrate the concept of abstract classes and abstract methods in C#.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> System;

<span class="hljs-comment">// define an abstract class</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">AbstractClasses</span>
{
    <span class="hljs-comment">// Abstract class</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BankAccount</span>
    {
        <span class="hljs-comment">// Properties</span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> AccountNumber { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">decimal</span> Balance { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">protected</span> <span class="hljs-keyword">set</span>; }

        <span class="hljs-comment">// Constructor</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">BankAccount</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> accountNumber, <span class="hljs-keyword">decimal</span> initialBalance</span>)</span>
        {
            AccountNumber = accountNumber;
            Balance = initialBalance;
        }

        <span class="hljs-comment">// Abstract methods</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deposit</span>(<span class="hljs-params"><span class="hljs-keyword">decimal</span> amount</span>)</span>;
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Withdraw</span>(<span class="hljs-params"><span class="hljs-keyword">decimal</span> amount</span>)</span>;
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayAccountInfo</span>(<span class="hljs-params"></span>)</span>;
    }

    <span class="hljs-comment">// Derived class: SavingsAccount</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">SavingsAccount</span> : <span class="hljs-title">BankAccount</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">decimal</span> interestRate;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">SavingsAccount</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> accountNumber, <span class="hljs-keyword">decimal</span> initialBalance, <span class="hljs-keyword">decimal</span> interestRate</span>)
            : <span class="hljs-title">base</span>(<span class="hljs-params">accountNumber, initialBalance</span>)</span>
        {
            <span class="hljs-keyword">this</span>.interestRate = interestRate;
        }

        <span class="hljs-comment">// Implementing abstract methods</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deposit</span>(<span class="hljs-params"><span class="hljs-keyword">decimal</span> amount</span>)</span>
        {
            Balance += amount;
            Console.WriteLine(<span class="hljs-string">$"Deposited <span class="hljs-subst">{amount}</span> to Savings Account <span class="hljs-subst">{AccountNumber}</span>. New Balance: <span class="hljs-subst">{Balance}</span>"</span>);
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Withdraw</span>(<span class="hljs-params"><span class="hljs-keyword">decimal</span> amount</span>)</span>
        {
            <span class="hljs-keyword">if</span> (amount &gt; Balance)
            {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InvalidOperationException(<span class="hljs-string">"Insufficient funds."</span>);
            }
            Balance -= amount;
            Console.WriteLine(<span class="hljs-string">$"Withdrew <span class="hljs-subst">{amount}</span> from Savings Account <span class="hljs-subst">{AccountNumber}</span>. New Balance: <span class="hljs-subst">{Balance}</span>"</span>);
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayAccountInfo</span>(<span class="hljs-params"></span>)</span>
        {
            Console.WriteLine(<span class="hljs-string">$"Savings Account <span class="hljs-subst">{AccountNumber}</span> - Balance: <span class="hljs-subst">{Balance}</span>, Interest Rate: <span class="hljs-subst">{interestRate}</span>%"</span>);
        }
    }

    <span class="hljs-comment">// Derived class: CheckingAccount</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">CheckingAccount</span> : <span class="hljs-title">BankAccount</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">decimal</span> overdraftLimit;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">CheckingAccount</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> accountNumber, <span class="hljs-keyword">decimal</span> initialBalance, <span class="hljs-keyword">decimal</span> overdraftLimit</span>)
            : <span class="hljs-title">base</span>(<span class="hljs-params">accountNumber, initialBalance</span>)</span>
        {
            <span class="hljs-keyword">this</span>.overdraftLimit = overdraftLimit;
        }

        <span class="hljs-comment">// Implementing abstract methods</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deposit</span>(<span class="hljs-params"><span class="hljs-keyword">decimal</span> amount</span>)</span>
        {
            Balance += amount;
            Console.WriteLine(<span class="hljs-string">$"Deposited <span class="hljs-subst">{amount}</span> to Checking Account <span class="hljs-subst">{AccountNumber}</span>. New Balance: <span class="hljs-subst">{Balance}</span>"</span>);
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Withdraw</span>(<span class="hljs-params"><span class="hljs-keyword">decimal</span> amount</span>)</span>
        {
            <span class="hljs-keyword">if</span> (amount &gt; Balance + overdraftLimit)
            {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InvalidOperationException(<span class="hljs-string">"Overdraft limit exceeded."</span>);
            }
            Balance -= amount;
            Console.WriteLine(<span class="hljs-string">$"Withdrew <span class="hljs-subst">{amount}</span> from Checking Account <span class="hljs-subst">{AccountNumber}</span>. New Balance: <span class="hljs-subst">{Balance}</span>"</span>);
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayAccountInfo</span>(<span class="hljs-params"></span>)</span>
        {
            Console.WriteLine(<span class="hljs-string">$"Checking Account <span class="hljs-subst">{AccountNumber}</span> - Balance: <span class="hljs-subst">{Balance}</span>, Overdraft Limit: <span class="hljs-subst">{overdraftLimit}</span>"</span>);
        }
    }
}
</code></pre>
<p>In this example, the <code>BankAccount</code> class is an abstract class that defines a common interface for different types of bank accounts. It includes abstract methods like <code>Deposit</code>, <code>Withdraw</code>, and <code>DisplayAccountInfo</code>, which must be implemented by any class that inherits from <code>BankAccount</code>.</p>
<p>The <code>SavingsAccount</code> and <code>CheckingAccount</code> classes inherit from <code>BankAccount</code> and provide specific implementations for these abstract methods. This design enforces that every type of bank account must implement deposit, withdrawal, and display functions, while still allowing each account type to implement these functions in a way that makes sense for that specific type.</p>
<h3 id="heading-how-to-use-abstract-classes-in-a-program">How to Use Abstract Classes in a Program</h3>
<p>Let's see how we can use the <code>SavingsAccount</code> and <code>CheckingAccount</code> classes in a <code>Program.cs</code> file.</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">namespace</span> <span class="hljs-title">AbstractClasses</span>
{
    <span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
        {
            <span class="hljs-comment">// Create a savings account</span>
            BankAccount savings = <span class="hljs-keyword">new</span> SavingsAccount(<span class="hljs-string">"SA123"</span>, <span class="hljs-number">1000</span>, <span class="hljs-number">1.5</span>m);
            <span class="hljs-comment">// Create a checking account</span>
            BankAccount checking = <span class="hljs-keyword">new</span> CheckingAccount(<span class="hljs-string">"CA123"</span>, <span class="hljs-number">500</span>, <span class="hljs-number">200</span>);

            <span class="hljs-comment">// Deposit and withdraw from the savings account</span>
            savings.DisplayAccountInfo();

           <span class="hljs-comment">// Deposit and withdraw from the checking account</span>
            savings.Deposit(<span class="hljs-number">200</span>);

            savings.Withdraw(<span class="hljs-number">100</span>);
            <span class="hljs-comment">// Display the updated account information</span>
            savings.DisplayAccountInfo();

            checking.DisplayAccountInfo();

             <span class="hljs-comment">// Deposit and withdraw from the checking account</span>
            checking.Deposit(<span class="hljs-number">300</span>);

            checking.Withdraw(<span class="hljs-number">600</span>);

            <span class="hljs-comment">// Display the updated account information</span>
            checking.DisplayAccountInfo();

            <span class="hljs-keyword">try</span>
            {
                checking.Withdraw(<span class="hljs-number">200</span>);
            }
            <span class="hljs-keyword">catch</span> (InvalidOperationException ex)
            {
                Console.WriteLine(<span class="hljs-string">$"Error: <span class="hljs-subst">{ex.Message}</span>"</span>);
            }

            checking.DisplayAccountInfo();
        }
    }
}
</code></pre>
<p>This program will produce the following output:</p>
<pre><code class="lang-markdown">Savings Account SA123 - Balance: 1000, Interest Rate: 1.5%
Deposited 200 to Savings Account SA123. New Balance: 1200
Withdrew 100 from Savings Account SA123. New Balance: 1100
Savings Account SA123 - Balance: 1100, Interest Rate: 1.5%
Checking Account CA123 - Balance: 500, Overdraft Limit: 200
Deposited 300 to Checking Account CA123. New Balance: 800
Withdrew 600 from Checking Account CA123. New Balance: 200
Checking Account CA123 - Balance: 200, Overdraft Limit: 200
Withdrew 200 from Checking Account CA123. New Balance: 0
Checking Account CA123 - Balance: 0, Overdraft Limit: 200
</code></pre>
<p>In this example, the <code>SavingsAccount</code> and <code>CheckingAccount</code> objects are created, and the abstract methods <code>Deposit</code>, <code>Withdraw</code>, and <code>DisplayAccountInfo</code> are called. The abstract class <code>BankAccount</code> ensures that both account types have these methods, while the derived classes provide the specific functionality.</p>
<h3 id="heading-key-points-to-remember-about-abstract-classes">Key Points to Remember About Abstract Classes</h3>
<ul>
<li><p><strong>Cannot be instantiated</strong>: You can't create an instance of an abstract class directly. A subclass must inherit it and provide the implementations for the abstract methods.</p>
</li>
<li><p><strong>Contain abstract methods</strong>: Abstract methods in an abstract class have no body. Any non-abstract class that inherits from the abstract class must implement these methods.</p>
</li>
<li><p><strong>Define common interfaces</strong>: Abstract classes set a common interface for related classes, ensuring they are consistent while allowing different implementations.</p>
</li>
</ul>
<p>Abstract classes are important in C#. They help enforce a structure across related classes but still allow for specific details. By using abstract classes, you can make your code more organized, easier to maintain, and extend.</p>
<h2 id="heading-singleton-classes-in-c-sharp">Singleton Classes in C Sharp</h2>
<p>Singleton classes are a design pattern that restricts the instantiation of a class to one single instance. This is particularly useful when you need a single, shared resource across your application, such as a configuration manager, logging service, or database connection.</p>
<h3 id="heading-why-use-singleton-classes-in-c">Why Use Singleton Classes in C#?</h3>
<p>Imagine you have a class responsible for managing a database connection. You don’t want multiple instances of this class running around, potentially causing issues with resource management or inconsistent data. A Singleton class ensures that only one instance is created and provides a global point of access to it.</p>
<h3 id="heading-example-defining-a-singleton-class">Example: Defining a Singleton Class</h3>
<p>Let’s now see how you can implement a Singleton class in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Define a singleton class</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Singleton</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> Singleton instance;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">readonly</span> <span class="hljs-keyword">object</span> lockObject = <span class="hljs-keyword">new</span> <span class="hljs-keyword">object</span>();

    <span class="hljs-comment">// Private constructor prevents instantiation from outside the class</span>
    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">Singleton</span>(<span class="hljs-params"></span>)</span>
    {
    }

    <span class="hljs-comment">// Public property to access the single instance of the class</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> Singleton Instance
    {
        <span class="hljs-keyword">get</span>
        {
            <span class="hljs-comment">// Ensure thread safety</span>
            <span class="hljs-keyword">lock</span> (lockObject)
            {
                <span class="hljs-keyword">if</span> (instance == <span class="hljs-literal">null</span>)
                {
                    instance = <span class="hljs-keyword">new</span> Singleton();
                }
            }
            <span class="hljs-keyword">return</span> instance;
        }
    }

    <span class="hljs-comment">// Example method to demonstrate the singleton instance</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">PrintMessage</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"Hello, I am a singleton class."</span>);
    }
}
</code></pre>
<p>In this example, the <code>Singleton</code> class is defined with a private constructor, which prevents other classes from creating new instances. The static property <code>Instance</code> returns the single instance of the class, creating it if it doesn't already exist. The <code>lockObject</code> ensures that the class is thread-safe, meaning that even in a multi-threaded environment, only one instance will be created.</p>
<p>The <code>PrintMessage</code> method is just a simple example to show that the Singleton instance can be used like any other class instance.</p>
<h3 id="heading-how-to-use-the-singleton-class-in-programcs">How to Use the Singleton Class in <code>Program.cs</code></h3>
<p>Now let’s see how you can use this Singleton class in your application:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
    {
        <span class="hljs-comment">// Retrieve the single instance of the Singleton class</span>
        Singleton singleton1 = Singleton.Instance;
        singleton1.PrintMessage(); <span class="hljs-comment">// Output: Hello, I am a singleton class.</span>

        <span class="hljs-comment">// Retrieve the instance again</span>
        Singleton singleton2 = Singleton.Instance;

        <span class="hljs-comment">// Check if both instances are the same</span>
        Console.WriteLine(singleton1 == singleton2); <span class="hljs-comment">// Output: True</span>
    }
}
</code></pre>
<p>In this example, we retrieve the Singleton instance twice. Because the class is a Singleton, both <code>singleton1</code> and <code>singleton2</code> refer to the same instance. The <code>==</code> operator confirms this by returning <code>true</code>.</p>
<h3 id="heading-how-to-extend-the-singleton-example">How to Extend the Singleton Example</h3>
<p>You can expand the Singleton pattern to handle more complex scenarios. For example, you could initialize the Singleton instance with configuration data:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ConfigurationManager</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">static</span> ConfigurationManager instance;
    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> <span class="hljs-title">Dictionary</span>&lt;<span class="hljs-title">string</span>, <span class="hljs-title">string</span>&gt; settings</span> = <span class="hljs-keyword">new</span> Dictionary&lt;<span class="hljs-keyword">string</span>, <span class="hljs-keyword">string</span>&gt;();

    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">ConfigurationManager</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-comment">// Simulate loading settings from a configuration file</span>
        settings[<span class="hljs-string">"AppName"</span>] = <span class="hljs-string">"MyApplication"</span>;
        settings[<span class="hljs-string">"Version"</span>] = <span class="hljs-string">"1.0.0"</span>;
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> ConfigurationManager Instance
    {
        <span class="hljs-keyword">get</span>
        {
            <span class="hljs-keyword">if</span> (instance == <span class="hljs-literal">null</span>)
            {
                instance = <span class="hljs-keyword">new</span> ConfigurationManager();
            }
            <span class="hljs-keyword">return</span> instance;
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> <span class="hljs-title">GetSetting</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> key</span>)</span>
    {
        <span class="hljs-keyword">return</span> settings.ContainsKey(key) ? settings[key] : <span class="hljs-literal">null</span>;
    }
}
</code></pre>
<p>Here, <code>ConfigurationManager</code> is a Singleton class that loads and manages application settings. The <code>GetSetting</code> method allows you to retrieve specific configuration values, ensuring that all parts of your application use the same settings.</p>
<h3 id="heading-key-points-to-remember-about-singleton-classes">Key Points to Remember About Singleton Classes</h3>
<ul>
<li><p><strong>Single instance</strong>: Singleton classes ensure that only one instance of the class exists in the application.</p>
</li>
<li><p><strong>Global access</strong>: Singleton provides a global point of access to the instance, making it easy to use across different parts of your application.</p>
</li>
<li><p><strong>Thread safety</strong>: In multi-threaded environments, ensure your Singleton is thread-safe to avoid creating multiple instances.</p>
</li>
<li><p><strong>Use cases</strong>: Common use cases for Singleton include managing configurations, logging services, and database connections.</p>
</li>
</ul>
<p>Singleton classes are a fundamental design pattern in software engineering, offering a simple yet powerful way to manage shared resources. Understanding and correctly implementing Singletons can help you write more efficient and maintainable code.</p>
<h2 id="heading-generic-classes-in-c-sharp">Generic Classes in C Sharp</h2>
<p>Generic classes in C# provide a powerful way to create reusable and type-safe code. By using generic classes, you can design a single class that works with any data type, eliminating the need for type-specific implementations. This makes your code more flexible and reduces redundancy.</p>
<h3 id="heading-why-use-generic-classes">Why Use Generic Classes?</h3>
<p>Imagine you need to implement a stack that stores integers. Later, you might need another stack to store strings.</p>
<p>Instead of writing two separate classes, you can write one generic stack class that can handle both data types—and any others you might need. Generic classes help you avoid code duplication and make your codebase easier to maintain.</p>
<h3 id="heading-example-defining-a-generic-class">Example: Defining a Generic Class</h3>
<p>Let’s take a look at a simple implementation of a generic stack class:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Define a generic class</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Stack</span>&lt;<span class="hljs-title">T</span>&gt;
{
    <span class="hljs-function"><span class="hljs-keyword">private</span> <span class="hljs-title">List</span>&lt;<span class="hljs-title">T</span>&gt; items</span> = <span class="hljs-keyword">new</span> List&lt;T&gt;();

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Push</span>(<span class="hljs-params">T item</span>)</span>
    {
        items.Add(item);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> T <span class="hljs-title">Pop</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (items.Count == <span class="hljs-number">0</span>)
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InvalidOperationException(<span class="hljs-string">"The stack is empty."</span>);
        }
        T item = items[items.Count - <span class="hljs-number">1</span>];
        items.RemoveAt(items.Count - <span class="hljs-number">1</span>);
        <span class="hljs-keyword">return</span> item;
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> T <span class="hljs-title">Peek</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">if</span> (items.Count == <span class="hljs-number">0</span>)
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> InvalidOperationException(<span class="hljs-string">"The stack is empty."</span>);
        }
        <span class="hljs-keyword">return</span> items[items.Count - <span class="hljs-number">1</span>];
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> <span class="hljs-title">IsEmpty</span>(<span class="hljs-params"></span>)</span>
    {
        <span class="hljs-keyword">return</span> items.Count == <span class="hljs-number">0</span>;
    }
}
</code></pre>
<p>In this example, the <code>Stack&lt;T&gt;</code> class is defined with a type parameter <code>T</code>. This type parameter is a placeholder that represents the type of data the stack will store. The class includes methods like <code>Push</code> to add an item to the stack, <code>Pop</code> to remove and return the top item, <code>Peek</code> to view the top item without removing it, and <code>IsEmpty</code> to check if the stack is empty.</p>
<p>Because <code>Stack&lt;T&gt;</code> is generic, you can use it with any data type, whether it's <code>int</code>, <code>string</code>, or even a custom class.</p>
<h3 id="heading-how-to-use-the-stack-class-in-programcs">How to Use the Stack Class in <code>Program.cs</code></h3>
<p>Let’s see how this generic <code>Stack</code> class can be used in a program:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
    {
        <span class="hljs-comment">// Stack for integers</span>
        Stack&lt;<span class="hljs-keyword">int</span>&gt; intStack = <span class="hljs-keyword">new</span> Stack&lt;<span class="hljs-keyword">int</span>&gt;();
        intStack.Push(<span class="hljs-number">10</span>);
        intStack.Push(<span class="hljs-number">20</span>);
        Console.WriteLine(intStack.Pop()); <span class="hljs-comment">// Output: 20</span>
        Console.WriteLine(intStack.Peek()); <span class="hljs-comment">// Output: 10</span>

        <span class="hljs-comment">// Stack for strings</span>
        Stack&lt;<span class="hljs-keyword">string</span>&gt; stringStack = <span class="hljs-keyword">new</span> Stack&lt;<span class="hljs-keyword">string</span>&gt;();
        stringStack.Push(<span class="hljs-string">"Hello"</span>);
        stringStack.Push(<span class="hljs-string">"World"</span>);
        Console.WriteLine(stringStack.Pop()); <span class="hljs-comment">// Output: World</span>
        Console.WriteLine(stringStack.Peek()); <span class="hljs-comment">// Output: Hello</span>
    }
}
</code></pre>
<p>In this example, we create two instances of the <code>Stack</code> class: one that stores integers and another that stores strings. The flexibility of generics allows us to use the same class to work with different data types, making our code more reusable and concise.</p>
<h3 id="heading-how-to-extend-the-generic-class">How to Extend the Generic Class</h3>
<p>Let’s take it a step further and extend our <code>Stack</code> class to include a method that returns all items as an array:</p>
<pre><code class="lang-csharp"><span class="hljs-function"><span class="hljs-keyword">public</span> T[] <span class="hljs-title">ToArray</span>(<span class="hljs-params"></span>)</span>
{
    <span class="hljs-keyword">return</span> items.ToArray();
}
</code></pre>
<p>Now, you can easily convert the stack’s items into an array:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">int</span>[] intArray = intStack.ToArray();
<span class="hljs-keyword">string</span>[] stringArray = stringStack.ToArray();
</code></pre>
<p>This extension further showcases the power of generics, allowing the same method to work with different data types seamlessly.</p>
<h3 id="heading-key-points-to-remember-about-generic-classes">Key Points to Remember About Generic Classes</h3>
<ul>
<li><p><strong>Flexibility</strong>: Generic classes can handle any data type, making them adaptable and reusable.</p>
</li>
<li><p><strong>Type safety</strong>: Using type parameters ensures that your code is type-safe, catching errors during compile-time instead of runtime.</p>
</li>
<li><p><strong>Code reuse</strong>: Generics remove the need to duplicate code for different data types, resulting in cleaner and easier-to-maintain code.</p>
</li>
<li><p><strong>Type parameters</strong>: Generic classes use type parameters as placeholders for the actual data types you will use when creating an instance of the class.</p>
</li>
</ul>
<p>Generic classes are crucial in C# for building flexible, reusable, and type-safe code. By learning and using generics, you can create more reliable and maintainable applications.</p>
<h2 id="heading-internal-classes-in-c-sharp">Internal Classes in C Sharp</h2>
<p>Internal classes in C# are a powerful way to encapsulate implementation details within an assembly. By using the <code>internal</code> access modifier, you can restrict access to certain classes, ensuring they are only accessible within the same assembly.</p>
<p>This is particularly useful for hiding complex logic or utility classes that are not intended to be exposed to the public API of your library or application.</p>
<h3 id="heading-why-use-internal-classes">Why Use Internal Classes?</h3>
<p>In a large application, you may have classes that should only be used internally by your code and not by external consumers. For example, helper classes, utility functions, or components of a larger system that do not need to be exposed outside the assembly can be marked as <code>internal</code>. This ensures that your public API remains clean and focused while still allowing full functionality within the assembly.</p>
<h3 id="heading-example-defining-an-internal-class">Example: Defining an Internal Class</h3>
<p>Let’s consider a scenario where you have a library that processes orders. You might have a class that handles the complex logic of calculating discounts, but you don't want this class to be accessible to users of your library. Instead, you only expose the main <code>OrderProcessor</code> class, keeping the discount logic hidden with an internal class.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Define a public class that uses an internal class</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">OrderProcessor</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">ProcessOrder</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> orderId</span>)</span>
    {
        <span class="hljs-comment">// Internal class is used here</span>
        DiscountCalculator calculator = <span class="hljs-keyword">new</span> DiscountCalculator();
        <span class="hljs-keyword">decimal</span> discount = calculator.CalculateDiscount(orderId);
        Console.WriteLine(<span class="hljs-string">$"Order <span class="hljs-subst">{orderId}</span> processed with a discount of <span class="hljs-subst">{discount:C}</span>"</span>);
    }

    <span class="hljs-comment">// Internal class that handles discount calculations</span>
    <span class="hljs-keyword">internal</span> <span class="hljs-keyword">class</span> <span class="hljs-title">DiscountCalculator</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">decimal</span> <span class="hljs-title">CalculateDiscount</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> orderId</span>)</span>
        {
            <span class="hljs-comment">// Complex discount calculation logic</span>
            <span class="hljs-keyword">return</span> orderId * <span class="hljs-number">0.05</span>m;
        }
    }
}
</code></pre>
<p>In this example, the <code>DiscountCalculator</code> class is marked as <code>internal</code>, meaning it’s only accessible within the assembly. The <code>OrderProcessor</code> class, which is <code>public</code>, uses this internal class to process orders. External users of the library can call <code>ProcessOrder</code> without needing to know about or interact with the <code>DiscountCalculator</code> class.</p>
<h3 id="heading-how-to-use-the-internal-class-in-programcs">How to Use the Internal Class in <code>Program.cs</code></h3>
<p>Now, let's see how this works in practice:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
    {
        OrderProcessor processor = <span class="hljs-keyword">new</span> OrderProcessor();
        processor.ProcessOrder(<span class="hljs-number">12345</span>); <span class="hljs-comment">// Output: Order 12345 processed with a discount of $617.25</span>
    }
}
</code></pre>
<p>In this example, the <code>ProcessOrder</code> method is publicly accessible, but the internal workings of discount calculation remain hidden, providing a clean and secure API.</p>
<h3 id="heading-key-points-to-remember-about-internal-classes">Key Points to Remember About Internal Classes</h3>
<ul>
<li><p><strong>Limited access</strong>: Internal classes can only be accessed within the same assembly, which helps keep your public API simple and focused.</p>
</li>
<li><p><strong>Encapsulation</strong>: They are used to hide implementation details, like helper functions or complex logic, that shouldn't be publicly visible.</p>
</li>
<li><p><strong>Visibility control</strong>: The <code>internal</code> access modifier lets you control which classes and members are visible, ensuring only the necessary parts of your code are accessible to other assemblies.</p>
</li>
</ul>
<p>Internal classes are important for managing complex applications, allowing you to control what parts of your code can be accessed from outside your assembly. By hiding details and limiting access, you can keep your codebase clean, easy to maintain, and secure.</p>
<h2 id="heading-nested-classes-in-c-sharp">Nested Classes in C Sharp</h2>
<p>Nested classes in C# are defined within another class. This structure is useful for grouping related classes together and encapsulating the implementation details. Nested classes can be either static or non-static, and they have direct access to the private members of their enclosing class.</p>
<h3 id="heading-why-use-nested-classes">Why Use Nested Classes?</h3>
<p>Nested classes are particularly useful when a class is closely tied to the logic of another class and isn’t meant to be used independently. They allow you to encapsulate helper classes, hide them from other parts of the program, and keep related code together. This can lead to a cleaner, more organized codebase.</p>
<h3 id="heading-example-defining-a-nested-class">Example: Defining a Nested Class</h3>
<p>Let’s consider a scenario where we have a class that represents a <code>Car</code> and another class that represents a <code>Engine</code>. Since the <code>Engine</code> class is closely related to the <code>Car</code> class and doesn’t make much sense on its own, we can define it as a nested class within <code>Car</code>.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Define a class with a nested class</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Car</span>
{
    <span class="hljs-comment">// Define private fields</span>
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> model;
    <span class="hljs-keyword">private</span> Engine carEngine;

   <span class="hljs-comment">// Constructor</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Car</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> model</span>)</span>
    {
        <span class="hljs-keyword">this</span>.model = model;
        carEngine = <span class="hljs-keyword">new</span> Engine();
    }


    <span class="hljs-comment">// Method to start the car</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">StartCar</span>(<span class="hljs-params"></span>)</span>
    {
        carEngine.StartEngine();
        Console.WriteLine(<span class="hljs-string">$"<span class="hljs-subst">{model}</span> is starting..."</span>);
    }

    <span class="hljs-comment">// Nested class</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Engine</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">StartEngine</span>(<span class="hljs-params"></span>)</span>
        {
            Console.WriteLine(<span class="hljs-string">"Engine started."</span>);
        }
    }
}
</code></pre>
<p>In this example, the <code>Car</code> class has a private field <code>model</code> and a method <code>StartCar</code> that starts the car. The <code>Engine</code> class is nested within the <code>Car</code> class and contains a <code>StartEngine</code> method. By nesting <code>Engine</code> inside <code>Car</code>, we express the close relationship between the two.</p>
<h3 id="heading-how-to-use-the-nested-class-in-programcs">How to Use the Nested Class in <code>Program.cs</code></h3>
<p>Let’s see how we can use the <code>Car</code> class and its nested <code>Engine</code> class in a program:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
    {
        Car myCar = <span class="hljs-keyword">new</span> Car(<span class="hljs-string">"Toyota"</span>);
        myCar.StartCar(); <span class="hljs-comment">// Output: Engine started. Toyota is starting...</span>

        <span class="hljs-comment">// Although you can create an instance of the nested class separately, it usually makes sense to use it through the outer class</span>
        Car.Engine engine = <span class="hljs-keyword">new</span> Car.Engine();
        engine.StartEngine(); <span class="hljs-comment">// Output: Engine started.</span>
    }
}
</code></pre>
<p>In this example, we create an instance of the <code>Car</code> class and call the <code>StartCar</code> method, which internally calls the <code>StartEngine</code> method of the nested <code>Engine</code> class. While it's possible to instantiate the nested class separately, it’s more common to access it through the outer class, emphasizing the relationship between the two.</p>
<h3 id="heading-key-points-to-remember-about-nested-classes">Key Points to Remember About Nested Classes</h3>
<ul>
<li><p><strong>Encapsulation</strong>: Nested classes keep details hidden that shouldn't be seen outside the main class.</p>
</li>
<li><p><strong>Access to private members</strong>: Nested classes can access private parts of the main class, making them good for helper classes that need to work with the main class's internal parts.</p>
</li>
<li><p><strong>Organization</strong>: Use nested classes to keep related classes together, which makes the code cleaner and more organized.</p>
</li>
<li><p><strong>Static or non-static</strong>: Nested classes can be static or non-static. Static nested classes can't access the instance parts of the main class directly, but non-static nested classes can.</p>
</li>
</ul>
<p>Nested classes are a useful way to organize your code, especially for complex objects with closely related parts. Keeping related classes together makes your code easier to manage and maintain.</p>
<h2 id="heading-partial-classes-in-c-sharp">Partial Classes in C Sharp</h2>
<p>Partial classes in C# allow you to split a class definition across multiple files. This feature is particularly useful in large projects, where it can be beneficial to break a complex class into smaller, more manageable sections.</p>
<p>By using the <code>partial</code> keyword, you can organize your code better, especially when working with generated code or collaborating in a team environment.</p>
<h3 id="heading-why-use-partial-classes">Why Use Partial Classes?</h3>
<p>Imagine you’re working on a large application where a single class contains hundreds of lines of code. This can become difficult to manage and maintain. By using partial classes, you can divide the class into logical parts, each residing in a separate file. This not only makes the code more readable but also allows multiple developers to work on different parts of the class simultaneously without causing merge conflicts.</p>
<h3 id="heading-example-defining-a-partial-class-in-c">Example: Defining a Partial Class in C</h3>
<p>Let’s say we have a class that handles various operations for an employee management system. Instead of putting all methods in one file, we can split them across multiple files using partial classes.</p>
<p><strong>File 1:</strong> <code>PartialClass_Methods1.cs</code></p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Define a partial class</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">partial</span> <span class="hljs-keyword">class</span> <span class="hljs-title">EmployeeOperations</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">AddEmployee</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> name</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Employee <span class="hljs-subst">{name}</span> added."</span>);
    }
}
</code></pre>
<p><strong>File 2:</strong> <code>PartialClass_Methods2.cs</code></p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Define the other part of the partial class</span>
<span class="hljs-keyword">public</span> <span class="hljs-keyword">partial</span> <span class="hljs-keyword">class</span> <span class="hljs-title">EmployeeOperations</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">RemoveEmployee</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> name</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Employee <span class="hljs-subst">{name}</span> removed."</span>);
    }
}
</code></pre>
<p>In these examples, the <code>EmployeeOperations</code> class is split into two files, each containing a part of the class. The first file handles adding employees, while the second file handles removing them.</p>
<h3 id="heading-how-to-use-the-partial-class-in-programcs">How to Use the Partial Class in <code>Program.cs</code></h3>
<p>Now, let’s use the <code>EmployeeOperations</code> class in our <code>Program.cs</code> file:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">class</span> <span class="hljs-title">Program</span>
{
    <span class="hljs-function"><span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Main</span>(<span class="hljs-params"><span class="hljs-keyword">string</span>[] args</span>)</span>
    {
        EmployeeOperations operations = <span class="hljs-keyword">new</span> EmployeeOperations();

        operations.AddEmployee(<span class="hljs-string">"John Doe"</span>);    <span class="hljs-comment">// Output: Employee John Doe added.</span>
        operations.RemoveEmployee(<span class="hljs-string">"John Doe"</span>); <span class="hljs-comment">// Output: Employee John Doe removed.</span>
    }
}
</code></pre>
<p>In this example, the <code>EmployeeOperations</code> class, although defined in multiple files, behaves like a single class. The methods <code>AddEmployee</code> and <code>RemoveEmployee</code> are seamlessly combined, providing a clean and organized way to manage operations.</p>
<h3 id="heading-key-points-to-remember-about-partial-classes">Key Points to Remember About Partial Classes</h3>
<ul>
<li><p><strong>Code organization</strong>: Partial classes help keep large classes organized by splitting them into smaller, focused sections.</p>
</li>
<li><p><strong>Team collaboration</strong>: Multiple developers can work on different parts of the same class without interfering with each other’s code.</p>
</li>
<li><p><strong>Generated code</strong>: Often used with auto-generated code, where part of the class is generated by a tool, and the rest is written manually.</p>
</li>
</ul>
<p>Partial classes are a powerful feature in C# that allows for better code management, especially in large-scale applications. By breaking down a class into logical components, you can maintain clean, readable, and maintainable code.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>Classes are the building blocks of object-oriented programming in C#. By understanding the different types of classes—abstract, static, sealed, concrete, and singleton—you can create well-structured, maintainable, and efficient code.</p>
<p>Whether you’re designing utility classes, defining abstract interfaces, or encapsulating complex logic, classes play a crucial role in shaping your application’s architecture.</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Create a Minimal API in .NET Core – A Step By Step Handbook ]]>
                </title>
                <description>
                    <![CDATA[ Minimal APIs are an exciting feature introduced in .NET 6, designed to revolutionize how you create APIs. Imagine building robust APIs with minimal code and zero boilerplate—no more wrestling with controllers, routing, or middleware. That’s what mini... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/create-a-minimal-api-in-net-core-handbook/</link>
                <guid isPermaLink="false">674de68794b89afe5676934e</guid>
                
                    <category>
                        <![CDATA[ dotnet ]]>
                    </category>
                
                    <category>
                        <![CDATA[ .NET ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Web API ]]>
                    </category>
                
                    <category>
                        <![CDATA[ MinimalApi ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Mon, 02 Dec 2024 16:55:35 +0000</pubDate>
                <media:content url="https://cdn.hashnode.com/res/hashnode/image/upload/v1733158500882/9af04a12-2121-4efd-a66f-00330896e358.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Minimal APIs are an exciting feature introduced in .NET 6, designed to revolutionize how you create APIs.</p>
<p>Imagine building robust APIs with minimal code and zero boilerplate—no more wrestling with controllers, routing, or middleware. That’s what minimal APIs allow you to do. The idea with these APIs is to streamline the development process, making it incredibly easy and efficient.</p>
<p>In this article, we'll dive into the world of minimal APIs in .NET 8 and guide you through creating a fully functional bookstore API. You'll learn how to get all books, retrieve a book by its ID, add new books, and even delete books. Let’s get started.</p>
<h1 id="heading-table-of-contents">Table of Contents</h1>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-introduction-to-minimal-apis">Introduction to Minimal APIs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-minimal-api">How to Create a Minimal API</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-http-methods-in-controller-based-and-minimal-apis">HTTP Methods in Controller-based and Minimal APIs</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-minimal-api-project-files">Minimal API Project Files</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-the-models">How to Create the Models</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-the-database-context">How to Create the Database Context</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-a-contract">How to Create a Contract</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-services">How to Add Services</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-exceptions">How to Create Exceptions</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-create-the-api-endpoints">How to Create the API Endpoints</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-add-seed-data-to-the-database">How to Add Seed Data to the Database</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-perform-a-migration">How to Perform a Migration</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-how-to-test-the-api-endpoints">How to Test the API Endpoints</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before we get going, make sure you have the following prerequisites installed on your machine:</p>
<ul>
<li><p><a target="_blank" href="https://dotnet.microsoft.com/download/dotnet/8.0">.NET 8 SDK</a></p>
</li>
<li><p><a target="_blank" href="https://code.visualstudio.com/download">Visual Studio Code</a> or any other code editor of your choice</p>
</li>
<li><p><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp">C# Dev Kit</a> for Visual Studio Code</p>
</li>
</ul>
<p>Alternatively, you can use Visual Studio 2022, which comes with built-in support for .NET 8. But in this article, we'll be using Visual Studio Code. It’s lightweight, easy to use, and cross-platform.</p>
<p>We’ll use Swagger UI to test our API. Swagger UI is a powerful tool that allows you to interact with your API directly from your browser. It provides a user-friendly interface to test your API endpoints, making it easier to test and debug your API.</p>
<p>When you create a new project, it will automatically install the necessary packages and configure the project to use Swagger UI. .NET 8 includes Swagger UI by default, so whether you create your application in Visual Studio or with .NET, Swagger UI will be configured for you.</p>
<p>Run your application, and the Swagger UI will automatically open in your browser – but since we are using VS Code, we need to click on the port number on our terminal.</p>
<p>You can find the source code for this project on <a target="_blank" href="https://github.com/Clifftech123/bookapi-minimal">GitHub</a>.</p>
<h2 id="heading-introduction-to-minimal-apis">Introduction to Minimal APIs</h2>
<p>Imagine working in a codebase with numerous endpoints, making it quite large and complex. Traditionally, building an API in <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core involves using controllers, routing, middleware, and a significant amount of boilerplate code. But there are two approaches to building an API in ASP.NET Core: the traditional way and the minimal way.</p>
<p>The traditional way is familiar to most developers, involving controllers and extensive infrastructure code. The minimal way, introduced in <code>.NET 6</code>, allows you to create APIs with minimal code and zero boilerplate. This approach simplifies the development process, enabling you to focus on writing business logic rather than dealing with infrastructure code.</p>
<p>Minimal APIs are lightweight, fast, and perfect for building small to medium-sized APIs. They are ideal for prototyping, building microservices, or creating simple APIs that don't require much complexity. In this handbook, we'll explore the world of minimal APIs in .NET 6 and learn how to create a fully functional bookstore API from scratch.</p>
<h2 id="heading-how-to-create-a-minimal-api">How to Create a Minimal API</h2>
<p>Creating a minimal API is straightforward when using the <code>dotnet CLI</code>, as the default template is already a minimal API. But if you use Visual Studio, you'll need to remove the boilerplate code that comes with the project template.</p>
<p>Let's start by using the <code>dotnet CLI</code> to create a minimal API project.</p>
<pre><code class="lang-bash">
dotnet new webapi  -n BookStoreApi
</code></pre>
<p>The <code>dotnet new webapi</code> command creates a new minimal API project named <code>BookStoreApi</code>. This project contains the necessary files and folders to get you started.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732623879052/3db8614b-7b27-43ce-ad84-9fa66001b535.png" alt="Minimal API Project Files   Structure  " width="2556" height="1370" loading="lazy"></p>
<p>Let's explore the project structure:</p>
<ul>
<li><p><code>Program.cs</code>: The entry point of the application, where the host is configured.</p>
</li>
<li><p><code>bookapi-minimal.sln</code>: The solution file that contains the project.</p>
</li>
<li><p><code>bookapi-minimal.http</code>: A file that contains sample HTTP requests to test the API.</p>
</li>
<li><p><code>bookapi-minimal.csproj</code>: The project file that contains the project configuration.</p>
</li>
<li><p><code>appsettings.json</code>: The configuration file that stores application settings.</p>
</li>
<li><p><code>appsettings.Development.json</code> : The configuration file for the development environment.</p>
</li>
</ul>
<p>When you open the program.cs file, you'll notice that the code is minimal. The <code>Program.cs</code> file contains the following code:</p>
<pre><code class="lang-csharp">
<span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);

<span class="hljs-comment">// Add services to the container.</span>
<span class="hljs-comment">// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle</span>
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

<span class="hljs-keyword">var</span> app = builder.Build();

<span class="hljs-comment">// Configure the HTTP request pipeline.</span>
<span class="hljs-keyword">if</span> (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

<span class="hljs-keyword">var</span> summaries = <span class="hljs-keyword">new</span>[]
{
    <span class="hljs-string">"Freezing"</span>, <span class="hljs-string">"Bracing"</span>, <span class="hljs-string">"Chilly"</span>, <span class="hljs-string">"Cool"</span>, <span class="hljs-string">"Mild"</span>, <span class="hljs-string">"Warm"</span>, <span class="hljs-string">"Balmy"</span>, <span class="hljs-string">"Hot"</span>, <span class="hljs-string">"Sweltering"</span>, <span class="hljs-string">"Scorching"</span>
};

app.MapGet(<span class="hljs-string">"/weatherforecast"</span>, () =&gt;
{
    <span class="hljs-keyword">var</span> forecast =  Enumerable.Range(<span class="hljs-number">1</span>, <span class="hljs-number">5</span>).Select(index =&gt;
        <span class="hljs-keyword">new</span> WeatherForecast
        (
            DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
            Random.Shared.Next(<span class="hljs-number">-20</span>, <span class="hljs-number">55</span>),
            summaries[Random.Shared.Next(summaries.Length)]
        ))
        .ToArray();
    <span class="hljs-keyword">return</span> forecast;
})
.WithName(<span class="hljs-string">"GetWeatherForecast"</span>)
.WithOpenApi();

app.Run();

<span class="hljs-keyword">record</span> <span class="hljs-title">WeatherForecast</span>(<span class="hljs-title">DateOnly</span> <span class="hljs-title">Date</span>, <span class="hljs-title">int</span> <span class="hljs-title">TemperatureC</span>, <span class="hljs-title">string</span>? <span class="hljs-title">Summary</span>)
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> TemperatureF =&gt; <span class="hljs-number">32</span> + (<span class="hljs-keyword">int</span>)(TemperatureC / <span class="hljs-number">0.5556</span>);
}
</code></pre>
<p>If you don't fully understand the code yet, don't worry—we'll cover it in detail in the upcoming sections. The key takeaway is that minimal APIs require very little code, which is one of their main advantages.</p>
<p>The default code sets up a simple weather forecast API that you can use to test your setup. It generates a list of weather forecasts and returns them when you make a <code>GET</code> request to the <code>/weatherforecast</code> endpoint. Also, the code includes Swagger UI to help you test the API.</p>
<p>Pay special attention to the <code>app.MapGet</code> method, which maps a route to a handler function. In this case, it maps the <code>/weatherforecast</code> route to a function that returns a list of weather forecasts. We'll use similar methods to create our own endpoints in the next sections.</p>
<p>Before we start creating our project folder structure, let's understand the HTTP methods in both Controller-based and Minimal APIs.</p>
<h2 id="heading-http-methods-in-controller-based-and-minimal-apis">HTTP Methods in Controller-based and Minimal APIs</h2>
<p>In a Controller-based approach, which is the traditional way of creating web APIs, you need to create a controller class and define methods for each HTTP method. For example:</p>
<ul>
<li><p>To create a <code>GET</code> method, you use the <code>[HttpGet]</code> attribute.</p>
</li>
<li><p>To create a <code>POST</code> method, you use the <code>[HttpPost]</code> attribute.</p>
</li>
<li><p>To create a <code>PUT</code> method, you use the <code>[HttpPut]</code> attribute.</p>
</li>
<li><p>To create a <code>DELETE</code> method, you use the <code>[HttpDelete]</code> attribute.</p>
</li>
</ul>
<p>This is how endpoints are created in a Controller-based approach.</p>
<p>In contrast, Minimal APIs use methods like <code>app.MapGet</code>, <code>app.MapPost</code>, <code>app.MapPut</code>, and <code>app.MapDelete</code> to create endpoints. This is the main difference between the two approaches: Controller-based APIs use attributes to define endpoints, while Minimal APIs use methods.</p>
<p>Now that you understand how to handle HTTP requests in both Controller-based and Minimal APIs, let's create our project folder structure.</p>
<p>Before we create our project folder structure, let's first run what we have. As we learned earlier, when you create a project with either Visual Studio or .NET CLI, it comes with a default WeatherForecast project which we can run and see on the UI. Let's run it to ensure everything works before we go on to create our project folder.</p>
<p>Run this command:</p>
<pre><code class="lang-bash">
dotnet run
</code></pre>
<p>You should see the following output:</p>
<pre><code class="lang-bash">info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5228
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: D:\Devolopemnt\Dotnet\bookapi-minimal
</code></pre>
<p>This means the application is running and listening on <a target="_blank" href="http://localhost:5228"><code>http://localhost:5228</code></a>. As I mentioned above, since we are using the <code>dotnet CLI</code> and Visual Studio Code, the application will not automatically open the browser for us. We need to do this manually.</p>
<p>Open your browser and navigate to <a target="_blank" href="http://localhost:5228/swagger/index.html"><code>http://localhost:5228/swagger/index.html</code></a> to see the default response from the API.</p>
<p>You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732623894640/b882a1ee-3957-4958-8f59-20b44fe7fb7d.png" alt="Swagger UI " width="2436" height="1169" loading="lazy"></p>
<p>Now the next thing for us to do is find a way to structure our project and create the necessary files and folders to get us started.</p>
<h2 id="heading-minimal-api-project-files">Minimal API Project Files</h2>
<p>To organize our project, we will create a structured folder hierarchy. This will help keep our code clean and maintainable. Here is the folder structure we will use:</p>
<ul>
<li><p><strong>AppContext</strong>: Contains the database context and related configurations.</p>
</li>
<li><p><strong>Configurations</strong>: Holds Entity Framework Core configurations and seed data for the database.</p>
</li>
<li><p><strong>Contracts</strong>: Contains Data Transfer Objects (DTOs) used in our application.</p>
</li>
<li><p><strong>Endpoints</strong>: Where we define and configure our minimal API endpoints.</p>
</li>
<li><p><strong>Exceptions</strong>: Contains custom exception classes used in the project.</p>
</li>
<li><p><strong>Extensions</strong>: Holds extension methods that we will use throughout the project.</p>
</li>
<li><p><strong>Models</strong>: Contains business logic models.</p>
</li>
<li><p><strong>Services</strong>: Contains service classes that implement business logic.</p>
</li>
<li><p><strong>Interfaces</strong>: Holds interface definitions used to map our services.</p>
</li>
</ul>
<p>In Visual Studio Code, you can create this folder structure as follows:</p>
<pre><code class="lang-bash">- AppContext
- Configurations
- Contracts
- Endpoints
- Exceptions
- Extensions
- Models
- Services
- Interfaces
</code></pre>
<p>After setting up, your project folder structure should look like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732623997951/8118c444-0d28-4bb7-8cad-2a9fd88c8c25.png" alt="BookApi Project Folder Structure " width="1920" height="890" loading="lazy"></p>
<p>Now that our project Structure is set up we can go ahead and start writing our code. Let's start by creating our models.</p>
<h2 id="heading-how-to-create-the-models">How to Create the Models</h2>
<p>In this section, we will create models for our application. Models are the building blocks of our application, representing the data that our application will work with. For our example, we will create a model for a book.</p>
<p>To get started, create a folder named <code>Models</code> in your project directory. Inside this folder, create a file named <code>BookModel.cs</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Models/BookModel.cs</span>


<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookModel</span>
    {
        <span class="hljs-keyword">public</span> Guid Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Author { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Description { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Category { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Language { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> TotalPages { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>This <code>BookModel class</code> defines the properties that represent the details of a book, such as its <code>title</code>, <code>author</code>, <code>description</code>, <code>category</code>, <code>language</code>, and <code>total pages</code>. Each property is designed to hold specific information about the book, making it easy to manage and manipulate book data within our application.</p>
<p>Now that we have created our model, let's create our database context.</p>
<h2 id="heading-how-to-create-the-database-context">How to Create the Database Context</h2>
<p>The database context is a class that represents a session with the database. It’s responsible for interacting with the database and executing database operations. In our application, we will use Entity Framework Core to interact with our database.</p>
<h3 id="heading-install-the-required-packages">Install the Required Packages</h3>
<p>Before creating our database context, we need to install the following packages:</p>
<ul>
<li><p><a target="_blank" href="http://Microsoft.EntityFrameworkCore.Design"><code>Microsoft.EntityFrameworkCore.Design</code></a></p>
</li>
<li><p><code>Microsoft.EntityFrameworkCore</code></p>
</li>
<li><p><code>Microsoft.EntityFrameworkCore.SqlServer</code></p>
</li>
<li><p><a target="_blank" href="http://Microsoft.EntityFrameworkCore.Tools"><code>Microsoft.EntityFrameworkCore.Tools</code></a></p>
</li>
<li><p><code>FluentValidation.DependencyInjectionExtensions</code></p>
</li>
</ul>
<p>You can install these packages using the following commands:</p>
<pre><code class="lang-bash">dotnet add package Microsoft.EntityFrameworkCore.Design
dotnet add package Microsoft.EntityFrameworkCore
dotnet add package Microsoft.EntityFrameworkCore.SqlServer
dotnet add package Microsoft.EntityFrameworkCore.Tools
dotnet add package FluentValidation.DependencyInjectionExtensions
</code></pre>
<h3 id="heading-verify-package-installation">Verify Package Installation</h3>
<p>To verify that the packages are installed, open the <code>bookapi-minimal.csproj</code> file in your project's root directory. You should see the installed packages listed as follows:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Project</span> <span class="hljs-attr">Sdk</span>=<span class="hljs-string">"Microsoft.NET.Sdk.Web"</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">TargetFramework</span>&gt;</span>net8.0<span class="hljs-tag">&lt;/<span class="hljs-name">TargetFramework</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Nullable</span>&gt;</span>enable<span class="hljs-tag">&lt;/<span class="hljs-name">Nullable</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ImplicitUsings</span>&gt;</span>enable<span class="hljs-tag">&lt;/<span class="hljs-name">ImplicitUsings</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">RootNamespace</span>&gt;</span>bookapi_minimal<span class="hljs-tag">&lt;/<span class="hljs-name">RootNamespace</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"FluentValidation.DependencyInjectionExtensions"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"11.9.2"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.OpenApi"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.6"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.Design"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.8"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">IncludeAssets</span>&gt;</span>runtime; build; native; contentfiles; analyzers; buildtransitive<span class="hljs-tag">&lt;/<span class="hljs-name">IncludeAssets</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PrivateAssets</span>&gt;</span>all<span class="hljs-tag">&lt;/<span class="hljs-name">PrivateAssets</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">PackageReference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.SqlServer"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.Tools"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.8"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">IncludeAssets</span>&gt;</span>runtime; build; native; contentfiles; analyzers; buildtransitive<span class="hljs-tag">&lt;/<span class="hljs-name">IncludeAssets</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PrivateAssets</span>&gt;</span>all<span class="hljs-tag">&lt;/<span class="hljs-name">PrivateAssets</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">PackageReference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Swashbuckle.AspNetCore"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"6.4.0"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">Project</span>&gt;</span>
</code></pre>
<p>This confirms that the packages have been successfully installed.</p>
<p>Now let's create our database context.</p>
<p>In the AppContext folder, create a new file named <code>ApplicationContext.cs</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// AppContext/ApplicationContext.cs</span>

<span class="hljs-keyword">using</span> bookapi_minimal.Models;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.AppContext</span>
{

    <span class="hljs-function"><span class="hljs-keyword">public</span> class <span class="hljs-title">ApplicationContext</span>(<span class="hljs-params">DbContextOptions&lt;ApplicationContext&gt; options</span>) : <span class="hljs-title">DbContext</span>(<span class="hljs-params">options</span>)</span>
    {

        <span class="hljs-comment">// Default schema for the database context</span>
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">const</span> <span class="hljs-keyword">string</span> DefaultSchema = <span class="hljs-string">"bookapi"</span>;


       <span class="hljs-comment">// DbSet to represent the collection of books in our database</span>
        <span class="hljs-keyword">public</span> DbSet&lt;BookModel&gt; Books { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

        <span class="hljs-comment">// Constructor to configure the database context</span>

        <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnModelCreating</span>(<span class="hljs-params">ModelBuilder modelBuilder</span>)</span>
        {
            <span class="hljs-keyword">base</span>.OnModelCreating(modelBuilder);
            modelBuilder.HasDefaultSchema(DefaultSchema);

            modelBuilder.ApplyConfigurationsFromAssembly(<span class="hljs-keyword">typeof</span>(ApplicationContext).Assembly);

            modelBuilder.ApplyConfigurationsFromAssembly(<span class="hljs-keyword">typeof</span>(ApplicationContext).Assembly);

        }

    }
}
</code></pre>
<p>Let's break down the code above:</p>
<ul>
<li><p>We define a class named <code>ApplicationContext</code> that inherits from <code>DbContext</code>. The <code>DbContext</code> class is part of Entity Framework Core and represents a session with the database.</p>
</li>
<li><p>The constructor accepts an instance of <code>DbContextOptions&lt;ApplicationContext&gt;</code>. This constructor is used to configure the database context options.</p>
</li>
<li><p>We define a property named <code>Books</code> type <code>DbSet&lt;BookModel&gt;</code>. This property represents the collection of books in our database.</p>
</li>
<li><p>We override the <code>OnModelCreating</code> method to configure the database schema and apply any configurations defined in our application.</p>
</li>
</ul>
<p>Now that we have created our database context, let's create our extension method and register our database context in the dependency injection container.</p>
<h3 id="heading-create-an-extension-method">Create an Extension Method</h3>
<p>Before we create the extension method, let's understand what an extension method is in the context of <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core.</p>
<p>An extension method is a static method that adds new functionality to an existing type without modifying the original type. In <a target="_blank" href="http://ASP.NET">ASP.NET</a> Core, extension methods are commonly used to extend the functionality of the <code>IServiceCollection</code> interface, which is used to register services in the dependency injection container.</p>
<p>Services are components that provide functionality to an application, such as database access, logging, and configuration. By creating an extension method for the <code>IServiceCollection</code> interface, you can simplify the process of registering your services in the dependency injection container.</p>
<p>Instead of putting everything in the <code>Program.cs</code> file, we will create an extension method to register our services in the dependency injection container. This will help us keep our code clean and organized.</p>
<p>In the <code>Extensions</code> folder, create a new file named <code>ServiceExtensions.cs</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> System.Reflection;
<span class="hljs-keyword">using</span> bookapi_minimal.AppContext;
<span class="hljs-keyword">using</span> FluentValidation;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Extensions</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ServiceExtensions</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">AddApplicationServices</span>(<span class="hljs-params"><span class="hljs-keyword">this</span> IHostApplicationBuilder builder</span>)</span>
        {
            <span class="hljs-keyword">if</span> (builder == <span class="hljs-literal">null</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArgumentNullException(<span class="hljs-keyword">nameof</span>(builder));
            <span class="hljs-keyword">if</span> (builder.Configuration == <span class="hljs-literal">null</span>) <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> ArgumentNullException(<span class="hljs-keyword">nameof</span>(builder.Configuration));

            <span class="hljs-comment">// Adding the database context</span>
            builder.Services.AddDbContext&lt;ApplicationContext&gt;(configure =&gt;
            {
                configure.UseSqlServer(builder.Configuration.GetConnectionString(<span class="hljs-string">"sqlConnection"</span>));
            });

            <span class="hljs-comment">// Adding validators from the current assembly</span>
            builder.Services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
        }
    }
}
</code></pre>
<p>Let's break down the code above:</p>
<ul>
<li><p>We define a static class named <code>ServiceExtensions</code> that contains an extension method named <code>AddApplicationServices</code>. This method extends the <code>IHostApplicationBuilder</code> interface, which is used to configure the application's request processing pipeline.</p>
</li>
<li><p>The <code>AddApplicationServices</code> method accepts an instance of <code>IHostApplicationBuilder</code> as a parameter. This parameter is used to access the application's configuration and services.</p>
</li>
<li><p>We add the <code>ApplicationContext</code> to the dependency injection container and configure it to use SQL Server as the database provider. We retrieve the connection string from the <code>appsettings.json</code> file using the <code>GetConnectionString</code> method.</p>
</li>
<li><p>We add <code>validators</code> from the current <code>assembly</code> using the <code>AddValidatorsFromAssembly</code> method. This method scans the current assembly for classes that implement the IValidator interface and registers them in the dependency injection container.</p>
</li>
</ul>
<p>Next, we need to add the connection string to the <code>appsettings.json</code> file. Add the following code to your <code>appsettings.json</code> file:</p>
<pre><code class="lang-json">{ 
     <span class="hljs-attr">"ConnectionStrings"</span>: {
    <span class="hljs-attr">"sqlConnection"</span>: <span class="hljs-string">"Server=localhost\\SQLEXPRESS02;Database=BookAPIMinimalAPI;Integrated Security=true;TrustServerCertificate=true;"</span>
  }
  }
</code></pre>
<p>Make sure to replace <code>your_password</code> it with your actual SQL Server password.</p>
<p>Your <code>appsettings.json</code> file should look like this:</p>
<pre><code class="lang-json">
{
  <span class="hljs-attr">"Logging"</span>: {
    <span class="hljs-attr">"LogLevel"</span>: {
      <span class="hljs-attr">"Default"</span>: <span class="hljs-string">"Information"</span>,
      <span class="hljs-attr">"Microsoft.AspNetCore"</span>: <span class="hljs-string">"Warning"</span>
    }
  },
  <span class="hljs-attr">"ConnectionStrings"</span>: {
    <span class="hljs-attr">"sqlConnection"</span>: <span class="hljs-string">"Server=localhost\\SQLEXPRESS02;Database=BookAPIMinimalAPI;Integrated Security=true;TrustServerCertificate=true;"</span>
  },
  <span class="hljs-attr">"AllowedHosts"</span>: <span class="hljs-string">"*"</span>
}
</code></pre>
<p>Congratulations! You have successfully created the database context, extension method, and connection string for your application. In the next section, we will create a Contract.</p>
<h2 id="heading-how-to-create-a-contract">How to Create a Contract</h2>
<p>Contracts are Data Transfer Objects (DTOs) that define the structure of the data exchanged between the client and the server. In our application, we will create contracts to represent the data sent and received by our API endpoints.</p>
<p>Here are the contracts we are going to create:</p>
<ul>
<li><p>CreateBookRequest: This represents the data sent when creating a new book.</p>
</li>
<li><p>UpdateBookRequest: tHI Represents the data sent when updating an existing book.</p>
</li>
<li><p>BookResponse: Represents the data returned when retrieving a book.</p>
</li>
<li><p>ErrorResponse: Represents the error response returned when an exception occurs.</p>
</li>
<li><p>ApiResponse: Represents the response returned by the API.</p>
</li>
</ul>
<p>In the <code>Contracts</code> folder, create a new file named <code>CreateBookRequest</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Contracts/CreateBookRequest.cs</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Contracts</span>
{

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">record</span> <span class="hljs-title">CreateBookRequest</span>
    { 

        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">init</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Author { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">init</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Description { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">init</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Category { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">init</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Language { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">init</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> TotalPages { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">init</span>; }
    }
}
</code></pre>
<p>In the <code>Contracts</code> folder, create a new file named <code>UpdateBookRequest</code> and add the following code:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Contracts/UpdateBookRequest.cs</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Contracts</span>
{

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">record</span> <span class="hljs-title">UpdateBookRequest</span>
    {
       <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Author { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Description { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Category { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Language { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> TotalPages { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    }
}
</code></pre>
<p>In the <code>Contracts</code> folder, create a new file named <code>BookResponse</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Contracts/BookResponse.cs</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Contracts</span>
{

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">record</span> <span class="hljs-title">BookResponse</span>
    {
        <span class="hljs-keyword">public</span> Guid Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Author { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Description { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Category { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Language { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> TotalPages { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>In the <code>Contracts</code> folder, create a new file named <code>ErrorResponse</code> and add the following code:</p>
<pre><code class="lang-csharp">

<span class="hljs-comment">// Contracts/ErrorResponse.cs</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Contracts</span>
{

        <span class="hljs-keyword">public</span> <span class="hljs-keyword">record</span> <span class="hljs-title">ErrorResponse</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> StatusCode { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Message { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    }

}
</code></pre>
<p>In the <code>Contracts</code> folder, create a new file named <code>ApiResponse</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Contracts/ApiResponse.cs</span>
<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Contracts</span>
{

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ApiResponse</span>&lt;<span class="hljs-title">T</span>&gt;
    {
        <span class="hljs-keyword">public</span> T Data { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Message { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">ApiResponse</span>(<span class="hljs-params">T data, <span class="hljs-keyword">string</span> message</span>)</span>
        {
            Data = data;
            Message = message;
        }
    }
}
</code></pre>
<p>These contracts help us define the structure of the data exchanged between the client and the server, making it easier to work with the data in our application.</p>
<p>In the next section, we will create services to implement the business logic of our application.</p>
<h2 id="heading-how-to-add-services">How to Add Services</h2>
<p>Services are components that provide functionality to an application. In our application, we will create services to implement the business logic of our application. We will create services to handle CRUD operations for books, validate book data, and handle exceptions.</p>
<p>In ASP.NET Core, services are registered in the dependency injection container and can be injected into other components, such as controllers and endpoints, But this is a minimal API so we will inject the services directly into the endpoints.</p>
<p>Let's create an interface for our services. In the <code>Interfaces</code> folder, create a new file named <code>IBookService.cs</code> and add the following code:</p>
<pre><code class="lang-csharp"> <span class="hljs-comment">// Interfaces/IBookService.cs</span>



<span class="hljs-keyword">using</span> bookapi_minimal.Contracts;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Interfaces</span>
{
      <span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IBookService</span>
    {
        <span class="hljs-function">Task&lt;BookResponse&gt; <span class="hljs-title">AddBookAsync</span>(<span class="hljs-params">CreateBookRequest createBookRequest</span>)</span>;
        <span class="hljs-function">Task&lt;BookResponse&gt; <span class="hljs-title">GetBookByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>;
        Task&lt;IEnumerable&lt;BookResponse&gt;&gt; GetBooksAsync();
        <span class="hljs-function">Task&lt;BookResponse&gt; <span class="hljs-title">UpdateBookAsync</span>(<span class="hljs-params">Guid id,  UpdateBookRequest  updateBookRequest</span>)</span>;
        <span class="hljs-function">Task&lt;<span class="hljs-keyword">bool</span>&gt; <span class="hljs-title">DeleteBookAsync</span>(<span class="hljs-params">Guid id</span>)</span>;
    }
}
</code></pre>
<p>Let's break down the code above: We have defined an interface named <code>IBookService</code> that contains methods to handle CRUD operations for books. The interface defines the following methods:</p>
<ul>
<li><p><code>AddBookAsync</code>: Adds a new book to the database.</p>
</li>
<li><p><code>GetBookByIdAsync</code>: Retrieves a book by its ID.</p>
</li>
<li><p><code>GetBooksAsync</code>: Retrieves all books from the database.</p>
</li>
<li><p><code>UpdateBookAsync</code>: Updates an existing book.</p>
</li>
</ul>
<p>We are using the Contract we created earlier in the <code>Contracts</code> folder. The <code>IBookService</code> interface defines the structure of the methods that will be implemented by the service classes. This helps us separate the interface from the implementation, making it easier to maintain and test our code.</p>
<p>Now that we have created the interface, let's create the service class that implements the interface.</p>
<h3 id="heading-how-to-implement-the-book-service">How to Implement the Book Service</h3>
<p>This service will implement the <code>IBookService</code> interface and provide the business logic for our application. In the <code>Services</code> folder, create a new file named <code>BookService.cs</code> . Your initial file should look like this:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Services/BookService.cs</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookService</span>
    {

    }
}
</code></pre>
<p>The first thing we need to do is add the interface to the <code>BookService</code> class. Update the <code>BookService</code> class to implement the <code>IBookService</code> interface as follows:</p>
<pre><code class="lang-csharp">

<span class="hljs-comment">// Services/BookService.cs</span>



<span class="hljs-keyword">using</span> bookapi_minimal.Interfaces;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookService</span>:<span class="hljs-title">IBookService</span>
    {

    }
}
</code></pre>
<p>When you do this, your VS Code might show an error because we have not implemented the methods in the interface. Let's go ahead and implement the methods in the <code>BookService</code> class.</p>
<p>In VS Code you can use the <code>Ctrl + .</code> shortcut to implement the methods in the interface. Then you will see the following code generated for you:</p>
<pre><code class="lang-csharp">
<span class="hljs-keyword">using</span> bookapi_minimal.Contracts;
<span class="hljs-keyword">using</span> bookapi_minimal.Interfaces;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Services</span>
{
     <span class="hljs-comment">// Service class for managing books</span>
   <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookService</span> : <span class="hljs-title">IBookService</span>
   {
       <span class="hljs-comment">// Method to add a new book to the database</span>
       <span class="hljs-function"><span class="hljs-keyword">public</span> Task&lt;BookResponse&gt; <span class="hljs-title">AddBookAsync</span>(<span class="hljs-params">CreateBookRequest createBookRequest</span>)</span>
       {
           <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
       }

      <span class="hljs-comment">// Method to Delete a book from the database</span>
       <span class="hljs-function"><span class="hljs-keyword">public</span> Task&lt;<span class="hljs-keyword">bool</span>&gt; <span class="hljs-title">DeleteBookAsync</span>(<span class="hljs-params">Guid id</span>)</span>
       {
           <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
       }

       <span class="hljs-comment">// Method to Get a book from the database by its ID</span>

       <span class="hljs-function"><span class="hljs-keyword">public</span> Task&lt;BookResponse&gt; <span class="hljs-title">GetBookByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
       {
           <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
       }

      <span class="hljs-comment">// Method to Get all books from the database</span>
       <span class="hljs-keyword">public</span> Task&lt;IEnumerable&lt;BookResponse&gt;&gt; GetBooksAsync()
       {
           <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
       }

       <span class="hljs-comment">// Method to Update a book in the database</span>
       <span class="hljs-function"><span class="hljs-keyword">public</span> Task&lt;BookResponse&gt; <span class="hljs-title">UpdateBookAsync</span>(<span class="hljs-params">Guid id, UpdateBookRequest updateBookRequest</span>)</span>
       {
           <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
       }
   }
}
</code></pre>
<p>Now you can see that the methods in the interface have been implemented in the <code>BookService</code> class. We will implement the business logic for each method in the next section.</p>
<p>Before we do that, let's add the necessary dependencies to the <code>BookService</code> class. We need to inject the <code>ApplicationContext</code> and <code>ILogger</code> dependencies into the <code>BookService</code> class. <code>ApplicationContext</code> is used to interact with the database, while <code>ILogger</code> is used for logging.</p>
<p>To inject the dependencies, update the <code>BookService</code> class as follows:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Services/BookService.cs</span>

<span class="hljs-comment">// ...</span>
 <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ApplicationContext _context; <span class="hljs-comment">// Database context</span>
  <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;BookService&gt; _logger; <span class="hljs-comment">// Logger for logging information and errors</span>

<span class="hljs-comment">//..</span>
</code></pre>
<p>Since we have added the dependencies, we need to update the <code>BookService</code> constructor to accept the dependencies. Update the <code>BookService</code> constructor as follows:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Services/BookService.cs</span>

<span class="hljs-comment">// ...</span>

  <span class="hljs-comment">// Constructor to initialize the database context and logger</span>
 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">BookService</span>(<span class="hljs-params">ApplicationContext context, ILogger&lt;BookService&gt; logger</span>)</span>
 {
            _context = context;
            _logger = logger;
}

<span class="hljs-comment">// ...</span>
</code></pre>
<p>Now that we have added the dependencies and updated the constructor, we can implement the business logic for each method in the <code>BookService</code> class.</p>
<p>Let's create logic for the CREATE, READ, UPDATE, and DELETE operations in the <code>BookService</code> class.</p>
<h3 id="heading-how-to-implement-the-addbookasync-method">How to Implement the <code>AddBookAsync</code> Method</h3>
<p>As I mentioned earlier, we’ll use the <code>AddBookAsync</code> method to add a new book to the database. In this method, we will create a new book entity, map the data from the <code>CreateBookRequest</code> object to the book entity, and save the book entity to the database. We will also return the book entity as an <code>BookResponse</code> object.</p>
<p>Update the <code>AddBookAsync</code> method in the <code>BookService</code> class as follows:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/BookService.cs</span>

<span class="hljs-comment">// ...</span>
 <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Add a new book</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="createBookRequest"&gt;</span>Book request to be added<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>Details of the created book<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;BookResponse&gt; <span class="hljs-title">AddBookAsync</span>(<span class="hljs-params">CreateBookRequest createBookRequest</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">var</span> book = <span class="hljs-keyword">new</span> BookModel
                {
                    Title = createBookRequest.Title,
                    Author = createBookRequest.Author,
                    Description = createBookRequest.Description,
                    Category = createBookRequest.Category,
                    Language = createBookRequest.Language,
                    TotalPages = createBookRequest.TotalPages
                };

                <span class="hljs-comment">// Add the book to the database</span>
                _context.Books.Add(book);
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
                _logger.LogInformation(<span class="hljs-string">"Book added successfully."</span>);

                <span class="hljs-comment">// Return the details of the created book</span>
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> BookResponse
                {
                    Id = book.Id,
                    Title = book.Title,
                    Author = book.Author,
                    Description = book.Description,
                    Category = book.Category,
                    Language = book.Language,
                    TotalPages = book.TotalPages
                };
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error adding book: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }
<span class="hljs-comment">// ...</span>
</code></pre>
<p>In this code, we are creating a new book entity from the <code>CreateBookRequest</code> object, mapping the data from the <code>CreateBookRequest</code> object to the book entity, saving the book entity to the database, and returning the book entity as a <code>BookResponse</code> object.</p>
<p>We are also logging information and errors using the <code>ILogger</code> dependency. If an exception occurs during the process, we log the error message and rethrow the exception.</p>
<p>Now that we have implemented the <code>AddBookAsync</code> method, let's implement the <code>GetBookByIdAsync</code> method.</p>
<h3 id="heading-how-to-implement-the-getbookbyidasync-method">How to Implement the <code>GetBookByIdAsync</code> Method</h3>
<p>The <code>GetBookByIdAsync</code> method is used to retrieve a book by its ID from the database. In this method, we will query the database for the book with the specified ID, map the book entity to a <code>BookResponse</code> object, and return the <code>BookResponse</code> object.</p>
<p>Update the <code>GetBookByIdAsync</code> method in the <code>BookService</code> class as follows:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Services/BookService.cs</span>

<span class="hljs-comment">//... </span>

    <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Get a book by its ID</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="id"&gt;</span>ID of the book<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>Details of the book<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;BookResponse&gt;  <span class="hljs-title">GetBookByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-comment">// Find the book by its ID</span>
                <span class="hljs-keyword">var</span> book = <span class="hljs-keyword">await</span> _context.Books.FindAsync(id);
                <span class="hljs-keyword">if</span> (book == <span class="hljs-literal">null</span>)
                {
                    _logger.LogWarning(<span class="hljs-string">$"Book with ID <span class="hljs-subst">{id}</span> not found."</span>);
                    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
                }

                <span class="hljs-comment">// Return the details of the book</span>
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> BookResponse
                {
                    Id = book.Id,
                    Title = book.Title,
                    Author = book.Author,
                    Description = book.Description,
                    Category = book.Category,
                    Language = book.Language,
                    TotalPages = book.TotalPages
                };
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error retrieving book: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }

<span class="hljs-comment">//...</span>
</code></pre>
<p>In this code, we are querying the database for the book with the specified ID, mapping the book entity to a <code>BookResponse</code> object, and returning the <code>BookResponse</code> object. We are also logging information and errors using the <code>ILogger</code> dependency.</p>
<p>If the book with the specified ID is not found, we log a warning message and return null. If an exception occurs during the process, we log the error message and rethrow the exception.</p>
<p>Now that we have implemented the <code>GetBookByIdAsync</code> method, let's implement the <code>GetBooksAsync</code> method.</p>
<h3 id="heading-how-to-implement-the-getbooksasync-method">How to Implement the <code>GetBooksAsync</code> Method</h3>
<p>The <code>GetBooksAsync</code> method is used to retrieve all books from the database. In this method, we will query the database for all books, map each book entity to a <code>BookResponse</code> object, and return a list of <code>BookResponse</code> objects.</p>
<p>Update the <code>GetBooksAsync</code> method in the <code>BookService</code> class as follows:</p>
<pre><code class="lang-csharp">

<span class="hljs-comment">// Services/BookService.cs</span>

<span class="hljs-comment">//... </span>


  <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Get all books</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>List of all books<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IEnumerable&lt;BookResponse&gt;&gt; GetBooksAsync()
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-comment">// Get all books from the database</span>
                <span class="hljs-keyword">var</span> books = <span class="hljs-keyword">await</span> _context.Books.ToListAsync();

                <span class="hljs-comment">// Return the details of all books</span>
                <span class="hljs-keyword">return</span> books.Select(book =&gt; <span class="hljs-keyword">new</span> BookResponse
                {
                    Id = book.Id,
                    Title = book.Title,
                    Author = book.Author,
                    Description = book.Description,
                    Category = book.Category,
                    Language = book.Language,
                    TotalPages = book.TotalPages
                });
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error retrieving books: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }
<span class="hljs-comment">//...</span>
</code></pre>
<p>Here, we are querying the database for all books, mapping each book entity to an <code>BookResponse</code> object, and returning a list of <code>BookResponse</code> objects. We are also logging information and errors using the <code>ILogger</code> dependency. If an exception occurs during the process, we log the error message and rethrow the exception.</p>
<p>Now that we have implemented the <code>GetBooksAsync</code> method, let's implement the <code>UpdateBookAsync</code> method.</p>
<h3 id="heading-how-to-implement-the-updatebookasync-method">How to Implement the <code>UpdateBookAsync</code> Method</h3>
<p>The <code>UpdateBookAsync</code> method is used to update an existing book in the database. In this method, we will query the database for the book with the specified ID, update the book entity with the data from the <code>UpdateBookRequest</code> object, save the updated book entity to the database, and return the updated book entity as a <code>BookResponse</code> object.</p>
<p>Update the <code>UpdateBookAsync</code> method in the <code>BookService</code> class as follows:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/BookService.cs</span>
 <span class="hljs-comment">//...</span>
 <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Update an existing book</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="id"&gt;</span>ID of the book to be updated<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="book"&gt;</span>Updated book model<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>Details of the updated book<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;BookResponse&gt; <span class="hljs-title">UpdateBookAsync</span>(<span class="hljs-params">Guid id, UpdateBookRequest book</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-comment">// Find the existing book by its ID</span>
                <span class="hljs-keyword">var</span> existingBook = <span class="hljs-keyword">await</span> _context.Books.FindAsync(id);
                <span class="hljs-keyword">if</span> (existingBook == <span class="hljs-literal">null</span>)
                {
                    _logger.LogWarning(<span class="hljs-string">$"Book with ID <span class="hljs-subst">{id}</span> not found."</span>);
                    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
                }

                <span class="hljs-comment">// Update the book details</span>
                existingBook.Title = book.Title;
                existingBook.Author = book.Author;
                existingBook.Description = book.Description;
                existingBook.Category = book.Category;
                existingBook.Language = book.Language;
                existingBook.TotalPages = book.TotalPages;

                <span class="hljs-comment">// Save the changes to the database</span>
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
                _logger.LogInformation(<span class="hljs-string">"Book updated successfully."</span>);

                <span class="hljs-comment">// Return the details of the updated book</span>
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> BookResponse
                {
                    Id = existingBook.Id,
                    Title = existingBook.Title,
                    Author = existingBook.Author,
                    Description = existingBook.Description,
                    Category = existingBook.Category,
                    Language = existingBook.Language,
                    TotalPages = existingBook.TotalPages
                };
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error updating book: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }
<span class="hljs-comment">//...</span>
</code></pre>
<p>Here, we are querying the database for the book with the specified ID, updating the book entity with the data from the <code>UpdateBookRequest</code> object, saving the updated book entity to the database, and returning the updated book entity as a <code>BookResponse</code> object. We are also logging information and errors using the <code>ILogger</code> dependency.</p>
<p>If the book with the specified ID is not found, we log a warning message and return null. If an exception occurs during the process, we log the error message and rethrow the exception.</p>
<p>Now that we have implemented the <code>UpdateBookAsync</code> method, let's implement the <code>DeleteBookAsync</code> method.</p>
<h3 id="heading-how-to-implement-the-deletebookasync-method">How to Implement the <code>DeleteBookAsync</code> Method</h3>
<p>The <code>DeleteBookAsync</code> method is used to delete an existing book from the database. In this method, we will query the database for the book with the specified ID, remove the book entity from the database, and return a boolean value indicating whether the book was successfully deleted.</p>
<p>Update the <code>DeleteBookAsync</code> method in the <code>BookService</code> class as follows:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/BookService.cs</span>

 <span class="hljs-comment">//...</span>


<span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Delete a book by its ID</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="id"&gt;</span>ID of the book to be deleted<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>True if the book was deleted, false otherwise<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">bool</span>&gt; <span class="hljs-title">DeleteBookAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-comment">// Find the book by its ID</span>
                <span class="hljs-keyword">var</span> book = <span class="hljs-keyword">await</span> _context.Books.FindAsync(id);
                <span class="hljs-keyword">if</span> (book == <span class="hljs-literal">null</span>)
                {
                    _logger.LogWarning(<span class="hljs-string">$"Book with ID <span class="hljs-subst">{id}</span> not found."</span>);
                    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
                }

                <span class="hljs-comment">// Remove the book from the database</span>
                _context.Books.Remove(book);
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
                _logger.LogInformation(<span class="hljs-string">$"Book with ID <span class="hljs-subst">{id}</span> deleted successfully."</span>);
                <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error deleting book: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }
<span class="hljs-comment">//...</span>
</code></pre>
<p>In this code, we are querying the database for the book with the specified ID, removing the book entity from the database, and returning a boolean value indicating whether the book was successfully deleted. We are also logging information and errors using the <code>ILogger</code> dependency.</p>
<p>If the book with the specified ID is not found, we log a warning message and return false. If an exception occurs during the process, we log the error message and rethrow the exception.</p>
<p>Now you have successfully implemented the business logic for the <code>AddBookAsync</code>, <code>GetBookByIdAsync</code>, <code>GetBooksAsync</code>, <code>UpdateBookAsync</code>, and <code>DeleteBookAsync</code> methods in the <code>BookService</code> class. These methods handle the CRUD operations for books, validate book data, and handle exceptions. By now, your <code>BookService</code> class should look like this:</p>
<pre><code class="lang-csharp">

<span class="hljs-keyword">using</span> bookapi_minimal.AppContext;
<span class="hljs-keyword">using</span> bookapi_minimal.Contracts;
<span class="hljs-keyword">using</span> bookapi_minimal.Interfaces;
<span class="hljs-keyword">using</span> bookapi_minimal.Models;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookService</span> : <span class="hljs-title">IBookService</span>
    {
          <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ApplicationContext _context; <span class="hljs-comment">// Database context</span>
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;BookService&gt; _logger; <span class="hljs-comment">// Logger for logging information and error</span>
          <span class="hljs-comment">// Constructor to initialize the database context and logger</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">BookService</span>(<span class="hljs-params">ApplicationContext context, ILogger&lt;BookService&gt; logger</span>)</span>
        {
            _context = context;
            _logger = logger;
        }

           <span class="hljs-comment"><span class="hljs-doctag">///</span> Add a new book</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="createBookRequest"&gt;</span>Book request to be added<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>Details of the created book<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;BookResponse&gt; <span class="hljs-title">AddBookAsync</span>(<span class="hljs-params">CreateBookRequest createBookRequest</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">var</span> book = <span class="hljs-keyword">new</span> BookModel
                {
                    Title = createBookRequest.Title,
                    Author = createBookRequest.Author,
                    Description = createBookRequest.Description,
                    Category = createBookRequest.Category,
                    Language = createBookRequest.Language,
                    TotalPages = createBookRequest.TotalPages
                };

                <span class="hljs-comment">// Add the book to the database</span>
                _context.Books.Add(book);
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
                _logger.LogInformation(<span class="hljs-string">"Book added successfully."</span>);

                <span class="hljs-comment">// Return the details of the created book</span>
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> BookResponse
                {
                    Id = book.Id,
                    Title = book.Title,
                    Author = book.Author,
                    Description = book.Description,
                    Category = book.Category,
                    Language = book.Language,
                    TotalPages = book.TotalPages
                };
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error adding book: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }

          <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Get a book by its ID</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="id"&gt;</span>ID of the book<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>Details of the book<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;BookResponse&gt;  <span class="hljs-title">GetBookByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-comment">// Find the book by its ID</span>
                <span class="hljs-keyword">var</span> book = <span class="hljs-keyword">await</span> _context.Books.FindAsync(id);
                <span class="hljs-keyword">if</span> (book == <span class="hljs-literal">null</span>)
                {
                    _logger.LogWarning(<span class="hljs-string">$"Book with ID <span class="hljs-subst">{id}</span> not found."</span>);
                    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
                }

                <span class="hljs-comment">// Return the details of the book</span>
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> BookResponse
                {
                    Id = book.Id,
                    Title = book.Title,
                    Author = book.Author,
                    Description = book.Description,
                    Category = book.Category,
                    Language = book.Language,
                    TotalPages = book.TotalPages
                };
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error retrieving book: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }



  <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Get all books</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>List of all books<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IEnumerable&lt;BookResponse&gt;&gt; GetBooksAsync()
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-comment">// Get all books from the database</span>
                <span class="hljs-keyword">var</span> books = <span class="hljs-keyword">await</span> _context.Books.ToListAsync();

                <span class="hljs-comment">// Return the details of all books</span>
                <span class="hljs-keyword">return</span> books.Select(book =&gt; <span class="hljs-keyword">new</span> BookResponse
                {
                    Id = book.Id,
                    Title = book.Title,
                    Author = book.Author,
                    Description = book.Description,
                    Category = book.Category,
                    Language = book.Language,
                    TotalPages = book.TotalPages
                });
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error retrieving books: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }


         <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Update an existing book</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="id"&gt;</span>ID of the book to be updated<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="book"&gt;</span>Updated book model<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>Details of the updated book<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;BookResponse&gt; <span class="hljs-title">UpdateBookAsync</span>(<span class="hljs-params">Guid id, UpdateBookRequest book</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-comment">// Find the existing book by its ID</span>
                <span class="hljs-keyword">var</span> existingBook = <span class="hljs-keyword">await</span> _context.Books.FindAsync(id);
                <span class="hljs-keyword">if</span> (existingBook == <span class="hljs-literal">null</span>)
                {
                    _logger.LogWarning(<span class="hljs-string">$"Book with ID <span class="hljs-subst">{id}</span> not found."</span>);
                    <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
                }

                <span class="hljs-comment">// Update the book details</span>
                existingBook.Title = book.Title;
                existingBook.Author = book.Author;
                existingBook.Description = book.Description;
                existingBook.Category = book.Category;
                existingBook.Language = book.Language;
                existingBook.TotalPages = book.TotalPages;

                <span class="hljs-comment">// Save the changes to the database</span>
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
                _logger.LogInformation(<span class="hljs-string">"Book updated successfully."</span>);

                <span class="hljs-comment">// Return the details of the updated book</span>
                <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> BookResponse
                {
                    Id = existingBook.Id,
                    Title = existingBook.Title,
                    Author = existingBook.Author,
                    Description = existingBook.Description,
                    Category = existingBook.Category,
                    Language = existingBook.Language,
                    TotalPages = existingBook.TotalPages
                };
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error updating book: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }



        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> Delete a book by its ID</span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;/summary&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;param name="id"&gt;</span>ID of the book to be deleted<span class="hljs-doctag">&lt;/param&gt;</span></span>
        <span class="hljs-comment"><span class="hljs-doctag">///</span> <span class="hljs-doctag">&lt;returns&gt;</span>True if the book was deleted, false otherwise<span class="hljs-doctag">&lt;/returns&gt;</span></span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;<span class="hljs-keyword">bool</span>&gt; <span class="hljs-title">DeleteBookAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-comment">// Find the book by its ID</span>
                <span class="hljs-keyword">var</span> book = <span class="hljs-keyword">await</span> _context.Books.FindAsync(id);
                <span class="hljs-keyword">if</span> (book == <span class="hljs-literal">null</span>)
                {
                    _logger.LogWarning(<span class="hljs-string">$"Book with ID <span class="hljs-subst">{id}</span> not found."</span>);
                    <span class="hljs-keyword">return</span> <span class="hljs-literal">false</span>;
                }

                <span class="hljs-comment">// Remove the book from the database</span>
                _context.Books.Remove(book);
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
                _logger.LogInformation(<span class="hljs-string">$"Book with ID <span class="hljs-subst">{id}</span> deleted successfully."</span>);
                <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(<span class="hljs-string">$"Error deleting book: <span class="hljs-subst">{ex.Message}</span>"</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }

    }
}
</code></pre>
<p>Congratulations! You have successfully implemented the business logic for the <code>AddBookAsync</code>, <code>GetBookByIdAsync</code>, <code>GetBooksAsync</code>, <code>UpdateBookAsync</code>, and <code>DeleteBookAsync</code> methods in the <code>BookService</code> class.</p>
<p>There's one thing we need to do: we need to register the service in our extension method. Let's go ahead and do that.</p>
<p>In your <code>ServiceExtensions.cs</code> file, add the following code:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Extensions/ServiceExtensions.cs</span>

<span class="hljs-comment">//..</span>

 builder.Services.AddScoped&lt;IBookService, BookService&gt;();
<span class="hljs-comment">//...</span>
</code></pre>
<p>This will register the <code>BookService</code> class as a scoped service. This means that the service will be created once per request and disposed of after the request is complete.</p>
<p>Now that we have the service working, let's go ahead and create the exception classes.</p>
<h2 id="heading-how-to-create-exceptions">How to Create Exceptions</h2>
<p>Properly handling exceptions is crucial for ensuring the stability and reliability of an application. In the context of ASP.NET Core, there are two main types of exceptions:</p>
<ul>
<li><p><strong>System Exceptions</strong>: These are exceptions thrown by the .NET runtime or the underlying system.</p>
</li>
<li><p><strong>Application Exceptions</strong>: These are exceptions thrown by the application code to handle specific errors or conditions.</p>
</li>
</ul>
<p>In ASP.NET Core with .NET 8, a new feature called global exception handling was introduced. This feature allows you to handle exceptions globally in your application, making it easier to manage errors and provide a consistent user experience.</p>
<p>In our application, we will create custom exception classes to handle specific errors and conditions. We’ll also leverage the global exception handling feature to manage exceptions globally, ensuring a uniform approach to error handling across the entire application.</p>
<p>We are going to create the following exception classes:</p>
<ul>
<li><p><code>NoBookFoundException</code>: Thrown when a book with the specified ID is not found.</p>
</li>
<li><p><code>BookDoesNotExistException</code>: Thrown when a book with the specified ID does not exist.</p>
</li>
<li><p><code>GlobalExceptionHandler</code>: Handles exceptions globally in the application.</p>
</li>
</ul>
<p>In the <code>Exceptions</code> folder, create a new file named <code>NoBookFoundException.cs</code> and add the following code:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Exceptions/NoBookFoundException.cs</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Exceptions</span>
{

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">NoBookFoundException</span> : <span class="hljs-title">Exception</span>
    {

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">NoBookFoundException</span>(<span class="hljs-params"></span>) : <span class="hljs-title">base</span>(<span class="hljs-params"><span class="hljs-string">"No books found"</span></span>)</span>
        {}
    }
}
</code></pre>
<p>In this code, we are creating a custom exception class named <code>NoBookFoundException</code> that inherits from the <code>Exception</code> class. The <code>NoBookFoundException</code> class is used to handle the scenario where no books are found in the database. We are also providing a custom error message for the exception.</p>
<p>In the <code>Exceptions</code> folder, create a new file named <code>BookDoesNotExistException.cs</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Exceptions</span>
{
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookDoesNotExistException</span> : <span class="hljs-title">Exception</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">BookDoesNotExistException</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> id</span>) : <span class="hljs-title">base</span>(<span class="hljs-params"><span class="hljs-string">$"Book with id <span class="hljs-subst">{id}</span> does not exist"</span></span>)</span>
        {
            <span class="hljs-keyword">this</span>.id = id;
        } 

    }
}
</code></pre>
<p>In this code, we are creating a custom exception class named <code>BookDoesNotExistException</code> that inherits from the <code>Exception</code> class. The <code>BookDoesNotExistException</code> class is used to handle the scenario where a book with the specified ID does not exist in the database. We are also providing a custom error message for the exception.</p>
<p>In the <code>Exceptions</code> folder, create a new file named <code>GlobalExceptionHandler.cs</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Exceptions/GlobalExceptionHandler.cs</span>

<span class="hljs-keyword">using</span> System.Net;
<span class="hljs-keyword">using</span> bookapi_minimal.Contracts;
<span class="hljs-keyword">using</span> Microsoft.AspNetCore.Diagnostics;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Exceptions</span>
{

   <span class="hljs-comment">// Global exception handler class implementing IExceptionHandler</span>
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">GlobalExceptionHandler</span> : <span class="hljs-title">IExceptionHandler</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;GlobalExceptionHandler&gt; _logger;

        <span class="hljs-comment">// Constructor to initialize the logger</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">GlobalExceptionHandler</span>(<span class="hljs-params">ILogger&lt;GlobalExceptionHandler&gt; logger</span>)</span>
        {
            _logger = logger;
        }

        <span class="hljs-comment">// Method to handle exceptions asynchronously</span>
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> ValueTask&lt;<span class="hljs-keyword">bool</span>&gt; <span class="hljs-title">TryHandleAsync</span>(<span class="hljs-params">
            HttpContext httpContext,
            Exception exception,
            CancellationToken cancellationToken</span>)</span>
        {
            <span class="hljs-comment">// Log the exception details</span>
            _logger.LogError(exception, <span class="hljs-string">"An error occurred while processing your request"</span>);

            <span class="hljs-keyword">var</span> errorResponse = <span class="hljs-keyword">new</span> ErrorResponse
            {
                Message = exception.Message,
                Title = exception.GetType().Name
            };

            <span class="hljs-comment">// Determine the status code based on the type of exception</span>
            <span class="hljs-keyword">switch</span> (exception)
            {
                <span class="hljs-keyword">case</span> BadHttpRequestException:
                    errorResponse.StatusCode = (<span class="hljs-keyword">int</span>)HttpStatusCode.BadRequest;
                    <span class="hljs-keyword">break</span>;

                <span class="hljs-keyword">case</span> NoBookFoundException:
                <span class="hljs-keyword">case</span> BookDoesNotExistException:
                    errorResponse.StatusCode = (<span class="hljs-keyword">int</span>)HttpStatusCode.NotFound;
                    <span class="hljs-keyword">break</span>;

                <span class="hljs-keyword">default</span>:
                    errorResponse.StatusCode = (<span class="hljs-keyword">int</span>)HttpStatusCode.InternalServerError;
                    <span class="hljs-keyword">break</span>;
            }

            <span class="hljs-comment">// Set the response status code</span>
            httpContext.Response.StatusCode = errorResponse.StatusCode;

            <span class="hljs-comment">// Write the error response as JSON</span>
            <span class="hljs-keyword">await</span> httpContext.Response.WriteAsJsonAsync(errorResponse, cancellationToken);

            <span class="hljs-comment">// Return true to indicate that the exception was handled</span>
            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }
    }
}
</code></pre>
<p>Let's break down the code above:</p>
<ul>
<li><p>We define a class named <code>GlobalExceptionHandler</code> that implements the <code>IExceptionHandler</code> interface. The <code>IExceptionHandler</code> interface is used to handle exceptions globally in the application.</p>
</li>
<li><p>The <code>GlobalExceptionHandler</code> class contains a constructor that initializes the <code>ILogger&lt;GlobalExceptionHandler&gt;</code> dependency. The <code>ILogger</code> is used for logging information and errors.</p>
</li>
<li><p>The <code>TryHandleAsync</code> method is used to handle exceptions asynchronously. This method accepts the <code>HttpContext</code>, <code>Exception</code>, and <code>CancellationToken</code> as parameters.</p>
</li>
<li><p>We log the exception details using the <code>ILogger</code> dependency.</p>
</li>
<li><p>We create an <code>ErrorResponse</code> object to represent the error response returned by the API. The <code>ErrorResponse</code> object contains the error message, title, and status code.</p>
</li>
<li><p>We determine the status code based on the type of exception. If the exception is a <code>BadHttpRequestException</code>, we set the status code to <code>BadRequest</code>. If the exception is a <code>NoBookFoundException</code> or <code>BookDoesNotExistException</code>, we set the status code to <code>NotFound</code>. Otherwise, we set the status code to <code>InternalServerError</code>.</p>
</li>
<li><p>We set the response status code using the <code>httpContext.Response.StatusCode</code> property.</p>
</li>
<li><p>We write the error response as JSON using the <code>httpContext.Response.WriteAsJsonAsync</code> method.</p>
</li>
<li><p>We return <code>true</code> to indicate that the exception was handled successfully.</p>
</li>
</ul>
<p>Now that we have created the exception classes, let's register the <code>GlobalExceptionHandler</code> in the dependency injection container. Since we created an Extension method for registering services in the dependency injection container, we will add the <code>GlobalExceptionHandler</code> to the <code>ServiceExtensions</code> class.</p>
<p>Update the <code>ServiceExtensions</code> class in the <code>Extensions</code> folder as follows:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Extensions/ServiceExtensions.cs</span>
<span class="hljs-comment">//...</span>
builder.Services.AddExceptionHandler&lt;GlobalExceptionHandler&gt;();

builder.Services.AddProblemDetails();

<span class="hljs-comment">//...</span>
</code></pre>
<p>The <code>AddExceptionHandler</code> method registers the <code>GlobalExceptionHandler</code> in the dependency injection container. The <code>AddProblemDetails</code> method registers the <code>ProblemDetails</code> class in the dependency injection container.</p>
<p>Now that we have registered the <code>GlobalExceptionHandler</code> in the dependency injection container, we can use it to handle exceptions globally in our application. In the next section, we will create the API endpoints to interact with the book data.</p>
<h2 id="heading-how-to-create-the-api-endpoints">How to Create the API Endpoints</h2>
<p>In the context of minimal APIs in ASP.NET Core, there are many ways to set up your endpoints.</p>
<p>You can define them directly in your <code>Program.cs</code> file. But as your project grows and you need to add more endpoints or functionality, it’s helpful to organize your code better. One way to achieve this is by creating a separate class to handle all the endpoints.</p>
<p>As we’ve discussed above, minimal APIs don’t use controllers or views like traditional ASP.NET Core applications. Instead, they use methods such as <code>MapGet</code>, <code>MapPost</code>, <code>MapPut</code>, and <code>MapDelete</code> to define HTTP methods and routes for API endpoints.</p>
<p>To get started, navigate to the <code>Endpoints</code> folder and create a new file named <code>BookEndpoints.cs</code>. Add the following code to the file:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Endpoints/BookEndpoints.cs</span>



<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Endpoints</span>
{
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookEndPoint</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> IEndpointRouteBuilder <span class="hljs-title">MapBookEndPoint</span>(<span class="hljs-params"><span class="hljs-keyword">this</span> IEndpointRouteBuilder app</span>)</span>
        {


            <span class="hljs-keyword">return</span> app;
        }
    }
}
</code></pre>
<p>The <code>BookEndpoints</code> class contains a <code>MapBookEndPoint</code> method that returns an <code>IEndpointRouteBuilder</code> object. The <code>IEndpointRouteBuilder</code> object is used to define the HTTP methods and routes for the API endpoints. In the next sections, we will define the API endpoints for <code>creating</code>, <code>reading</code>, <code>updating</code>, and <code>deleting</code> books.</p>
<h3 id="heading-how-to-create-the-addbookasync-books-endpoint">How to Create the <code>AddBookAsync</code> Books Endpoint</h3>
<p>In this section, we will create the <code>AddBookAsync</code> endpoint. This endpoint will accept a <code>Book</code> object as a JSON payload and add it to the database. We will use the <code>MapPost</code> method to define the HTTP method and route for this endpoint.</p>
<p>Add the following code to the <code>BookEndpoints</code> class:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Endpoints/BookEndpoints.cs</span>


<span class="hljs-comment">//...</span>
   <span class="hljs-comment">// Endpoint to add a new book</span>
      app.MapPost(<span class="hljs-string">"/books"</span>, <span class="hljs-keyword">async</span> (CreateBookRequest createBookRequest, IBookService bookService) =&gt;
        {
        <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.AddBookAsync(createBookRequest);
        <span class="hljs-keyword">return</span> Results.Created(<span class="hljs-string">$"/books/<span class="hljs-subst">{result.Id}</span>"</span>, result); 
        });


<span class="hljs-comment">//...</span>
</code></pre>
<ul>
<li><p><strong>Route Definition</strong>: The MapPost method defines the route for the endpoint as <code>/books</code>.</p>
</li>
<li><p><strong>Request Model</strong>: The endpoint accepts an <code>CreateBookRequest</code> object as a JSON payload. The <code>CreateBookRequest</code> object contains the data required to create a new book.</p>
</li>
<li><p><strong>Response Model</strong>: The endpoint returns a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data for the newly created book.</p>
</li>
<li><p><strong>Return Value</strong>: The endpoint returns a <code>Created</code> result. The <code>Created</code> result contains the location of the newly created book and the <code>Book</code> object.</p>
</li>
</ul>
<h3 id="heading-how-to-create-the-getbookasync-book-endpoint">How to Create the <code>GetBookAsync</code> Book Endpoint</h3>
<p>In this section, we will create the <code>GetBookAsync</code> endpoint. This endpoint will accept a book ID as a query parameter and return the book with the specified ID. We will use the <code>MapGet</code> method to define the HTTP method and route for this endpoint.</p>
<p>Add the following code to the <code>BookEndpoints</code> class:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Endpoints/BookEndpoints.cs</span>

<span class="hljs-comment">// ...</span>
    <span class="hljs-comment">// Endpoint to get all books</span>
    app.MapGet(<span class="hljs-string">"/books"</span>, <span class="hljs-keyword">async</span> (IBookService bookService) =&gt;
     {
    <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.GetBooksAsync();
    <span class="hljs-keyword">return</span> Results.Ok(result);
});


<span class="hljs-comment">//...</span>
</code></pre>
<ul>
<li><p><strong>Route Definition</strong>: The MapGet method defines the route for the endpoint as <code>/books</code>.</p>
</li>
<li><p><strong>Request Model</strong>: The endpoint accepts a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data required to create a new book.</p>
</li>
<li><p><strong>Response Model</strong>: The endpoint returns a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data for the newly created book.</p>
</li>
<li><p><strong>Return Value</strong>: The endpoint returns an <code>Ok</code> result. The <code>Ok</code> result contains the <code>Book</code> object.</p>
</li>
</ul>
<h3 id="heading-how-to-create-the-getbookbyidasync-book-endpoint">How to Create the <code>GetBookByIdAsync</code> Book Endpoint</h3>
<p>In this section, we will create the <code>GetBookByIdAsync</code> endpoint. This endpoint will accept a book ID as a route parameter and return the book with the specified ID. We will use the <code>MapGet</code> method to define the HTTP method and route for this endpoint.</p>
<p>Add the following code to the <code>BookEndpoints</code> class:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Endpoints/BookEndpoints.cs</span>
<span class="hljs-comment">//...</span>
<span class="hljs-comment">// Endpoint to get a book by ID</span>

  app.MapGet(<span class="hljs-string">"/books/{id:guid}"</span>, <span class="hljs-keyword">async</span> (Guid id, IBookService bookService) =&gt;
  {
    <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.GetBookByIdAsync(id);
    <span class="hljs-keyword">return</span> result != <span class="hljs-literal">null</span> ? Results.Ok(result) : Results.NotFound();
});

<span class="hljs-comment">//...</span>
</code></pre>
<ul>
<li><p><strong>Route Definition</strong>: The MapGet method defines the route for the endpoint as <code>/books/{id:guid}</code>. The <code>{id:guid}</code> parameter specifies that the <code>id</code> parameter should be a GUID.</p>
</li>
<li><p><strong>Request Model</strong>: The endpoint accepts a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data required to create a new book.</p>
</li>
<li><p><strong>Response Model</strong>: The endpoint returns a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data for the newly created book.</p>
</li>
<li><p><strong>Return Value</strong>: The endpoint returns an <code>Ok</code> result if the book is found. The <code>NotFound</code> result is returned if the book is not found.</p>
</li>
</ul>
<h3 id="heading-how-to-create-the-updatebookasync-book-endpoint">How to Create the <code>UpdateBookAsync</code> Book Endpoint</h3>
<p>In this section, we will create the <code>UpdateBookAsync</code> endpoint. This endpoint will accept a book ID as a route parameter and an <code>Book</code> object as a JSON payload and update the book with the specified ID. We will use the <code>MapPut</code> method to define the HTTP method and route for this endpoint.</p>
<p>Add the following code to the <code>BookEndpoints</code> class:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Endpoints/BookEndpoints.cs</span>

<span class="hljs-comment">//...</span>
   <span class="hljs-comment">// Endpoint to update a book by ID</span>
    app.MapPut(<span class="hljs-string">"/books/{id:guid}"</span>, <span class="hljs-keyword">async</span> (Guid id, UpdateBookRequest updateBookRequest, IBookService bookService) =&gt;
 {
<span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.UpdateBookAsync(id, updateBookRequest);
<span class="hljs-keyword">return</span> result != <span class="hljs-literal">null</span> ? Results.Ok(result) : Results.NotFound();
});

<span class="hljs-comment">//...</span>
</code></pre>
<ul>
<li><p><strong>Route Definition</strong>: The MapPut method defines the route for the endpoint as <code>/books/{id:guid}</code>. The <code>{id:guid}</code> parameter specifies that the <code>id</code> parameter should be a GUID.</p>
</li>
<li><p><strong>Request Model</strong>: The endpoint accepts a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data required to create a new book.</p>
</li>
<li><p><strong>Response Model</strong>: The endpoint returns a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data for the newly created book.</p>
</li>
<li><p><strong>Return Value</strong>: The endpoint returns an <code>Ok</code> result if the book is found. The <code>NotFound</code> result is returned if the book is not found.</p>
</li>
</ul>
<h3 id="heading-how-to-create-the-deletebookasync-book-endpoint">How to Create the <code>DeleteBookAsync</code> Book Endpoint</h3>
<p>In this section, we will create the <code>DeleteBookAsync</code> endpoint. This endpoint will accept a book ID as a route parameter and delete the book with the specified ID. We will use the <code>MapDelete</code> method to define the HTTP method and route for this endpoint.</p>
<p>Add the following code to the <code>BookEndpoints</code> class:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Endpoints/BookEndpoints.cs</span>

<span class="hljs-comment">//...</span>
   <span class="hljs-comment">// Endpoint to delete a book by ID</span>
 app.MapDelete(<span class="hljs-string">"/books/{id:guid}"</span>, <span class="hljs-keyword">async</span> (Guid id, IBookService bookService) =&gt;
{
<span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.DeleteBookAsync(id);
   <span class="hljs-keyword">return</span> result ? Results.NoContent() : Results.NotFound();
});


<span class="hljs-comment">//...</span>
</code></pre>
<ul>
<li><p><strong>Route Definition</strong>: The MapDelete method defines the route for the endpoint as <code>/books/{id:guid}</code>. The <code>{id:guid}</code> parameter specifies that the <code>id</code> parameter should be a GUID.</p>
</li>
<li><p><strong>Request Model</strong>: The endpoint accepts a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data required to create a new book.</p>
</li>
<li><p><strong>Response Model</strong>: The endpoint returns a <code>Book</code> object as a JSON payload. The <code>Book</code> object contains the data for the newly created book.</p>
</li>
<li><p><strong>Return Value</strong>: The endpoint returns a <code>NoContent</code> result if the book is deleted successfully. The <code>NotFound</code> result is returned if the book is not found.</p>
</li>
</ul>
<p>Now we have defined all the methods for the book endpoints. So your endpoint class should look like this:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Endpoints/BookEndpoints.cs</span>
<span class="hljs-keyword">using</span> bookapi_minimal.Contracts;
<span class="hljs-keyword">using</span> bookapi_minimal.Interfaces;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Endpoints</span>
{
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookEndPoint</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> IEndpointRouteBuilder <span class="hljs-title">MapBookEndPoint</span>(<span class="hljs-params"><span class="hljs-keyword">this</span> IEndpointRouteBuilder app</span>)</span>
        {
            <span class="hljs-comment">// Define the endpoints</span>

            <span class="hljs-comment">// Endpoint to add a new book</span>
            app.MapPost(<span class="hljs-string">"/books"</span>, <span class="hljs-keyword">async</span> (CreateBookRequest createBookRequest, IBookService bookService) =&gt;
            {
                <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.AddBookAsync(createBookRequest);
                <span class="hljs-keyword">return</span> Results.Created(<span class="hljs-string">$"/books/<span class="hljs-subst">{result.Id}</span>"</span>, result); 
            });


               <span class="hljs-comment">// Endpoint to get all books</span>
            app.MapGet(<span class="hljs-string">"/books"</span>, <span class="hljs-keyword">async</span> (IBookService bookService) =&gt;
            {
                <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.GetBooksAsync();
                <span class="hljs-keyword">return</span> Results.Ok(result);
            });

            <span class="hljs-comment">// Endpoint to get a book by ID</span>
            app.MapGet(<span class="hljs-string">"/books/{id:guid}"</span>, <span class="hljs-keyword">async</span> (Guid id, IBookService bookService) =&gt;
            {
                <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.GetBookByIdAsync(id);
                <span class="hljs-keyword">return</span> result != <span class="hljs-literal">null</span> ? Results.Ok(result) : Results.NotFound();
            });


            <span class="hljs-comment">// Endpoint to update a book by ID</span>
            app.MapPut(<span class="hljs-string">"/books/{id:guid}"</span>, <span class="hljs-keyword">async</span> (Guid id, UpdateBookRequest updateBookRequest, IBookService bookService) =&gt;
            {
                <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.UpdateBookAsync(id, updateBookRequest);
                <span class="hljs-keyword">return</span> result != <span class="hljs-literal">null</span> ? Results.Ok(result) : Results.NotFound();
            });

            <span class="hljs-comment">// Endpoint to delete a book by ID</span>
            app.MapDelete(<span class="hljs-string">"/books/{id:guid}"</span>, <span class="hljs-keyword">async</span> (Guid id, IBookService bookService) =&gt;
            {
                <span class="hljs-keyword">var</span> result = <span class="hljs-keyword">await</span> bookService.DeleteBookAsync(id);
                <span class="hljs-keyword">return</span> result ? Results.NoContent() : Results.NotFound();
            });

            <span class="hljs-keyword">return</span> app;
        }
    }
}
</code></pre>
<p>Congratulations! You have created all the endpoints for the book API. The endpoints handle the CRUD operations for books and return the appropriate responses based on the request and data.</p>
<h3 id="heading-how-to-register-the-endpoints">How to Register the Endpoints</h3>
<p>After defining the API endpoints for the book API, the next step is to register these endpoints in the <code>Program.cs</code> file. We will use the <code>MapBookEndpoints</code> method to register the book endpoints.</p>
<p>We should also clean up our <code>Program.cs</code> class to ensure it remains organized and maintainable.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Program.cs</span>

<span class="hljs-keyword">using</span> System.Reflection;
<span class="hljs-keyword">using</span> bookapi_minimal.Endpoints;
<span class="hljs-keyword">using</span> bookapi_minimal.Services;
<span class="hljs-keyword">using</span> Microsoft.OpenApi.Models;

<span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);


builder.AddApplicationServices();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen(c=&gt;
{
    c.SwaggerDoc(<span class="hljs-string">"v1"</span>, <span class="hljs-keyword">new</span> OpenApiInfo { Title = <span class="hljs-string">"Mimal API"</span>, Version = <span class="hljs-string">"v1"</span>, Description = <span class="hljs-string">"Showing how you can build minimal "</span> +
        <span class="hljs-string">"api with .net"</span> });


    <span class="hljs-comment">// Set the comments path for the Swagger JSON and UI.</span>
    <span class="hljs-keyword">var</span> xmlFile = <span class="hljs-string">$"<span class="hljs-subst">{Assembly.GetExecutingAssembly().GetName().Name}</span>.xml"</span>;
    <span class="hljs-keyword">var</span> xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);
    c.IncludeXmlComments(xmlPath);

});
<span class="hljs-keyword">var</span> app = builder.Build();

<span class="hljs-comment">// Configure the HTTP request pipeline.</span>
<span class="hljs-keyword">if</span> (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseExceptionHandler();


app.MapGroup(<span class="hljs-string">"/api/v1/"</span>)
   .WithTags(<span class="hljs-string">" Book endpoints"</span>)
   .MapBookEndPoint();

app.Run();
</code></pre>
<p>Let's break down the key components of the <code>Program.cs</code> file:</p>
<ul>
<li><p><strong>AddApplicationServices</strong>: This method registers the necessary services for the API. It is an extension method we created earlier to add services to the dependency injection container.</p>
</li>
<li><p><strong>AddSwaggerGen</strong>: This method registers the Swagger generator, which is used to create the Swagger documentation for the API. We specify the title, version, and description of the API in the Swagger document.</p>
</li>
<li><p><strong>MapGroup</strong>: This method groups the endpoints. It takes a path as a parameter and returns an <code>IEndpointRouteBuilder</code> object. We use the <code>WithTags</code> method to add tags to the endpoints and the <code>MapBookEndpoints</code> method to register the book endpoints.</p>
</li>
<li><p><strong>Run</strong>: This method starts the application.</p>
</li>
</ul>
<p>To enable Swagger documentation, you need to add the <code>GenerateDocumentationFile</code> property to your <code>.csproj</code> file. In this example, the file is named <code>bookapi-minimal.csproj</code>, but the name may vary based on your project.</p>
<p>Add the following line to your <code>.csproj</code> file:</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">GenerateDocumentationFile</span>&gt;</span>true<span class="hljs-tag">&lt;/<span class="hljs-name">GenerateDocumentationFile</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>
</code></pre>
<p>By the end, bookapi-minimal.csproj should look like this:</p>
<pre><code class="lang-xml">
<span class="hljs-tag">&lt;<span class="hljs-name">Project</span> <span class="hljs-attr">Sdk</span>=<span class="hljs-string">"Microsoft.NET.Sdk.Web"</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">TargetFramework</span>&gt;</span>net8.0<span class="hljs-tag">&lt;/<span class="hljs-name">TargetFramework</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Nullable</span>&gt;</span>enable<span class="hljs-tag">&lt;/<span class="hljs-name">Nullable</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ImplicitUsings</span>&gt;</span>enable<span class="hljs-tag">&lt;/<span class="hljs-name">ImplicitUsings</span>&gt;</span>
     <span class="hljs-tag">&lt;<span class="hljs-name">GenerateDocumentationFile</span>&gt;</span>true<span class="hljs-tag">&lt;/<span class="hljs-name">GenerateDocumentationFile</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">RootNamespace</span>&gt;</span>bookapi_minimal<span class="hljs-tag">&lt;/<span class="hljs-name">RootNamespace</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
   <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"FluentValidation.DependencyInjectionExtensions"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"11.9.2"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.OpenApi"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.6"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.Design"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.8"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">IncludeAssets</span>&gt;</span>runtime; build; native; contentfiles; analyzers; buildtransitive<span class="hljs-tag">&lt;/<span class="hljs-name">IncludeAssets</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PrivateAssets</span>&gt;</span>all<span class="hljs-tag">&lt;/<span class="hljs-name">PrivateAssets</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">PackageReference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.SqlServer"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.8"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.Tools"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.8"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">IncludeAssets</span>&gt;</span>runtime; build; native; contentfiles; analyzers; buildtransitive<span class="hljs-tag">&lt;/<span class="hljs-name">IncludeAssets</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PrivateAssets</span>&gt;</span>all<span class="hljs-tag">&lt;/<span class="hljs-name">PrivateAssets</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">PackageReference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Swashbuckle.AspNetCore"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"6.4.0"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">Project</span>&gt;</span>
</code></pre>
<p>Now that we have registered the book endpoints in the <code>Program.cs</code> file, we can run the application and test the API endpoints using Swagger.</p>
<p>When you run the application, you should see the Swagger documentation at the following URL: <a target="_blank" href="https://localhost:5001/swagger/index.html"><code>https://localhost:5001/swagger/index.html</code></a>. The Swagger documentation provides information about the API endpoints, request and response models, and allows you to test the endpoints directly from the browser. You should see something like this:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732624213627/e1e3b3d1-2ecb-486a-b95b-28b958f52462.png" alt="Book API Endpoints Swagger UI " width="2474" height="1242" loading="lazy"></p>
<p>Congratulations! You have implemented the business logic for the book service, created custom exceptions, defined API endpoints, and registered the endpoints in the <code>Program.cs</code> file. You have also enabled Swagger documentation to test the API endpoints.</p>
<h2 id="heading-how-to-add-seed-data-to-the-database">How to Add Seed Data to the Database</h2>
<p>One more important step is to seed the database with initial data when the application starts. This seed data will populate the database, allowing you to test your API endpoints without manually adding data.</p>
<p>Let's add some seed data before performing migrations and testing our API endpoints.</p>
<p>To achieve this, we will create a new class in our Configuration folder called <code>BookTypeConfigurations</code> and add the following code:</p>
<pre><code class="lang-csharp">

<span class="hljs-keyword">using</span> bookapi_minimal.Models;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore.Metadata.Builders;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">bookapi_minimal.Configurations</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BookTypeConfigurations</span> : <span class="hljs-title">IEntityTypeConfiguration</span>&lt;<span class="hljs-title">BookModel</span>&gt;
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Configure</span>(<span class="hljs-params">EntityTypeBuilder&lt;BookModel&gt; builder</span>)</span>
        {
            <span class="hljs-comment">// Configure the table name</span>
            builder.ToTable(<span class="hljs-string">"Books"</span>);

            <span class="hljs-comment">// Configure the primary key</span>
            builder.HasKey(x =&gt; x.Id);

            <span class="hljs-comment">// Configure properties</span>
            builder.Property(x =&gt; x.Id).ValueGeneratedOnAdd();
            builder.Property(x =&gt; x.Title).IsRequired().HasMaxLength(<span class="hljs-number">100</span>);
            builder.Property(x =&gt; x.Author).IsRequired().HasMaxLength(<span class="hljs-number">100</span>);
            builder.Property(x =&gt; x.Description).IsRequired().HasMaxLength(<span class="hljs-number">500</span>);
            builder.Property(x =&gt; x.Category).IsRequired().HasMaxLength(<span class="hljs-number">100</span>);
            builder.Property(x =&gt; x.Language).IsRequired().HasMaxLength(<span class="hljs-number">50</span>);
            builder.Property(x =&gt; x.TotalPages).IsRequired();

            <span class="hljs-comment">// Seed data</span>
            builder.HasData(
                <span class="hljs-keyword">new</span> BookModel
                {
                    Id = Guid.NewGuid(),
                    Title = <span class="hljs-string">"The Alchemist"</span>,
                    Author = <span class="hljs-string">"Paulo Coelho"</span>,
                    Description = <span class="hljs-string">"The Alchemist follows the journey of an Andalusian shepherd"</span>,
                    Category = <span class="hljs-string">"Fiction"</span>,
                    Language = <span class="hljs-string">"English"</span>,
                    TotalPages = <span class="hljs-number">208</span>
                },
                <span class="hljs-keyword">new</span> BookModel
                {
                    Id = Guid.NewGuid(),
                    Title = <span class="hljs-string">"To Kill a Mockingbird"</span>,
                    Author = <span class="hljs-string">"Harper Lee"</span>,
                    Description = <span class="hljs-string">"A novel about the serious issues of rape and racial inequality."</span>,
                    Category = <span class="hljs-string">"Fiction"</span>,
                    Language = <span class="hljs-string">"English"</span>,
                    TotalPages = <span class="hljs-number">281</span>
                },
                <span class="hljs-keyword">new</span> BookModel
                {
                    Id = Guid.NewGuid(),
                    Title = <span class="hljs-string">"1984"</span>,
                    Author = <span class="hljs-string">"George Orwell"</span>,
                    Description = <span class="hljs-string">"A dystopian social science fiction novel and cautionary tale about the dangers of totalitarianism. "</span>,
                  Category = <span class="hljs-string">"Fiction"</span>,
                  Language = <span class="hljs-string">"English"</span>,
                  TotalPages = <span class="hljs-number">328</span>
                } 
            );
        }
    }
}
</code></pre>
<p>Let's break down the code above:</p>
<p>In Entity Framework Core, you can use the <code>IEntityTypeConfiguration</code> interface to configure the entity type and seed data for the database. The <code>BookTypeConfigurations</code> class implements the <code>IEntityTypeConfiguration&lt;BookModel&gt;</code> interface and provides the configuration for the <code>BookModel</code> entity.</p>
<ul>
<li><p><strong>Configure Method</strong>: This method is used to configure the <code>BookModel</code> entity type. It defines the table name, primary key, and properties for the <code>BookModel</code> entity.</p>
<ul>
<li><p><strong>Table Name</strong>: The <code>ToTable</code> method specifies the name of the table to be created in the database. In this case, the table name is set to "Books".</p>
</li>
<li><p><strong>Primary Key</strong>: The <code>HasKey</code> method specifies the primary key for the <code>BookModel</code> entity. The primary key is set to the <code>Id</code> property.</p>
</li>
<li><p><strong>Properties</strong>: The <code>Property</code> method configures the properties of the <code>BookModel</code> entity. It specifies the data type, length, and constraints for each property.</p>
</li>
</ul>
</li>
<li><p><strong>Seed Data</strong>: The <code>HasData</code> method seeds the database with initial data. It creates three <code>BookModel</code> objects with sample data for testing the API endpoints.</p>
</li>
</ul>
<p>Now that we have created the <code>BookTypeConfigurations</code> class, we need to register this configuration in the <code>ApplicationContext</code> class. This ensures that the configuration is applied when the database is created or migrated.</p>
<p>We’re finally almost ready to test our API. But before we do that, we need to perform migrations to create the database and apply the seed data.</p>
<p>Remember that we added our database connection string in the <code>appsettings.json</code> file? Now let's perform a migration and later update our database for the migration to take effect.</p>
<h2 id="heading-how-to-perform-a-migration">How to Perform a Migration</h2>
<p>Migrations allow you to update the database schema based on changes made to your model classes. In Entity Framework Core, you can use the <code>dotnet ef migrations add</code> command to create a new migration reflecting these changes.</p>
<p>To perform a migration, run the following command in the terminal:</p>
<pre><code class="lang-bash">dotnet ef migrations add InitialCreate
</code></pre>
<p>If the command is successful, you should see an output similar to this:</p>
<pre><code class="lang-bash">Build started...
Build succeeded.
Done. To undo this action, use <span class="hljs-string">'ef migrations remove'</span>
</code></pre>
<p>You will now see a new folder called <code>Migrations</code> in your project. This folder contains the migration files that were created based on the changes made to your model classes. These migration files include the SQL commands required to update the database schema.</p>
<h3 id="heading-how-to-update-the-database">How to Update the Database</h3>
<p>After creating the migration, you need to apply the migration to update the database schema. You can use the <code>dotnet ef database update</code> command to apply the migration and update the database. Make sure the SQL Server is running.</p>
<p>Run the following command in the terminal:</p>
<pre><code class="lang-bash">
dotnet ef database update
</code></pre>
<p>This will update the database schema based on the changes made to your model classes. Make sure there are no errors on your database connection string.</p>
<h2 id="heading-how-to-test-the-api-endpoints">How to Test the API Endpoints</h2>
<p>Now we can test our endpoints using Swagger. To do this, run the application by executing the following command in the terminal:</p>
<pre><code class="lang-bash">
dotnet run
</code></pre>
<p>This will run our application. You can open your browser and navigate to <a target="_blank" href="https://localhost:5001/swagger/index.html"><code>https://localhost:5001/swagger/index.html</code></a> to access the Swagger documentation. You should see a list of API endpoints, request and response models, and the ability to test the endpoints directly from the browser.</p>
<p>If your port number is different from <code>5001</code>, don't worry – it will still work. The port might change depending on the type of machine you're using, but it will still achieve the same result.</p>
<h3 id="heading-how-to-test-the-get-all-books-endpoint">How to Test the <code>Get All Books</code> Endpoint</h3>
<p>To test the <code>Get All Books</code> endpoint, follow these steps:</p>
<ol>
<li><p>In the Swagger documentation, click on the <code>GET /api/v1/books</code> endpoint.</p>
</li>
<li><p>Click the <code>Try it out</code> button.</p>
</li>
<li><p>Click the <code>Execute</code> button.</p>
</li>
</ol>
<p>This will send a request to the API to retrieve all the books in the database.</p>
<p>You should see the response from the API, which will include the list of books that were seeded in the database.</p>
<p>The image below shows the response from the API:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732624950148/b497bc8e-727a-43c9-910f-755b3b6f208b.png" alt="Get All Books Endpoint Swagger UI " width="2391" height="1277" loading="lazy"></p>
<h3 id="heading-how-to-test-the-get-book-by-id-endpoint">How to Test the <code>Get Book by ID</code> Endpoint</h3>
<p>To test the <code>Get Book by ID</code> endpoint, follow these steps:</p>
<ol>
<li><p>In the Swagger documentation, click on the <code>GET /api/v1/books/{id}</code> endpoint.</p>
</li>
<li><p>Enter the ID of a book in the <code>id</code> field. You can use one of the book IDs that was seeded in the database.</p>
</li>
<li><p>Click the <code>Try it out</code> button.</p>
</li>
</ol>
<p>This will send a request to the API to retrieve the book with the specified ID. You should see the response from the API, which will include the book with the specified ID.</p>
<p>The image below shows the response from the API:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732625042363/fe356453-afa6-4a78-b963-d0befff7bd63.png" alt="Get Book By ID Endpoint Swagger UI " width="2342" height="1282" loading="lazy"></p>
<h3 id="heading-how-to-test-the-add-book-endpoint">How to Test the <code>Add Book</code> Endpoint</h3>
<p>To test the <code>Add Book</code> endpoint, follow these steps:</p>
<ol>
<li><p>In the Swagger documentation, click on the <code>POST /api/v1/books</code> endpoint.</p>
</li>
<li><p>Click the <code>Try it out</code> button.</p>
</li>
<li><p>Enter the book details in the request body.</p>
</li>
<li><p>Click the <code>Execute</code> button.</p>
</li>
</ol>
<p>This will send a request to the API to add a new book to the database.</p>
<p>You should see the response from the API, which will include the newly created book.</p>
<p>The image below shows the response from the API:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732625138350/faa54e57-e560-49ac-976a-b074e8eebb13.png" alt="Add Book Endpoint Swagger UI " width="2322" height="1292" loading="lazy"></p>
<h3 id="heading-how-to-test-the-update-book-endpoint">How to Test the <code>Update Book</code> Endpoint</h3>
<p>To test the <code>Update Book</code> endpoint, follow these steps:</p>
<ol>
<li><p>In the Swagger documentation, click on the <code>PUT /api/v1/books/{id}</code> endpoint.</p>
</li>
<li><p>Enter the ID of a book in the <code>id</code> field. You can use the id of one of the books that we just added.</p>
</li>
<li><p>Click the <code>Try it out</code> button.</p>
</li>
</ol>
<p>This will send a request to the API to update the book with the specified ID.</p>
<p>You should see the response from the API, which will include the updated book.</p>
<p>The image below shows the response from the API:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732625300781/3de90d6c-92ca-40cb-a54e-2236ec921d86.png" alt="Update Book Endpoint Swagger UI " width="2326" height="1311" loading="lazy"></p>
<h3 id="heading-how-to-test-the-delete-book-endpoint">How to Test the <code>Delete Book</code> Endpoint</h3>
<p>To test the <code>Delete Book</code> endpoint, follow these steps:</p>
<ol>
<li><p>In the Swagger documentation, click on the <code>DELETE /api/v1/books/{id}</code> endpoint.</p>
</li>
<li><p>Enter the ID of a book in the <code>id</code> field. You can use any of the ids from the books that we just added or the seeded data.</p>
</li>
<li><p>Click the <code>Try it out</code> button.</p>
</li>
</ol>
<p>This will send a request to the API to delete the book with the specified ID.</p>
<p>The image below shows the response from the API:</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1732625225432/3b066f4c-2bf2-4f0c-a104-a94dbbad1706.png" alt="Delete Book Endpoint Swagger UI " width="2327" height="1270" loading="lazy"></p>
<p>Congratulations! You have implemented all the CRUD operations for books and tested the API endpoints using Swagger, verifying that they work as expected. You can now build on this foundation to add more features and functionality to your API.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>This handbook explored how to create a minimal API in ASP.NET Core with .NET 8. We built a comprehensive book API that supports CRUD operations, implemented custom exceptions, defined and registered API endpoints, and enabled Swagger documentation for easy testing.</p>
<p>Following this tutorial, you have gained a solid foundation for building minimal APIs with ASP.NET Core. You can now apply this knowledge and create robust APIs for various domains and industries.</p>
<p>I hope you found this tutorial both helpful and informative. Thank you for reading!</p>
<p>Feel free to connect with me on social media:</p>
<ul>
<li><p><a target="_blank" href="https://x.com/Clifftech_Dev">Twitter</a></p>
</li>
<li><p><a target="_blank" href="https://www.linkedin.com/in/isaiah-clifford-opoku/">LinkedIn</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/Clifftech123">GitHub</a></p>
</li>
</ul>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ Learn TypeScript – A Comprehensive Guide for Beginners ]]>
                </title>
                <description>
                    <![CDATA[ TypeScript has become an industry standard for building large-scale applications, with many organizations choosing it as their primary language for application development. This tutorial will serve as your introductory guide to TypeScript. It's desig... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/typescript-for-beginners-guide/</link>
                <guid isPermaLink="false">66bb57043c5ab240beb8cd97</guid>
                
                    <category>
                        <![CDATA[ beginners guide ]]>
                    </category>
                
                    <category>
                        <![CDATA[ JavaScript ]]>
                    </category>
                
                    <category>
                        <![CDATA[ TypeScript ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Thu, 08 Aug 2024 16:45:28 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/08/Attractive.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>TypeScript has become an industry standard for building large-scale applications, with many organizations choosing it as their primary language for application development.</p>
<p>This tutorial will serve as your introductory guide to TypeScript. It's designed to cater to learners at all stages – from beginners to advanced users. It teaches both fundamental and advanced TypeScript concepts, making it a helpful resource for anyone looking to delve into TypeScript.</p>
<p>The aim of this guide is not to be an exhaustive resource, but rather a concise and handy reference. It distills the essence of TypeScript into a digestible format.</p>
<p>Whether you're a novice just starting out, an intermediate learner aiming to consolidate your knowledge, or an advanced user in need of a quick refresher, this guide is crafted to meet your TypeScript learning requirements.</p>
<p>After carefully reading through this tutorial and practicing the examples it contains, you should have the skills to build robust, scalable, and maintainable TypeScript applications. We'll cover key TypeScript concepts like types, functions, classes, interfaces, generics, and more.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><p><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-who-is-this-guide-for">Who is this guide for?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-typescript-vs-javascript">TypeScript vs. JavaScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-advantages-of-typescript">Advantages of TypeScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-code-generation">Code Generation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-installation">Installation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-configuration">Configuration</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-understanding-tsconfig-json">Understanding tsconfig.json</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-typescript-basics">TypeScript Basics</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-type-declarations-and-variables-in-typescript">Type Declarations and Variables in TypeScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-functions-in-typescript">Functions in TypeScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-classes-and-objects-in-typescript">Classes and Objects in TypeScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-interfaces-in-typescript">Interfaces in TypeScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-enums-in-typescript">Enums in TypeScript</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-generics-in-typescript">Generics in TypeScript</a></p>
</li>
</ul>
<h2 id="heading-prerequisites">Prerequisites</h2>
<p>Before you begin going through this guide, you should have a basic understanding of JavaScript. Familiarity with object-oriented programming concepts like classes, interfaces, and inheritance is also recommended.</p>
<p>But if you're new to these concepts, don't worry - we'll cover them in detail in this guide.</p>
<h2 id="heading-who-is-this-guide-for">Who is this Guide For?</h2>
<p>This guide is for anyone looking to learn TypeScript. Whether you're a beginner, an intermediate learner, or an advanced user, this guide is designed to meet your TypeScript learning needs.</p>
<p>It's also a handy reference for anyone looking to brush up on their TypeScript skills.</p>
<h2 id="heading-typescript-vs-javascript">TypeScript vs JavaScript</h2>
<p>TypeScript is a statically-typed superset of JavaScript, designed to enhance the development of large-scale applications.</p>
<p>It introduces optional <code>static typing</code>, <code>classes</code>, and <code>interfaces</code> to <code>JavaScript</code>, drawing parallels with languages like <code>C#</code> and <code>Java</code>. TypeScript code is transpiled to plain JavaScript, ensuring compatibility across various JavaScript environments.</p>
<p>While TypeScript and JavaScript can operate in the same environment, they exhibit key differences. The main one is that TypeScript is statically typed, providing type safety, while JavaScript is dynamically typed.</p>
<p>Let's delve into some of these differences:</p>
<p>TypeScript code is written in <code>.ts</code> or <code>.tsx</code> files, whereas JavaScript code resides in <code>.js</code> or <code>.jsx</code> files. The <code>.tsx</code> and <code>.jsx</code> extensions indicate that the file may contain JSX syntax, a popular choice for UI development in libraries like React.</p>
<p>Let's explore the differences between JavaScript and TypeScript through an example:</p>
<pre><code class="lang-js"><span class="hljs-comment">// JavaScript</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a, b</span>) </span>{
  <span class="hljs-keyword">return</span> a + b;
}

<span class="hljs-comment">// Calling the function</span>
add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>); <span class="hljs-comment">// Returns: 3</span>
</code></pre>
<p>In the JavaScript example above, the <code>add</code> function takes two parameters, <code>a</code> and <code>b</code>, and returns their sum. The function is invoked with the arguments <code>1</code> and <code>2</code>, yielding <code>3</code>. Notice that the function parameters are not annotated with types, which is typical in JavaScript.</p>
<p>Now, let's see how we can write the same function in TypeScript:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// TypeScript</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">return</span> a + b;
}

<span class="hljs-comment">// Calling the function</span>
add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>); <span class="hljs-comment">// Returns: 3</span>
</code></pre>
<p>In the TypeScript version, we've annotated the parameters <code>a</code> and <code>b</code> with the <code>number</code> type. We've also specified that the function returns a <code>number</code>.</p>
<p>This is a key difference between JavaScript and TypeScript. TypeScript enforces type safety, meaning it checks the types of values at compile time and throws errors if they don't match the expected types.</p>
<p>This feature helps catch errors early in the development process, making TypeScript a popular choice for large-scale applications.</p>
<p>TypeScript and JavaScript are both powerful languages used in a wide range of applications. Let's summarize their key differences:</p>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Feature</td><td>TypeScript</td><td>JavaScript</td></tr>
</thead>
<tbody>
<tr>
<td>Type System</td><td>Statically typed (types are checked at compile-time)</td><td>Dynamically typed (types are checked at run-time)</td></tr>
<tr>
<td>Superset</td><td>Yes, TypeScript is a superset of JavaScript</td><td>N/A</td></tr>
<tr>
<td>Compilation</td><td>Needs to be compiled (or transpiled) into JavaScript</td><td>Does not need to be compiled</td></tr>
<tr>
<td>OOP Features</td><td>Includes advanced OOP features such as interfaces, generics, and decorators</td><td>Supports OOP through prototypes, does not natively support interfaces or generics</td></tr>
<tr>
<td>Tooling</td><td>Offers better tooling with autocompletion, type checking, and source map support</td><td>Basic tooling</td></tr>
<tr>
<td>Community and Ecosystem</td><td>Newer, smaller community and ecosystem</td><td>Large community and vast ecosystem of libraries and frameworks since 1995</td></tr>
<tr>
<td>Learning Curve</td><td>Steeper due to additional features</td><td>Generally easier for beginners</td></tr>
<tr>
<td>Use Cases</td><td>Typically used in larger codebases where the benefits of type checking and autocompletion are most noticeable</td><td>Used for both client-side and server-side development, can be executed natively in the browser</td></tr>
</tbody>
</table>
</div><h2 id="heading-advantages-of-typescript">Advantages of TypeScript</h2>
<p>TypeScript offers several advantages over JavaScript:</p>
<ol start="2">
<li><p><strong>Improved Tooling</strong>: TypeScript's static typing enables better tooling support. Features like <code>autocompletion</code>, type <code>inference</code>, and type checking make the development process more efficient and enjoyable.</p>
</li>
<li><p><strong>Better Documentation</strong>: TypeScript codebases are often easier to understand and maintain. The type annotations serve as implicit documentation, making it easier to understand what kind of values a function expects and returns.</p>
</li>
<li><p><strong>Advanced Features</strong>: TypeScript supports advanced JavaScript features such as <code>decorators</code> and <code>async/await</code>, and it also introduces features not available in JavaScript, such as <code>interfaces</code>, <code>enums</code>, and <code>tuples</code>.</p>
</li>
<li><p><strong>Refactoring</strong>: TypeScript's tooling makes refactoring larger codebases safer and more predictable. You can make large-scale changes with confidence.</p>
</li>
<li><p><strong>Gradual Adoption</strong>: TypeScript is a superset of JavaScript, which means you can gradually adopt TypeScript in your projects. You can start by renaming your <code>.js</code> files to <code>.ts</code> and then you can gradually add type annotations as you see fit.</p>
</li>
<li><p><strong>Community and Ecosystem</strong>: TypeScript has a growing community and ecosystem. Many popular JavaScript libraries, such as React and Angular, have TypeScript definitions, which makes it easier to use them in a TypeScript project.</p>
</li>
</ol>
<h2 id="heading-code-generation">Code Generation</h2>
<p>TypeScript code isn't natively understood by browsers or Node.js, so it needs to be transpiled into JavaScript. This transpilation process is handled by the TypeScript compiler (<code>tsc</code>), which reads TypeScript code and generates equivalent JavaScript code.</p>
<p>To transpile a TypeScript file, you can use the <code>tsc</code> command followed by the filename:</p>
<pre><code class="lang-bash">$ tsc index.ts
</code></pre>
<p>This command transpiles the <code>index.ts</code> file into a <code>index.js</code> file in the same directory. The resulting JavaScript code can be executed in any JavaScript environment, such as a browser or Node.js.</p>
<h3 id="heading-watching-for-file-changes">Watching for File Changes</h3>
<p>During active development, it's beneficial to have your TypeScript code automatically recompiled whenever you make changes. The TypeScript compiler provides a <code>--watch</code> option for this purpose:</p>
<pre><code class="lang-shell">$ tsc index.ts --watch
</code></pre>
<p>With this command, the compiler will monitor the <code>index.ts</code> file and automatically recompile it whenever it detects a change.</p>
<h3 id="heading-configuring-the-typescript-compiler">Configuring the TypeScript Compiler</h3>
<p>For larger projects, it's common to have a configuration file, <code>tsconfig.json</code>, to manage compiler options. This file allows you to specify the root level files and the compiler options required to compile the project.</p>
<p>Here's an example of a <code>tsconfig.json</code> file:</p>
<pre><code class="lang-json">{
  <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"es5"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"commonjs"</span>,
    <span class="hljs-attr">"strict"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"outDir"</span>: <span class="hljs-string">"./dist"</span>
  },
  <span class="hljs-attr">"include"</span>: [<span class="hljs-string">"src/**/*.ts"</span>],
  <span class="hljs-attr">"exclude"</span>: [<span class="hljs-string">"node_modules"</span>]
}
</code></pre>
<p>In this configuration, the <code>compilerOptions</code> object contains options for the compiler. The <code>target</code> option specifies the ECMAScript target version, the <code>module</code> option sets the module system, the <code>strict</code> option enables a wide range of type checking behavior, and the <code>outDir</code> option specifies the output directory for the compiled JavaScript files.</p>
<p>The <code>include</code> and <code>exclude</code> options are used to specify the files to be compiled and ignored, respectively.</p>
<p>To compile the project based on the <code>tsconfig.json</code> file, you can run the <code>tsc</code> command without any arguments:</p>
<pre><code class="lang-bash">$ tsc
</code></pre>
<p>This command will compile all TypeScript files in the project according to the options specified in the <code>tsconfig.json</code> file.</p>
<h2 id="heading-typescript-basics">TypeScript Basics</h2>
<p>In this section , we'll go through the basics of TypeScript. You'll see more examples of how TypeScript is statically typed, and you'll learn more about its tooling and error checking.</p>
<h3 id="heading-installation">Installation</h3>
<p>Before we dive into TypeScript, you'll need to make sure that you have Node.js installed on your system. <code>Node.js</code> is a runtime environment that allows you to run JavaScript outside of the browser. You can download Node.js from the <a target="_blank" href="https://nodejs.org/en/download/">official website</a>.</p>
<p>Once Node.js is installed, you can install TypeScript using the Node Package Manager (npm), which comes bundled with Node.js.</p>
<p>Open your terminal and run the following command:</p>
<pre><code class="lang-bash">npm install -g typescript
</code></pre>
<p>This command installs TypeScript globally on your system. You can confirm the installation by running the <code>tsc</code> command, which stands for <code>TypeScript</code> <code>compiler</code>:</p>
<pre><code class="lang-bash">tsc --version
</code></pre>
<p>This command should display the version of TypeScript that you've installed.</p>
<p>Now that TypeScript is installed, we're ready to start our journey into the world of TypeScript!</p>
<h3 id="heading-configuration">Configuration</h3>
<p>Great! Now that we have TypeScript installed, let's talk about something else important: <code>configuration</code>. For larger projects, it's common to have a configuration file, <code>tsconfig.json</code>, to manage compiler options. This file allows you to specify the root level files and the compiler options required to compile the project.</p>
<p>When you run the <code>tsc</code> command, the compiler looks for a <code>tsconfig.json</code> file in the current directory. If it finds one, it uses the options specified in the file to compile the project. If it doesn't find one, it uses the default options.</p>
<p>To generate a <code>tsconfig.json</code> file, you can run the following command:</p>
<pre><code class="lang-bash">tsc --init
</code></pre>
<h3 id="heading-understanding-tsconfigjson">Understanding <code>tsconfig.json</code></h3>
<p>Now that we have TypeScript installed and configured, let's dive deeper into the <code>tsconfig.json</code> file. This file is a crucial part of any TypeScript project. It holds various settings that determine how your TypeScript code gets compiled into JavaScript.</p>
<p>To create a <code>tsconfig.json</code> file, you can use the <code>tsc --init</code> command as I showed above. This command generates a <code>tsconfig.json</code> file in your current directory with some default settings.</p>
<p>Here's an example of what a <code>tsconfig.json</code> file might look like:</p>
<pre><code class="lang-json">{
 <span class="hljs-attr">"compilerOptions"</span>: {
    <span class="hljs-attr">"target"</span>: <span class="hljs-string">"es5"</span>,
    <span class="hljs-attr">"module"</span>: <span class="hljs-string">"commonjs"</span>,
    <span class="hljs-attr">"strict"</span>: <span class="hljs-literal">true</span>,
    <span class="hljs-attr">"outDir"</span>: <span class="hljs-string">"./dist"</span>
 },
 <span class="hljs-attr">"include"</span>: [<span class="hljs-string">"src/**/*.ts"</span>],
 <span class="hljs-attr">"exclude"</span>: [<span class="hljs-string">"node_modules"</span>]
}
</code></pre>
<p>In this configuration:</p>
<ul>
<li><p>The <code>compilerOptions</code> object contains settings for the TypeScript compiler.</p>
</li>
<li><p>The <code>target</code> option tells the compiler which version of ECMAScript to compile your code down to.</p>
</li>
<li><p>The <code>module</code> option sets the module system for your project.</p>
</li>
<li><p>The <code>strict</code> option enables a wide range of type checking behavior.</p>
</li>
<li><p>The <code>outDir</code> option specifies the directory where the compiled JavaScript files will be placed.</p>
</li>
<li><p>The <code>include</code> and <code>exclude</code> options tell the compiler which files to include and exclude during the compilation process.</p>
</li>
</ul>
<p>After setting up your <code>tsconfig.json</code> file, you can compile your TypeScript project by simply running the <code>tsc</code> command in your terminal. This command will compile all TypeScript files in your project according to the options specified in your <code>tsconfig.json</code> file.</p>
<h3 id="heading-type-declarations-and-variables-in-typescript">Type Declarations and Variables in TypeScript</h3>
<p>Let's now learn more about types. TypeScript supports several types, including <code>number</code>, <code>string</code>, <code>boolean</code>, <code>object</code>, <code>null</code>, <code>undefined</code>, <code>symbol</code>, <code>bigint</code>, and <code>any</code>. Let's explore each of these types in detail.</p>
<ol>
<li><code>number</code>: This type is used for numeric values. It can be an integer or floating-point value.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> age: <span class="hljs-built_in">number</span> = <span class="hljs-number">30</span>;
<span class="hljs-keyword">let</span> weight: <span class="hljs-built_in">number</span> = <span class="hljs-number">65.5</span>;
</code></pre>
<ol start="2">
<li><code>string</code>: This type is used for textual data. It can be defined using single quotes, double quotes, or template literals.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> name: <span class="hljs-built_in">string</span> = <span class="hljs-string">'John Doe'</span>;
<span class="hljs-keyword">let</span> greeting: <span class="hljs-built_in">string</span> = <span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>`</span>;
</code></pre>
<ol start="3">
<li><code>boolean</code>: This type is used for logical values. It can only be <code>true</code> or <code>false</code>.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> isAdult: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">true</span>;
<span class="hljs-keyword">let</span> isStudent: <span class="hljs-built_in">boolean</span> = <span class="hljs-literal">false</span>;
</code></pre>
<ol start="4">
<li><code>object</code>: This type is used for complex data structures. An object can have properties and methods.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> person: <span class="hljs-built_in">object</span> = { name: <span class="hljs-string">'John Doe'</span>, age: <span class="hljs-number">30</span> };
<span class="hljs-keyword">let</span> date: <span class="hljs-built_in">object</span> = <span class="hljs-keyword">new</span> <span class="hljs-built_in">Date</span>();
</code></pre>
<ol start="5">
<li><code>null</code>: This type has only one value: <code>null</code>. It is used when you want to explicitly set a variable to have no value or object.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> emptyValue: <span class="hljs-literal">null</span> = <span class="hljs-literal">null</span>;
<span class="hljs-keyword">let</span> anotherEmptyValue: <span class="hljs-literal">null</span> = <span class="hljs-literal">null</span>;
</code></pre>
<ol start="6">
<li><code>undefined</code>: This type has only one value: <code>undefined</code>. It is used when a variable has been declared but has not yet been assigned a value.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> unassignedValue: <span class="hljs-literal">undefined</span> = <span class="hljs-literal">undefined</span>;
<span class="hljs-keyword">let</span> anotherUnassignedValue: <span class="hljs-literal">undefined</span>;
</code></pre>
<ol start="7">
<li><code>symbol</code>: This type is used to create unique identifiers for objects.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> symbol1: symbol = <span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'symbol1'</span>);
<span class="hljs-keyword">let</span> symbol2: symbol = <span class="hljs-built_in">Symbol</span>(<span class="hljs-string">'symbol2'</span>);
</code></pre>
<ol start="8">
<li><code>bigint</code>: This type is used for whole numbers larger than <code>2^53 - 1</code>, which is the upper limit for the <code>number</code> type.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> bigNumber: bigint = <span class="hljs-number">9007199254740993n</span>;
<span class="hljs-keyword">let</span> anotherBigNumber: bigint = BigInt(<span class="hljs-number">9007199254740993</span>);
</code></pre>
<ol start="9">
<li><code>any</code>: This type is used when the type of a variable could be anything. It is a way of opting out of type-checking.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> variable: <span class="hljs-built_in">any</span> = <span class="hljs-string">'I am a string'</span>;
variable = <span class="hljs-number">42</span>; <span class="hljs-comment">// I am a number now</span>
</code></pre>
<p>Now let talk about some different ways you can declare variables in TypeScript.</p>
<p>TypeScript provides a way to define the shape of an object, including its properties and methods, using type declarations. This allows you to create reusable types that can be used to define the structure of objects throughout your codebase.</p>
<ol>
<li><strong>Type Aliases</strong>: Type aliases are a way to create a new name for an existing type. They are often used to define complex types that are used in multiple places.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> Point = {
  x: <span class="hljs-built_in">number</span>;
  y: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">let</span> origin: Point = { x: <span class="hljs-number">0</span>, y: <span class="hljs-number">0</span> };
</code></pre>
<p>In this example, <code>Point</code> is a type alias for an object with <code>x</code> and <code>y</code> properties. It is used to define the type of the <code>origin</code> object.</p>
<ol start="2">
<li><strong>Intersection Types</strong>: Intersection types are a way to combine multiple types into a single type. They are often used to create complex types that have the properties of multiple other types.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> Printable = {
  print: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
};

<span class="hljs-keyword">type</span> Loggable = {
  log: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">void</span>;
};

<span class="hljs-keyword">type</span> Logger = Printable &amp; Loggable;

<span class="hljs-keyword">let</span> logger: Logger = {
  print: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Printing...'</span>),
  log: <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Logging...'</span>),
};
</code></pre>
<p>In this example, <code>Printable</code> and <code>Loggable</code> are two types that have a <code>print</code> and <code>log</code> method, respectively. The <code>Logger</code> type is an intersection of <code>Printable</code> and <code>Loggable</code>, so it has both a <code>print</code> and <code>log</code> method.</p>
<ol start="3">
<li><strong>Union Types</strong>: Union types are a way to define a type that can be one of several different types. They are often used to create flexible types that can represent a variety of values.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">type</span> ID = <span class="hljs-built_in">string</span> | <span class="hljs-built_in">number</span>;

<span class="hljs-keyword">let</span> id: ID = <span class="hljs-string">'123'</span>;
id = <span class="hljs-number">123</span>;
</code></pre>
<p>In this example, <code>ID</code> is a union type that can be either a <code>string</code> or a <code>number</code>. It is used to define the type of the <code>id</code> variable, which can be assigned a <code>string</code> or a <code>number</code>.</p>
<ol start="4">
<li><strong>Type Assertions</strong>: Type assertions are a way to tell the TypeScript compiler that you know more about the type of a value than it does. They are similar to type casting in other languages.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">let</span> value: <span class="hljs-built_in">any</span> = <span class="hljs-string">'Hello, TypeScript!'</span>;
<span class="hljs-keyword">let</span> length: <span class="hljs-built_in">number</span> = (value <span class="hljs-keyword">as</span> <span class="hljs-built_in">string</span>).length;
</code></pre>
<p>In this example, the <code>as</code> keyword is used to assert that <code>value</code> is of type <code>string</code>. This allows us to access the <code>length</code> property of the string.</p>
<h3 id="heading-functions-in-typescript">Functions in TypeScript</h3>
<p>Functions are the building blocks of any programming language. They encapsulate logic into reusable units of code, promoting code reuse and modularity. In TypeScript, functions can be defined using the <code>function</code> keyword or arrow functions (<code>=&gt;</code>). Both methods have their own use cases and characteristics.</p>
<p>Let's talk about some types of functions in TypeScript:</p>
<ol>
<li><strong>Function Declarations</strong>: Functions can be declared using the <code>function</code> keyword followed by a unique function name. The function body is enclosed in curly braces <code>{}</code>.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span></span>): <span class="hljs-title">void</span> </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>!`</span>);
}

greet(<span class="hljs-string">'Alice'</span>);  <span class="hljs-comment">// Outputs: Hello, Alice!</span>
</code></pre>
<p>In this example, <code>greet</code> is a function that takes one parameter, <code>name</code>, of type <code>string</code>. The function doesn't return anything, so its return type is <code>void</code>.</p>
<ol start="2">
<li><strong>Arrow Functions</strong>: Arrow functions are a more modern syntax for writing functions in TypeScript and JavaScript. They are especially useful when writing small, inline functions.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">const</span> greet = (name: <span class="hljs-built_in">string</span>): <span class="hljs-function"><span class="hljs-params">void</span> =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, <span class="hljs-subst">${name}</span>!`</span>);
}

greet(<span class="hljs-string">'Bob'</span>);  <span class="hljs-comment">// Outputs: Hello, Bob!</span>
</code></pre>
<p>In this example, <code>greet</code> is an arrow function that behaves exactly the same as the <code>greet</code> function in the previous example. The <code>=&gt;</code> symbol separates the function parameters and the function body.</p>
<ol start="3">
<li><strong>Function Types</strong>: In TypeScript, you can specify the types of the parameters and the return value of a function. This provides type safety, ensuring that the function is called with the correct types of arguments and that it returns the correct type of value.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">add</span>(<span class="hljs-params">a: <span class="hljs-built_in">number</span>, b: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">return</span> a + b;
}

<span class="hljs-keyword">let</span> sum: <span class="hljs-built_in">number</span> = add(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>);  <span class="hljs-comment">// sum is 3</span>
</code></pre>
<p>In this example, the <code>add</code> function takes two parameters, <code>a</code> and <code>b</code>, both of type <code>number</code>, and returns a <code>number</code>.</p>
<ol start="4">
<li><strong>Optional and Default Parameters</strong>: TypeScript allows function parameters to be optional or have default values.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">greet</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, greeting: <span class="hljs-built_in">string</span> = 'Hello'</span>): <span class="hljs-title">void</span> </span>{
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`<span class="hljs-subst">${greeting}</span>, <span class="hljs-subst">${name}</span>!`</span>);
}

greet(<span class="hljs-string">'Charlie'</span>);  <span class="hljs-comment">// Outputs: Hello, Charlie!</span>
greet(<span class="hljs-string">'Charlie'</span>, <span class="hljs-string">'Hi'</span>);  <span class="hljs-comment">// Outputs: Hi, Charlie!</span>
</code></pre>
<p>In this example, the <code>greet</code> function has two parameters, <code>name</code> and <code>greeting</code>. The <code>greeting</code> parameter is optional and has a default value of 'Hello'.</p>
<ol start="5">
<li><strong>Rest Parameters</strong>: TypeScript supports rest parameters, which allow you to pass an arbitrary number of arguments to a function.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">sum</span>(<span class="hljs-params">...numbers: <span class="hljs-built_in">number</span>[]</span>): <span class="hljs-title">number</span> </span>{
  <span class="hljs-keyword">return</span> numbers.reduce(<span class="hljs-function">(<span class="hljs-params">a, b</span>) =&gt;</span> a + b, <span class="hljs-number">0</span>);
}

<span class="hljs-keyword">let</span> total: <span class="hljs-built_in">number</span> = sum(<span class="hljs-number">1</span>, <span class="hljs-number">2</span>, <span class="hljs-number">3</span>, <span class="hljs-number">4</span>, <span class="hljs-number">5</span>); <span class="hljs-comment">// total is 15</span>
</code></pre>
<p>In this example, the <code>sum</code> function takes an arbitrary number of arguments and returns their sum.</p>
<h3 id="heading-classes-and-objects-in-typescript">Classes and Objects in TypeScript</h3>
<p>Classes are a fundamental part of object-oriented programming (OOP). They are templates for creating objects, providing initial values for state (member variables) and implementations of behavior (member functions or methods).</p>
<p>TypeScript supports classes, which are declared using the <code>class</code> keyword. One advantage of TypeScript classes is that they support object-oriented programming (OOP) features such as <code>inheritance</code>, <code>encapsulation</code>, and <code>polymorphism</code>.</p>
<ol>
<li><strong>Class Declaration</strong>: In TypeScript, classes are declared using the <code>class</code> keyword.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Person {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
  }

  greet(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, my name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> and I am <span class="hljs-subst">${<span class="hljs-built_in">this</span>.age}</span> years old.`</span>);
  }
}

<span class="hljs-keyword">let</span> john = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">'John'</span>, <span class="hljs-number">25</span>);
john.greet(); <span class="hljs-comment">// Outputs: Hello, my name is John and I am 25 years old.</span>
</code></pre>
<p>In this example, <code>Person</code> is a class with two properties, <code>name</code> and <code>age</code>, and a method <code>greet</code>. The <code>constructor</code> is a special method for creating and initializing an object created with a class.</p>
<ol start="2">
<li><strong>Inheritance</strong>: TypeScript supports inheritance, a mechanism of basing a class upon another class, retaining similar implementation. Inheritance is achieved using the <code>extends</code> keyword.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Employee <span class="hljs-keyword">extends</span> Person {
  department: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span>, department: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">super</span>(name, age);
    <span class="hljs-built_in">this</span>.department = department;
  }

  greet(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">super</span>.greet();
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`I work in <span class="hljs-subst">${<span class="hljs-built_in">this</span>.department}</span>.`</span>);
  }
}

<span class="hljs-keyword">let</span> jane = <span class="hljs-keyword">new</span> Employee(<span class="hljs-string">'Jane'</span>, <span class="hljs-number">30</span>, <span class="hljs-string">'HR'</span>);
jane.greet(); <span class="hljs-comment">// Outputs: Hello, my name is Jane and I am 30 years old. I work in HR.</span>
</code></pre>
<p>In this example, <code>Employee</code> is a class that extends <code>Person</code>. It adds a new property <code>department</code> and overrides the <code>greet</code> method. The <code>super</code> keyword is used to call corresponding methods of the parent class.</p>
<ol start="3">
<li><strong>Abstract Classes</strong>: Abstract classes are classes that cannot be instantiated directly. They are used as base classes for other classes and can contain abstract methods that must be implemented by derived classes.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> Shape {
  <span class="hljs-keyword">abstract</span> area(): <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">class</span> Circle <span class="hljs-keyword">extends</span> Shape {
  radius: <span class="hljs-built_in">number</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">radius: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">super</span>();
    <span class="hljs-built_in">this</span>.radius = radius;
  }

  area(): <span class="hljs-built_in">number</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">Math</span>.PI * <span class="hljs-built_in">this</span>.radius ** <span class="hljs-number">2</span>;
  }
}

<span class="hljs-keyword">let</span> circle = <span class="hljs-keyword">new</span> Circle(<span class="hljs-number">5</span>);
<span class="hljs-built_in">console</span>.log(circle.area()); <span class="hljs-comment">// Outputs: 78.54</span>
</code></pre>
<p>In this example, <code>Shape</code> is an abstract class with an abstract method <code>area</code>. The <code>Circle</code> class extends <code>Shape</code> and implements the <code>area</code> method. Abstract classes are useful for defining a common interface for a set of classes.</p>
<ol start="4">
<li><strong>Encapsulation</strong>: Encapsulation is the bundling of data (properties) and methods that operate on the data (methods) into a single unit called a class. In TypeScript, encapsulation is achieved by using access modifiers such as public, private, and protected.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-ts"><span class="hljs-keyword">class</span> Person {
  <span class="hljs-keyword">private</span> name: <span class="hljs-built_in">string</span>;
  <span class="hljs-keyword">protected</span> age: <span class="hljs-built_in">number</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span></span>) {
    <span class="hljs-built_in">this</span>.name = name;
    <span class="hljs-built_in">this</span>.age = age;
  }

  greet(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">`Hello, my name is <span class="hljs-subst">${<span class="hljs-built_in">this</span>.name}</span> and I am <span class="hljs-subst">${<span class="hljs-built_in">this</span>.age}</span> years old.`</span>);
  }
}

<span class="hljs-keyword">let</span> john = <span class="hljs-keyword">new</span> Person(<span class="hljs-string">"John"</span>, <span class="hljs-number">25</span>);
<span class="hljs-built_in">console</span>.log(john.name); <span class="hljs-comment">// Error: Property "name" is private</span>
<span class="hljs-built_in">console</span>.log(john.age);  <span class="hljs-comment">// Error: Property "age" is protected</span>
</code></pre>
<p>In this example, <code>name</code> is a private property of the <code>Person</code> class, so it cannot be accessed from outside the class. <code>age</code> is a protected property, so it can be accessed from subclasses but not from outside the class.</p>
<ol start="5">
<li><strong>Polymorphism</strong>: Polymorphism is the ability of an object to take on many forms. In TypeScript, polymorphism is achieved through method overriding, where a method in a subclass has the same name and signature as a method in its superclass.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Animal {
  speak(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Animal makes a sound'</span>);
  }
}

<span class="hljs-keyword">class</span> Dog <span class="hljs-keyword">extends</span> Animal {
  speak(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Dog barks'</span>);
  }
}

<span class="hljs-keyword">let</span> animal: Animal = <span class="hljs-keyword">new</span> Dog();
animal.speak(); <span class="hljs-comment">// Outputs: Dog barks</span>
</code></pre>
<p>In this example, <code>Animal</code> is a base class with a <code>speak</code> method. <code>Dog</code> is a subclass that overrides the <code>speak</code> method. When an instance of <code>Dog</code> is assigned to a variable of type <code>Animal</code>, the <code>speak</code> method of <code>Dog</code> is called.</p>
<ol start="6">
<li><strong>Access Modifiers</strong>: TypeScript supports the access modifiers <code>public</code>, <code>private</code>, and <code>protected</code>. By default, each member is <code>public</code>.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Animal {
  <span class="hljs-keyword">private</span> name: <span class="hljs-built_in">string</span>;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span></span>) {
    <span class="hljs-built_in">this</span>.name = name;
  }

  <span class="hljs-keyword">public</span> getName(): <span class="hljs-built_in">string</span> {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.name;
  }
}

<span class="hljs-keyword">let</span> dog = <span class="hljs-keyword">new</span> Animal(<span class="hljs-string">'Dog'</span>);
<span class="hljs-built_in">console</span>.log(dog.getName()); <span class="hljs-comment">// Outputs: Dog</span>
</code></pre>
<p>In this example, <code>name</code> is a private member of the <code>Animal</code> class. It can only be accessed within the <code>Animal</code> class. The <code>getName</code> method is public, so it can be called from outside the class.</p>
<h3 id="heading-interfaces-in-typescript">Interfaces in TypeScript</h3>
<p>Interfaces in TypeScript are powerful ways to define contracts within your code. They are used to type-check whether an object fits a certain structure.</p>
<p>By defining an interface we can name a specific combination of variables, making sure they will always be used as a set.</p>
<ol>
<li><strong>Interface Declaration</strong>: Interfaces are declared with the <code>interface</code> keyword.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Person {
  name: <span class="hljs-built_in">string</span>;
  age: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">let</span> john: Person = { name: <span class="hljs-string">'John'</span>, age: <span class="hljs-number">25</span> };
</code></pre>
<p>In this example, <code>Person</code> is an interface that describes an object that has a <code>name</code> of type <code>string</code> and an <code>age</code> of type <code>number</code>.</p>
<ol start="2">
<li><strong>Optional Properties</strong>: Interface properties can be marked as optional with <code>?</code>.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Person {
  name: <span class="hljs-built_in">string</span>;
  age?: <span class="hljs-built_in">number</span>;
}

<span class="hljs-keyword">let</span> alice: Person = { name: <span class="hljs-string">'Alice'</span> };
</code></pre>
<p>In this example, <code>age</code> is an optional property in the <code>Person</code> interface. The object <code>alice</code> is still a <code>Person</code> even though it doesn't have an <code>age</code>.</p>
<ol start="3">
<li><strong>Function Types</strong>: Interfaces can also describe function types.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> GreetFunction {
  (name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span>): <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">let</span> greet: GreetFunction = <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">name: <span class="hljs-built_in">string</span>, age: <span class="hljs-built_in">number</span></span>): <span class="hljs-title">string</span> </span>{
  <span class="hljs-keyword">return</span> <span class="hljs-string">`Hello, my name is <span class="hljs-subst">${name}</span> and I am <span class="hljs-subst">${age}</span> years old.`</span>;
};
</code></pre>
<p>In this example, <code>GreetFunction</code> is an interface that describes a function that takes a <code>name</code> and an <code>age</code> and returns a <code>string</code>.</p>
<ol start="4">
<li><strong>Extending Interfaces</strong>: Interfaces can extend one another, creating a new interface that inherits the members of the base interface.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Animal {
  name: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">interface</span> Dog <span class="hljs-keyword">extends</span> Animal {
  breed: <span class="hljs-built_in">string</span>;
}

<span class="hljs-keyword">let</span> myDog: Dog = { name: <span class="hljs-string">'Rex'</span>, breed: <span class="hljs-string">'German Shepherd'</span> };
</code></pre>
<p>In this example, <code>Dog</code> extends <code>Animal</code>, so a <code>Dog</code> has both a <code>name</code> and a <code>breed</code>.</p>
<h3 id="heading-enums-in-typescript">Enums in TypeScript</h3>
<p>Enums are a way to define a set of named constants. They are often used to represent a set of related values, such as the days of the week or the months of the year.</p>
<p>TypeScript supports both numeric and string enums, providing a flexible way to define and work with sets of constants.</p>
<ol>
<li><strong>Numeric Enums</strong>: Numeric enums are a way to define a set of named constants with numeric values. By default, the values of the constants start at 0 and increment by 1 for each subsequent constant.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">enum</span> Day {
  Sunday,
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday
}

<span class="hljs-keyword">let</span> today: Day = Day.Monday;
</code></pre>
<p>In this example, <code>Day</code> is a numeric enum that represents the days of the week. The constants <code>Sunday</code>, <code>Monday</code>, <code>Tuesday</code>, and so on are assigned numeric values starting from 0.</p>
<ol start="2">
<li><strong>String Enums</strong>: String enums are a way to define a set of named constants with string values. Unlike numeric enums, the values of the constants in a string enum are initialized with the value of the constant name.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">enum</span> Month {
  January = <span class="hljs-string">'January'</span>,
  February = <span class="hljs-string">'February'</span>,
  March = <span class="hljs-string">'March'</span>,
  April = <span class="hljs-string">'April'</span>,
  May = <span class="hljs-string">'May'</span>,
  June = <span class="hljs-string">'June'</span>,
  July = <span class="hljs-string">'July'</span>,
  August = <span class="hljs-string">'August'</span>,
  September = <span class="hljs-string">'September'</span>,
  October = <span class="hljs-string">'October'</span>,
  November = <span class="hljs-string">'November'</span>,
  December = <span class="hljs-string">'December'</span>
}

<span class="hljs-keyword">let</span> currentMonth: Month = Month.June;
</code></pre>
<p>In this example, <code>Month</code> is a string enum that represents the months of the year. The constants <code>January</code>, <code>February</code>, <code>March</code>, and so on are assigned string values equal to their names.</p>
<ol start="3">
<li><strong>Computed Enums</strong>: Enums can have computed values, which are initialized with an expression instead of a constant value. This allows for more flexibility in defining the values of the constants.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">enum</span> Color {
  Red = <span class="hljs-number">1</span>,
  Green = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">2</span>, <span class="hljs-number">2</span>),
  Blue = <span class="hljs-built_in">Math</span>.pow(<span class="hljs-number">2</span>, <span class="hljs-number">3</span>)
}

<span class="hljs-keyword">let</span> color: Color = Color.Green;
</code></pre>
<p>In this example, <code>Color</code> is an enum with computed values. The constants <code>Red</code>, <code>Green</code>, and <code>Blue</code> are assigned the values 1, 4, and 8, respectively, using the <code>Math.pow</code> function.</p>
<ol start="4">
<li><strong>Reverse Mapping</strong>: Enums in TypeScript support reverse mapping, which means that you can access the name of a constant from its value. This is useful for debugging and logging purposes.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-built_in">enum</span> Day {
  Sunday,
  Monday,
  Tuesday,
  Wednesday,
  Thursday,
  Friday,
  Saturday
}

<span class="hljs-keyword">let</span> dayName: <span class="hljs-built_in">string</span> = Day[<span class="hljs-number">1</span>]; <span class="hljs-comment">// 'Monday'</span>
</code></pre>
<p>In this example, the <code>Day</code> enum is used to access the name</p>
<h3 id="heading-generics-in-typescript">Generics in TypeScript</h3>
<p>Generics are a way to define a function or class that can be used with different types of data. They are often used to create reusable components that can work with different types of data.</p>
<p>TypeScript supports generics, allowing you to write type-safe code that is flexible and reusable.</p>
<p>Now let's look at some examples of generic functions and classes.</p>
<ol>
<li><strong>Generic Functions</strong>: Generic functions are functions that can work with a variety of data types. They are defined using type parameters, which are placeholders for the actual types that will be used when the function is called.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">identity</span>&lt;<span class="hljs-title">T</span>&gt;(<span class="hljs-params">value: T</span>): <span class="hljs-title">T</span> </span>{
  <span class="hljs-keyword">return</span> value;
}

<span class="hljs-keyword">let</span> result1: <span class="hljs-built_in">number</span> = identity&lt;<span class="hljs-built_in">number</span>&gt;(<span class="hljs-number">42</span>);
<span class="hljs-keyword">let</span> result2: <span class="hljs-built_in">string</span> = identity&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">'Hello, TypeScript!'</span>);
</code></pre>
<p>In this example, <code>identity</code> is a generic function that takes a type parameter <code>T</code> and returns a value of type <code>T</code>. The type parameter <code>T</code> is used to specify the type of the argument and the return value.</p>
<ol start="2">
<li><strong>Generic Classes</strong>: Generic classes are classes that can work with a variety of data types. They are defined using type parameters, which are placeholders for the actual types that will be used when the class is instantiated.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">class</span> Box&lt;T&gt; {
  value: T;

  <span class="hljs-keyword">constructor</span>(<span class="hljs-params">value: T</span>) {
    <span class="hljs-built_in">this</span>.value = value;
  }
}

<span class="hljs-keyword">let</span> box1: Box&lt;<span class="hljs-built_in">number</span>&gt; = <span class="hljs-keyword">new</span> Box&lt;<span class="hljs-built_in">number</span>&gt;(<span class="hljs-number">42</span>);
<span class="hljs-keyword">let</span> box2: Box&lt;<span class="hljs-built_in">string</span>&gt; = <span class="hljs-keyword">new</span> Box&lt;<span class="hljs-built_in">string</span>&gt;(<span class="hljs-string">'Hello, TypeScript!'</span>);
</code></pre>
<p>In this example, <code>Box</code> is a generic class that takes a type parameter <code>T</code> and has a property <code>value</code> of type <code>T</code>. The type parameter <code>T</code> is used to specify the type of the value stored in the box.</p>
<ol start="3">
<li><strong>Generic Constraints</strong>: Generic constraints are a way to restrict the types that can be used with a generic function or class. They are defined using the <code>extends</code> keyword, followed by the type or interface that the type parameter must extend.</li>
</ol>
<p>Example:</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">interface</span> Printable {
  print(): <span class="hljs-built_in">void</span>;
}

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">printValue</span>&lt;<span class="hljs-title">T</span> <span class="hljs-title">extends</span> <span class="hljs-title">Printable</span>&gt;(<span class="hljs-params">value: T</span>): <span class="hljs-title">void</span> </span>{
  value.print();
}

<span class="hljs-keyword">class</span> Person <span class="hljs-keyword">implements</span> Printable {
  print(): <span class="hljs-built_in">void</span> {
    <span class="hljs-built_in">console</span>.log(<span class="hljs-string">'Printing person...'</span>);
  }
}

<span class="hljs-keyword">let</span> person: Person = <span class="hljs-keyword">new</span> Person();
printValue(person);
</code></pre>
<p>In this example, <code>Printable</code> is an interface that defines a <code>print</code> method. The <code>printValue</code> function is a generic function that takes a type parameter <code>T</code> that must extend <code>Printable</code>. The <code>Person</code> class implements the <code>Printable</code> interface.</p>
<p>At this point you have a basic understanding of TypeScript and you can start diving into more advanced concepts.</p>
<h2 id="heading-conclusion">Conclusion</h2>
<p>In this article, you've learned the basics of TypeScript.</p>
<p>We talked about the basic syntax of TypeScript, such as variables, functions, and classes.</p>
<p>You also learned about TypeScript's built-in types, such as numbers, strings, and booleans.</p>
<p>We discussed TypeScript's built-in enumerations, such as number enums, string enums, and computed enums. And you learned about TypeScript's generic types, such as generic functions and classes.</p>
<p>Thank you for reading!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build CRUD Operations with .NET Core – A Todo API Handbook ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to this comprehensive guide on building CRUD operations with .NET Core. We'll use a Todo API as our practical example so you can get hands-on experience as you learn.  Throughout this tutorial, you'll learn how to create, read, update, and de... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-crud-operations-with-dotnet-core-handbook/</link>
                <guid isPermaLink="false">66bb56fb3c5ab240beb8cd95</guid>
                
                    <category>
                        <![CDATA[ api ]]>
                    </category>
                
                    <category>
                        <![CDATA[ crud ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ .net core ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Fri, 24 May 2024 14:33:16 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/05/Attractive.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to this comprehensive guide on building CRUD operations with .NET Core. We'll use a Todo API as our practical example so you can get hands-on experience as you learn. </p>
<p>Throughout this tutorial, you'll learn how to create, read, update, and delete Todo items, and how to leverage Entity Framework Core to interact with a database.</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-how-to-enhance-your-development-experience-with-visual-studio-code-extensions">How to Enhance Your Development Experience with Visual Studio Code Extensions</a></li>
<li><a class="post-section-overview" href="#heading-learning-outcomes">Learning Outcomes</a></li>
<li><a class="post-section-overview" href="#heading-what-is-net-core">What is .NET Core?</a></li>
<li><a class="post-section-overview" href="#heading-net-core-vs-net-framework">.NET Core vs .NET Framework</a></li>
<li><a class="post-section-overview" href="#heading-step-1-set-up-your-project-directory">Step 1: Set Up Your Project Directory</a></li>
<li><a class="post-section-overview" href="#heading-step-2-establish-your-project-structure">Step 2: Establish Your Project Structure</a></li>
<li><a class="post-section-overview" href="#heading-step-3-create-the-todo-model">Step 3: Create the Todo Model</a></li>
<li><a class="post-section-overview" href="#heading-step-4-set-up-the-database-context">Step 4: Set Up the Database Context</a></li>
<li><a class="post-section-overview" href="#heading-step-5-define-data-transfer-objects-dtos">Step 5: Define Data Transfer Objects (DTOs)</a></li>
<li><a class="post-section-overview" href="#heading-step-6-implement-object-mapping-for-the-todo-api">Step 6: Implement Object Mapping for the Todo API</a></li>
<li><a class="post-section-overview" href="#heading-step-7-implement-global-exception-handling-middleware">Step 7: Implement Global Exception Handling Middleware</a>  </li>
<li><a class="post-section-overview" href="#heading-step-8-implement-the-service-layer-and-service-interface">Step 8: Implement the Service Layer and Service Interface</a></li>
<li><a class="post-section-overview" href="#heading-step-9-implement-the-createtodoasync-method-in-the-todoservices-class">step 9: Implement the CreateTodoAsync Method in the Service Class</a> </li>
<li><a class="post-section-overview" href="#heading-step-10-implement-the-getallasync-method-in-the-service-class">Step 10: Implement the GetAllAsync Method in the Service Class</a> </li>
<li><a class="post-section-overview" href="#heading-step-11-create-the-todocontroller-class">step 11: Create the TodoController Class  </a> </li>
<li><a class="post-section-overview" href="#step-12">Step 12: Implement the CreateTodoAsync  Method in the TodoController Class</a></li>
<li><a class="post-section-overview" href="#heading-step-13-implement-migrations-and-update-the-database">Step 13: Implement Migrations and Update the Database</a></li>
<li><a class="post-section-overview" href="#heading-step-14-verify-your-api-with-postman">Step 14: Verify Your API with Postman</a></li>
<li><a class="post-section-overview" href="#heading-step-15-retrieve-all-todo-items">Step 15: Retrieve All Todo Items</a> </li>
<li><a class="post-section-overview" href="#heading-step-16-implement-the-getbyidasync-method">Step 16: Implement the GetByIdAsync Method</a></li>
<li><a class="post-section-overview" href="#heading-step-17-implement-the-updatetodoasync-method">Step 17: Implement the UpdateTodoAsync Method</a></li>
<li><a class="post-section-overview" href="#heading-step-18-implement-the-deletetodoasync-method">Step 18: Implement the DeleteTodoAsync Method</a></li>
<li><a class="post-section-overview" href="#heading-step-19-test-your-api-endpoints-with-postman">Step 19: Test Your API Endpoints with Postman</a></li>
<li><a class="post-section-overview" href="#heading-conclusion">Conclusion</a></li>
</ul>
<p>Before we dive in, let's ensure you're equipped with the necessary prerequisites.</p>
<h2 id="prerequisites">Prerequisites</h2>

<p>Before you get started, make sure you have the necessary tools installed on your machine. Here are the download links:</p>
<ul>
<li><a target="_blank" href="https://dotnet.microsoft.com/download">.NET SDK</a></li>
<li><a target="_blank" href="https://code.visualstudio.com/download">Visual Studio Code</a></li>
<li><a target="_blank" href="https://visualstudio.microsoft.com/downloads/">Visual Studio 2019</a></li>
<li><a target="_blank" href="https://www.postman.com/downloads/">Postman</a></li>
<li><a target="_blank" href="https://www.microsoft.com/en-us/sql-server/sql-server-downloads">SQLServer</a></li>
</ul>
<p>After installing the .NET SDK, it's important to verify its installation and check the version. For this tutorial, we'll be using .NET 8.0.</p>
<p>To check the version of the .NET SDK installed on your machine, open the terminal and run the following command:</p>
<pre><code class="lang-bash">dotnet --version
</code></pre>
<p>If the .NET SDK is installed correctly, the version number will be displayed in the terminal:</p>
<pre><code class="lang-bash">8.0
</code></pre>
<p>If you see a different version number, ensure you have .NET 8.0 installed on your machine.</p>
<h2 id="enhancing-development"> How to Enhance Your Development Experience with Visual Studio Code Extensions</h2>

<p>Visual Studio Code, a lightweight and open-source code editor, is an excellent tool for building .NET Core applications. And you can further enhance its functionality with extensions that streamline the development process. </p>
<p>Here are two recommended extensions for .NET Core development:</p>
<ul>
<li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csdevkit">C# for Visual Studio Code</a></li>
<li><a target="_blank" href="https://marketplace.visualstudio.com/items?itemName=adrianwilczynski.namespace">C# Namespace Autocompletion</a></li>
</ul>
<p>To install these extensions, follow these steps:</p>
<ol>
<li>Open Visual Studio Code.</li>
<li>Click on the Extensions icon in the Activity Bar on the side of the window to open the Extensions view.</li>
<li>In the search bar, type the name of the extension.</li>
<li>In the search results, locate the correct extension and click on the Install button.</li>
</ol>
<p>Here's how the Extensions view looks in Visual Studio Code:</p>
<ul>
<li><p>C# Devkit Extension for Visual Studio Code
<img src="https://www.freecodecamp.org/news/content/images/2024/05/DevKIt.png" alt="Extensions view for Devkit" width="600" height="400" loading="lazy"></p>
</li>
<li><p>Namespace Autocompletion Extension for Visual Studio Code
<img src="https://www.freecodecamp.org/news/content/images/2024/05/NameSpace.png" alt="Extensions view for Namespace Autocompletion" width="600" height="400" loading="lazy"></p>
</li>
</ul>
<p>In the images above, the extensions are already installed. If they're not installed on your system, you can do so by clicking on the Install button.</p>
<p>With these essential tools in place, we're now fully equipped to start building our Todo API.</p>
<h2 id="learning-outcomes"> Learning Outcomes </h2>


<p>By the end of this tutorial, you'll have learned how to:</p>
<ul>
<li>Set up a new .NET Core project using the .NET Core CLI</li>
<li>Define a model for a Todo item</li>
<li>Create a database context to interact with the database</li>
<li>Implement routing and controllers for the Todo API</li>
<li>Create a service class to handle business logic</li>
<li>Implement CRUD operations for the Todo API</li>
<li>Handle exceptions globally using middleware</li>
<li>Test the API endpoints using Postman</li>
</ul>
<p>If you're new to C# and .NET, don't worry. I'll explain all the concepts in depth to ensure you understand them. For additional information, you can refer to the <a target="_blank" href="https://docs.microsoft.com/en-us/dotnet/csharp/">C# documentation</a>.</p>
<p>Before we delve into the code, let's clarify what .NET Core is.</p>
<h2 id="what-is-net-core"> What is .NET Core? </h2>

<p>.NET Core, also known as ASP.NET, is a cross-platform framework that facilitates the building of web applications, APIs, and services. It's a free, open-source, and high-performance framework, designed for creating modern, cloud-based, internet-connected applications. It's the successor to the .NET Framework.</p>
<p>But what's the difference between .NET Core and .NET Framework?</p>
<h2 id="net-core-vs-net-framework"> .NET Core vs .NET Framework </h2>

<p>.NET Core and .NET Framework are two distinct frameworks used for application development. .NET Core is a cross-platform framework that operates on Windows, macOS, and Linux. It's a modular, open-source, and free-to-use framework, designed for building modern, cloud-based, internet-connected applications.</p>
<p>On the other hand, <code>.NET Framework</code> is a <code>Windows-only framework</code> used for building <code>Windows desktop</code> <code>applications</code>, <code>web applications</code>, and services. Unlike .NET Core, it's not open-source or free to use. However, it's a mature framework that has been around for a long time.</p>
<p>With a foundational understanding of .NET Core and .NET Framework under your belt, we're ready to dive into building our Todo API.</p>
<p>In this tutorial, we'll leverage .NET Core to construct a Todo API that performs CRUD operations. Our journey will take us through creating a new project, defining the Todo model, setting up the database, and implementing the CRUD operations.</p>
<p>Let's begin with Visual Studio Code. In this tutorial, we'll be using the .NET Core CLI to create our project and build our API. If you prefer Visual Studio 2019, you can follow along using that IDE as well but we will be using Visual Studio Code for this article. </p>
<h2 id="step-1">  Step 1: Set Up Your Project Directory </h2>

<p>First, navigate to the directory where you want to house your project. This could be any folder on your system where you'd like to store your code.</p>
<p>Once you're in the desired directory, open the terminal. You can do this in Visual Studio Code by going to <code>View -&gt; Terminal</code> or by pressing Ctrl + a  backtick.</p>
<p>With the terminal open, type the following command:</p>
<pre><code class="lang-bash">dotnet new webapi -n TodoAPI
</code></pre>
<p>This command instructs the .NET Core CLI to create a new web API project named <code>TodoAPI</code>. The <code>-n</code> option specifies the name of the project.</p>
<p> <img src="https://www.freecodecamp.org/news/content/images/2024/05/TerminalCreatingNewAPI.png" alt="Creating a new API with the .NET Core CLI" width="600" height="400" loading="lazy"></p>
<p>The image above illustrates how to execute the command in the terminal.</p>
<p>After pressing the 'Enter' key, the .NET Core CLI will start generating the necessary files for your project.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/ProjectFile.png" alt=".NET project folder structure" width="600" height="400" loading="lazy"></p>
<p>The image above showcases the generated project structure. It includes all the necessary files and directories required for a .NET Core web API project.</p>
<p>With the project files and folders generated by the .NET Core CLI, let's take a moment to understand the purpose of each file.</p>
<ul>
<li><p><code>appsettings.json</code>: This file houses the application's configuration settings. It's the go-to place for storing connection strings, logging configurations, and other settings.</p>
</li>
<li><p><code>Program.cs</code>: Serving as the application's entry point, this file is responsible for setting up the host and configuring the services.</p>
</li>
<li><p><code>TodoAPI.csproj</code>: This project file contains metadata about your project, including references to the necessary packages and libraries.</p>
</li>
<li><p><code>appsettings.Development.json</code>: This file is designed for configuration settings specific to the development environment. It's ideal for storing environment-specific settings. But for the purpose of this tutorial, we'll be using the <code>appsettings.json</code> file instead.</p>
</li>
<li><p><code>TodoAPI.http</code>: This file is typically used to test API endpoints using the REST Client extension in Visual Studio Code, as it contains sample requests for the API endpoints. However, in this tutorial, we'll be using Postman for testing, so we won't need this file and will proceed to delete it.</p>
</li>
</ul>
<h2 id="step-2">  Step 2: Establish Your Project Structure  </h2>

<p>Having set up our project directory, it's time to lay out the structure of our project. We'll be creating several folders, each with a specific purpose:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/ProjectFolder.png" alt="project folder structure" width="600" height="400" loading="lazy"></p>
<ul>
<li><code>AppDataContext</code>: This folder will contain the database context, which is responsible for interacting with the database.</li>
<li><code>Contracts</code>: This folder will house our Data Transfer Objects (DTOs), which are used to shape the data sent between the client and the server.</li>
<li><code>Models</code>: This folder will contain the Todo model, which represents the structure of a Todo item.</li>
<li><code>Controllers</code>: This folder will house the TodoController, which handles incoming HTTP requests and sends responses.</li>
<li><code>Interfaces</code>: This folder will contain the IService interface, which defines the contract for our service class.</li>
<li><code>Services</code>: This folder will house the Service class, which implements the IService interface and contains the business logic of our application.</li>
<li><code>Mapping</code>: This folder will contain the mapping profile, which is used to map properties between different objects.</li>
<li><code>Middleware</code>: This folder will house the exception middleware, which handles exceptions globally across our application.</li>
</ul>
<p><em>Congratulations!</em> You've successfully set up your project directory and established the project structure. In the next section, we'll delve into defining the Todo model.</p>
<h3 id="heading-how-to-adjust-the-programcs-file-for-controllerbase">   How to Adjust the Program.cs File for ControllerBase </h3>

<p>When creating a new application using the <code>dotnet new webapi</code> command in .NET Core 6 and onwards, the generated project is a minimal web API project. But for this tutorial, we'll be using the traditional way of creating APIs, which requires some adjustments to the <code>Program.cs</code> file.</p>
<p>Before we dive into the changes, let's briefly discuss what a minimal API is.</p>
<h3 id="heading-understanding-minimal-apis">  Understanding Minimal APIs </h3>

<p>In .NET 6, Microsoft introduced a new feature known as Minimal APIs. These APIs are simpler and more lightweight than traditional APIs. They allow you to define your API routes and endpoints using a single file, without the need for controllers or startup classes. This approach facilitates the creation of small, focused APIs that are quick to build and easy to maintain.</p>
<p>However, for the purpose of this tutorial, we'll stick to the traditional API structure. Let's proceed with the necessary changes to the <code>Program.cs</code> file.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/Program.cs.png" alt="Initial view of Program.cs" width="600" height="400" loading="lazy"></p>
<p>The image above displays the initial state of the <code>Program.cs</code> file when you create a new web API project. To adapt it for use with ControllerBase, we need to remove some code and add new code.</p>
<p>Start by deleting everything in the <code>Program.cs</code> file and replacing it with the following code:</p>
<pre><code class="lang-csharp">
 <span class="hljs-comment">// program.cs</span>
<span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);

<span class="hljs-comment">// Add services to the container.</span>
builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

<span class="hljs-keyword">var</span> app = builder.Build();

<span class="hljs-comment">// Configure the HTTP request pipeline.</span>
<span class="hljs-keyword">if</span> (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();

app.UseAuthorization();

app.MapControllers();

app.Run();
</code></pre>
<p>Now we can proceed to the next step, where we'll define the Todo model.</p>
<h2 id="step-3">  Step 3: Create the Todo Model  </h2>

<p>Before diving into creating our Todo model, it's important to know what a model does in <code>.NET CORE</code>. Think of a <code>model</code> as a <code>blueprint</code> for the kind of data our application will work with. It helps us organize and manage this data efficiently.</p>
<p>For our Todo list app, we need a clear picture of what each Todo item looks like. This means deciding on things like names, descriptions, whether it's done or not, deadlines, priorities, and when it was made or changed. By being clear about these details, we can handle and show our Todo items well.</p>
<h3 id="heading-meet-the-todo-model">  Meet the Todo Model </h3>

<p>Now, let's make our idea real by creating the <code>Todo</code> model. This model is like a template for our Todo items, making sure they have all the right pieces.</p>
<p>Let's create a new file called <code>Todo.cs</code> in the <code>Models</code> folder and fill it with this code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Models/Todo.cs</span>
<span class="hljs-keyword">using</span> System.ComponentModel.DataAnnotations;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Todo</span>
    {
        [<span class="hljs-meta">Key</span>]
        <span class="hljs-keyword">public</span> Guid Id { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Description { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span> IsComplete { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> DateTime DueDate { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> Priority { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> DateTime CreatedAt { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
        <span class="hljs-keyword">public</span> DateTime UpdatedAt { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">Todo</span>(<span class="hljs-params"></span>)</span>
        {
            IsComplete = <span class="hljs-literal">false</span>;
        }
    }
}
</code></pre>
<p>Here's what each part of the <code>Todo</code> model means:</p>
<ul>
<li><strong>Id</strong>: A special number that makes each Todo item unique.</li>
<li><strong>Title</strong>: The name of the Todo item.</li>
<li><strong>Description</strong>: Extra details about the Todo item.</li>
<li><strong>IsComplete</strong>: Whether the Todo item is finished or not.</li>
<li><strong>DueDate</strong>: The date by which the Todo item needs to be done.</li>
<li><strong>Priority</strong>: How important the Todo item is.</li>
<li><strong>CreatedAt</strong> and <strong>UpdatedAt</strong>: When the Todo item was first made and last changed.</li>
</ul>
<p>The <code>[Key]</code> tag tells us that <code>Id</code> is the main way to identify each Todo item in our database.</p>
<p>By having a clear <code>Todo</code> model, we can easily keep track of and display our Todo items in the best way possible.</p>
<p>In ASP.NET Core, models can be used to represent a variety of things. One such use case is error handling. When an error occurs in our application, we can create a model for that error and return it to the client. </p>
<p>Let's create a model specifically for error handling in our application.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Models/ErrorResponse.cs</span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Models</span>
{
       <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">ErrorResponse</span>
 {
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> StatusCode { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Message { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
 }
}
</code></pre>
<p>This ErrorResponse model will be used to return error messages to the client when an error occurs in our application. It includes a title for the error, massage, and a status code, providing the client with useful information about what went wrong.</p>
<p>Let's define another model to manage our database connection string.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Models/DbSettings.cs </span>

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Models</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">DbSettings</span>
    {
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> ConnectionString { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    }
}
</code></pre>
<p>The <code>DbSettings</code> model is designed to encapsulate the connection string for our database. It contains a single property, <code>ConnectionString</code>, which will store the actual connection string value.</p>
<p>With our <code>Todo</code> model in place, we're now ready to proceed with setting up the database context.</p>
<p>Before we begin setting up our database, we need to install the necessary packages for our project.</p>
<h3 id="heading-package-installation">   Package Installation </h3>


<p>To set up our project, we need to install several packages. We'll use the dotnet CLI for this task. </p>
<p>Before we begin, ensure you're in the root directory of your project. If you're unsure of your current location in the terminal, you can verify it by running the following command:</p>
<pre><code class="lang-bash">ls
</code></pre>
<p>This command will list all the files and folders in your current directory. The image below shows the terminal output after running the <code>ls</code> command.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/ls-terminal.png" alt="Terminal ls file" width="600" height="400" loading="lazy"></p>
<p>If your terminal output matches the image above, you're in the correct directory to install the packages.</p>
<p>Now, let's install the packages:</p>
<pre><code class="lang-bash">dotnet add package Microsoft.EntityFrameworkCore --version 8.0.0 
dotnet add package Microsoft.EntityFrameworkCore.Design --version 8.0.0
dotnet add package Microsoft.EntityFrameworkCore.SqlServer --version 8.0.0
dotnet add package AutoMapper --version 13.0.1
</code></pre>
<p>Here's a brief overview of what these packages do:</p>
<ul>
<li><code>Microsoft.EntityFrameworkCore</code>: Provides the core Entity Framework Core functionality, enabling us to interact with our database.</li>
<li><code>Microsoft.EntityFrameworkCore.Design</code>: Includes design-time components for Entity Framework Core, such as migrations.</li>
<li><code>Microsoft.EntityFrameworkCore.SqlServer</code>: Allows us to use SQL Server as our database provider.</li>
<li><code>AutoMapper</code>: Simplifies object-to-object mapping, making it easier to map properties between different objects.</li>
</ul>
<p><strong>Note</strong>: Ensure you install the same versions of the packages as shown above to avoid any compatibility issues.</p>
<p>To confirm that all the packages have been installed successfully, navigate to the <code>TodoAPI.csproj</code> file located in the root directory of your project. The installed packages should be listed under the <code>ItemGroup</code> section.</p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">Project</span> <span class="hljs-attr">Sdk</span>=<span class="hljs-string">"Microsoft.NET.Sdk.Web"</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">PropertyGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">TargetFramework</span>&gt;</span>net8.0<span class="hljs-tag">&lt;/<span class="hljs-name">TargetFramework</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">Nullable</span>&gt;</span>enable<span class="hljs-tag">&lt;/<span class="hljs-name">Nullable</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">ImplicitUsings</span>&gt;</span>enable<span class="hljs-tag">&lt;/<span class="hljs-name">ImplicitUsings</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">InvariantGlobalization</span>&gt;</span>true<span class="hljs-tag">&lt;/<span class="hljs-name">InvariantGlobalization</span>&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">PropertyGroup</span>&gt;</span>

  <span class="hljs-tag">&lt;<span class="hljs-name">ItemGroup</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"AutoMapper"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"13.0.1"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.AspNetCore.OpenApi"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.Design"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.0"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">IncludeAssets</span>&gt;</span>runtime; build; native; contentfiles; analyzers; buildtransitive<span class="hljs-tag">&lt;/<span class="hljs-name">IncludeAssets</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">PrivateAssets</span>&gt;</span>all<span class="hljs-tag">&lt;/<span class="hljs-name">PrivateAssets</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">PackageReference</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Microsoft.EntityFrameworkCore.SqlServer"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"8.0.0"</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">PackageReference</span> <span class="hljs-attr">Include</span>=<span class="hljs-string">"Swashbuckle.AspNetCore"</span> <span class="hljs-attr">Version</span>=<span class="hljs-string">"6.4.0"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">ItemGroup</span>&gt;</span>

<span class="hljs-tag">&lt;/<span class="hljs-name">Project</span>&gt;</span>
</code></pre>
<p>The above <code>TodoAPI.csproj</code> file shows the installed packages listed under the <code>ItemGroup</code> section. If your <code>TodoAPI.csproj</code> file reflects the same, it confirms that the packages have been installed successfully.</p>
<p>With the necessary packages installed, we're now ready to set up the database context for our Todo API.</p>
<h2 id="step-4">  Step 4: Set Up the Database Context  </h2>

<p>In ASP.NET Core, the database context is a crucial component that manages interactions with the database. It's responsible for tasks such as establishing a connection to the database, querying data, and saving changes. </p>
<p>To enable our <code>Todo API</code> to interact with the database, we need to create a database context.</p>
<p>Let's create a new file named <code>TodoDbContext</code> in the <code>AppDataContext</code> folder and populate it with the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// AppDataContext/TodoDbContext.cs</span>

<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> Microsoft.Extensions.Options;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.AppDataContext</span>
{

    <span class="hljs-comment">// TodoDbContext class inherits from DbContext</span>
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TodoDbContext</span> : <span class="hljs-title">DbContext</span>
     {

        <span class="hljs-comment">// DbSettings field to store the connection string</span>
         <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> DbSettings _dbsettings;

            <span class="hljs-comment">// Constructor to inject the DbSettings model</span>
         <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TodoDbContext</span>(<span class="hljs-params">IOptions&lt;DbSettings&gt; dbSettings</span>)</span>
         {
             _dbsettings = dbSettings.Value;
         }


        <span class="hljs-comment">// DbSet property to represent the Todo table</span>
         <span class="hljs-keyword">public</span> DbSet&lt;Todo&gt; Todos { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

         <span class="hljs-comment">// Configuring the database provider and connection string</span>

         <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnConfiguring</span>(<span class="hljs-params">DbContextOptionsBuilder optionsBuilder</span>)</span>
         {
             optionsBuilder.UseSqlServer(_dbsettings.ConnectionString);
         }

            <span class="hljs-comment">// Configuring the model for the Todo entity</span>
         <span class="hljs-function"><span class="hljs-keyword">protected</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">OnModelCreating</span>(<span class="hljs-params">ModelBuilder modelBuilder</span>)</span>
         {
             modelBuilder.Entity&lt;Todo&gt;()
                 .ToTable(<span class="hljs-string">"TodoAPI"</span>)
                 .HasKey(x =&gt; x.id);
         }
     }
}
</code></pre>
<p>Here's a breakdown of the <code>TodoDbContext</code> class:</p>
<ul>
<li><strong><code>TodoDbContext</code></strong>: This class, which inherits from <code>DbContext</code> (a part of Entity Framework Core), is the primary class that interacts with the database.</li>
<li><strong><code>_dbsettings</code></strong>: This private field stores the connection string for our database. We inject the <code>DbSettings</code> model, which we created earlier to manage the connection string, into the <code>TodoDbContext</code> class.</li>
<li><strong><code>Todos</code></strong>: This property represents the <code>Todo</code> table in our database. It's a <code>DbSet</code> of <code>Todo</code> objects, which allows us to query and save instances of <code>Todo</code>.</li>
<li><strong><code>OnConfiguring</code></strong>: This method configures the database provider and connection string. We're using SQL Server as our database provider, and the connection string is retrieved from the <code>DbSettings</code> model.</li>
<li><strong><code>OnModelCreating</code></strong>: This method configures the model for the <code>Todo</code> entity. We specify the table name, primary key, and other configurations for the <code>Todo</code> entity.</li>
</ul>
<p>To use our <code>TodoDbContext</code> for interacting with the database, we need to register it in the <code>Program.cs</code> file. This registration process is part of setting up the Dependency Injection (DI) container in .NET Core.</p>
<p>Here's how to do it:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Program.cs</span>


<span class="hljs-keyword">using</span> TodoAPI.AppDataContext;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();



 <span class="hljs-comment">// Add  This to in the Program.cs file</span>
builder.Services.Configure&lt;DbSettings&gt;(builder.Configuration.GetSection(<span class="hljs-string">"DbSettings"</span>)); <span class="hljs-comment">// Add this line</span>
builder.Services.AddSingleton&lt;TodoDbContext&gt;(); <span class="hljs-comment">// Add this line</span>




<span class="hljs-keyword">var</span> app = builder.Build();

<span class="hljs-comment">// Add this line</span>

{
    <span class="hljs-keyword">using</span> <span class="hljs-keyword">var</span> scope = app.Services.CreateScope(); <span class="hljs-comment">// Add this line</span>
    <span class="hljs-keyword">var</span> context = scope.ServiceProvider; <span class="hljs-comment">// Add this line</span>
}


<span class="hljs-keyword">if</span> (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection();
app.UseExceptionHandler();
app.UseAuthorization();

app.MapControllers();

app.Run();
</code></pre>
<p>In the code snippet above, we're doing two things:</p>
<ul>
<li>Configuring the database settings by binding the <code>DbSettings</code> section from the <code>appsettings.json</code> file to the <code>DbSettings</code> class. This allows us to access the database connection string in our application.</li>
<li>Registering the <code>TodoDbContext</code> with the DI container as a singleton service. This means that a single instance of <code>TodoDbContext</code> will be created and shared across the entire application.</li>
</ul>
<p>With the database context registered, we can now use it to perform CRUD operations on our Todo items.</p>
<p>Now let's check if everything is working fine by running the application.</p>
<pre><code class="lang-bash">
dotnet run
</code></pre>
<p>If you see the following output, it means your application is running successfully:</p>
<pre><code class="lang-bash">
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5086
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
Content root path: E:\Todo\TodoAPI
</code></pre>
<p><strong>Note</strong>: If you encounter any errors, just make sure you've followed all the steps correctly and that the necessary packages have been installed successfully. If you see some warnings, you can ignore them for now.</p>
<p>With the <code>TodoDbContext</code> class now set up, we're ready to define the Contracts  for our application.</p>
<h2 id="step-5">  Step 5: Define Data Transfer Objects (DTOs) </h2>

<p>In the context of .NET development, a Data Transfer Object (DTO) is a simple object that carries data between processes. It's often used in conjunction with a service layer to shape the data sent between the client and the server. </p>
<p>For our Todo API, we'll define two DTOs: <code>CreateTodoRequest</code> and <code>UpdateTodoRequest</code>. These DTOs will help us enforce the structure and validation of the data sent to our API.</p>
<p>Navigate to the <code>Contracts</code> folder and create two new files: <code>CreateTodoRequest.cs</code> and <code>UpdateTodoRequest.cs</code>.</p>
<h3 id="heading-the-createtodorequest-file"> The <code>CreateTodoRequest</code> File </h3>


<p>The <code>CreateTodoRequest</code> DTO will define the structure and validation rules for creating a new Todo item. Add the following code to the <code>CreateTodoRequest.cs</code> file:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">CreateTodoRequest</span>
{
    [<span class="hljs-meta">Required</span>]
    [<span class="hljs-meta">StringLength(100)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    [<span class="hljs-meta">StringLength(500)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Description { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    [<span class="hljs-meta">Required</span>]
    <span class="hljs-keyword">public</span> DateTime DueDate { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    [<span class="hljs-meta">Range(1, 5)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> Priority { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
}
</code></pre>
<p>In this DTO, we've defined properties for <code>Title</code>, <code>Description</code>, <code>DueDate</code>, and <code>Priority</code>. We've also added validation attributes like <code>[Required]</code>, <code>[StringLength]</code>, and <code>[Range]</code> to enforce certain rules on these properties.</p>
<h3 id="heading-the-updatetodorequest-file"> The <code>UpdateTodoRequest</code> File </h3>


<p>The <code>UpdateTodoRequest</code> DTO will define the structure and validation rules for updating an existing Todo item. Add the following code to the <code>UpdateTodoRequest.cs</code> file:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">UpdateTodoRequest</span>
{
    [<span class="hljs-meta">StringLength(100)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Title { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    [<span class="hljs-meta">StringLength(500)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Description { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">bool</span>? IsComplete { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-keyword">public</span> DateTime? DueDate { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    [<span class="hljs-meta">Range(1, 5)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span>? Priority { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">UpdateTodoRequest</span>(<span class="hljs-params"></span>)</span>
    {
        IsComplete = <span class="hljs-literal">false</span>;
    }
}
</code></pre>
<p>In this DTO, we've defined properties for <code>Title</code>, <code>Description</code>, <code>IsComplete</code>, <code>DueDate</code>, and <code>Priority</code>. The <code>IsComplete</code> property is nullable, which means it can be set to <code>null</code> if not provided. We've also added validation attributes like <code>[StringLength]</code> and <code>[Range]</code> to enforce certain rules on these properties.</p>
<p>With these DTOs in place, we're now ready to implement the service layer for our Todo API.</p>
<p>Now test the application, and see if there are any errors.</p>
<pre><code class="lang-bash">
 dotnet  build
</code></pre>
<p>If you see the following output, it means your application is running successfully:</p>
<pre><code class="lang-bash">MSBuild version 17.8.3+195e7f5a3 <span class="hljs-keyword">for</span> .NET
  Determining projects to restore...
  All projects are up-to-date <span class="hljs-keyword">for</span> restore.
  TodoAPI -&gt; E:\Todo\TodoAPI\bin\Debug\net8.0\TodoAPI.dll

Build succeeded.
    0 Warning(s)
    0 Error(s)

Time Elapsed 00:00:00.94
</code></pre>
<p><strong>Note</strong>: If you encounter any errors, make sure you've followed all the steps correctly and that the necessary packages have been installed successfully. If you see some warnings, you can ignore them for now.</p>
<p>With the DTOs defined, we're now ready to implement the Mapping for the   Todo API.</p>
<h2 id="step-6">  Step 6: Implement Object Mapping for the Todo API </h2>

<p>Having defined the DTOs for our Todo API, the next step is to implement object mapping. This process allows us to convert between the DTOs and the Todo model, a critical aspect of data transformation in our application.</p>
<p>To streamline this process, we'll use the <code>AutoMapper</code> library. AutoMapper is a widely-used library that simplifies object-to-object mapping, making it easier to map properties between different objects.</p>
<p>We've already installed the <code>AutoMapper</code> package in our project. Now, in the <code>MappingProfiles</code> folder, create a new file named <code>AutoMapperProfile.cs</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">using</span> AutoMapper;
<span class="hljs-keyword">using</span> TodoAPI.Contracts;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.MappingProfiles</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AutoMapperProfile</span> : <span class="hljs-title">Profile</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">AutoMapperProfile</span>(<span class="hljs-params"></span>)</span>
        {
            CreateMap&lt;CreateTodoRequest, Todo&gt;()
                .ForMember(dest =&gt; dest.id, opt =&gt; opt.Ignore())
                .ForMember(dest =&gt; dest.CreatedAt, opt =&gt; opt.Ignore())
                .ForMember(dest =&gt; dest.UpdatedAt, opt =&gt; opt.Ignore());

            CreateMap&lt;UpdateTodoRequest, Todo&gt;()
                .ForMember(dest =&gt; dest.id, opt =&gt; opt.Ignore())
                .ForMember(dest =&gt; dest.CreatedAt, opt =&gt; opt.Ignore())
                .ForMember(dest =&gt; dest.UpdatedAt, opt =&gt; opt.Ignore());
        }
    }
}
</code></pre>
<p>Let's break down the <code>AutoMapperProfile</code> class:</p>
<ul>
<li><strong>AutoMapperProfile</strong>: This class, which inherits from <code>Profile</code> (a class provided by AutoMapper), allows us to define mapping configurations.</li>
<li><strong>CreateMap</strong>: This method creates a mapping between two objects. Here, we're mapping from <code>CreateTodoRequest</code> to <code>Todo</code> and from <code>UpdateTodoRequest</code> to <code>Todo</code>.</li>
<li><strong>ForMember</strong>: This method configures the mapping for a specific property. We're using it to ignore the <code>id</code>, <code>CreatedAt</code>, and <code>UpdatedAt</code> properties when mapping from the DTOs to the <code>Todo</code> model.</li>
</ul>
<p>Now let's add the automapper to the DI container in the <code>Program.cs</code> file.</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Program.cs</span>

<span class="hljs-keyword">using</span> TodoAPI.AppDataContext;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);

builder.Services.AddControllers();

builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();



 <span class="hljs-comment">// Add  This to in the Program.cs file</span>
builder.Services.AddAutoMapper(AppDomain.CurrentDomain.GetAssemblies());  <span class="hljs-comment">// Add this line</span>


<span class="hljs-comment">// .....</span>

<span class="hljs-keyword">var</span> app = builder.Build();



<span class="hljs-comment">// .....</span>
<span class="hljs-keyword">if</span> (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseExceptionHandler();
app.UseAuthorization();

app.MapControllers();

app.Run();
</code></pre>
<p>With the mapping profiles in place, we can now implement the service layer for our Todo API.</p>
<h2 id="step-7"> Step 7: Implement Global Exception Handling Middleware </h2>

<p>As we progress with our Todo API, it's crucial to implement a mechanism for handling exceptions globally. This ensures that any exceptions that occur during the execution of our application are caught and handled appropriately, providing meaningful error messages to the client.</p>
<p>.NET 8 introduces the <code>IExceptionHandler</code> interface, which simplifies the process of creating a custom exception handler. This handler will catch all exceptions that occur in our application and return a consistent error response to the client.</p>
<p>Let's create a global exception handler in the <code>Middleware</code> folder. Create a new file named <code>GlobalExceptionHandler.cs</code> and add the following code:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Middleware/GlobalExceptionHandler.cs</span>

<span class="hljs-keyword">using</span> System.Net;
<span class="hljs-keyword">using</span> Microsoft.AspNetCore.Diagnostics;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Middleware</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">GlobalExceptionHandler</span> : <span class="hljs-title">IExceptionHandler</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;GlobalExceptionHandler&gt; _logger;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">GlobalExceptionHandler</span>(<span class="hljs-params">ILogger&lt;GlobalExceptionHandler&gt; logger</span>)</span>
        {
            _logger = logger;
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> ValueTask&lt;<span class="hljs-keyword">bool</span>&gt; <span class="hljs-title">TryHandleAsync</span>(<span class="hljs-params">
            HttpContext httpContext,
            Exception exception,
            CancellationToken cancellationToken</span>)</span>
        {
            _logger.LogError(
                <span class="hljs-string">$"An error occurred while processing your request: <span class="hljs-subst">{exception.Message}</span>"</span>);

            <span class="hljs-keyword">var</span> errorResponse = <span class="hljs-keyword">new</span> ErrorResponse
            {
                Message = exception.Message
            };

            <span class="hljs-keyword">switch</span> (exception)
            {
                <span class="hljs-keyword">case</span> BadHttpRequestException:
                    errorResponse.StatusCode = (<span class="hljs-keyword">int</span>)HttpStatusCode.BadRequest;
                    errorResponse.Title = exception.GetType().Name;
                    <span class="hljs-keyword">break</span>;

                <span class="hljs-keyword">default</span>:
                    errorResponse.StatusCode = (<span class="hljs-keyword">int</span>)HttpStatusCode.InternalServerError;
                    errorResponse.Title = <span class="hljs-string">"Internal Server Error"</span>;
                    <span class="hljs-keyword">break</span>;
            }

            httpContext.Response.StatusCode = errorResponse.StatusCode;

            <span class="hljs-keyword">await</span> httpContext
                .Response
                .WriteAsJsonAsync(errorResponse, cancellationToken);

            <span class="hljs-keyword">return</span> <span class="hljs-literal">true</span>;
        }
    }
}
</code></pre>
<p>Here's a breakdown of the <code>GlobalExceptionHandler</code> class:</p>
<ul>
<li><strong>GlobalExceptionHandler</strong>: This class implements the <code>IExceptionHandler</code> interface, enabling global exception handling in our application.</li>
<li><strong>TryHandleAsync</strong>: This method is invoked when an exception occurs. It logs the error message, creates an <code>ErrorResponse</code> object, sets the status code and title based on the exception type, and returns a consistent error response to the client.</li>
<li><strong>ErrorResponse</strong>: This class represents the error response returned to the client when an exception occurs. It contains properties for the error message, status code, and title.</li>
<li><strong>BadHttpRequestException</strong>: This case handles exceptions of type <code>BadHttpRequestException</code> and sets the status code and title accordingly.</li>
</ul>
<p>After setting up the global exception handler, we need to register it in our <code>Program.cs</code> file:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Program.cs</span>

<span class="hljs-keyword">using</span> TodoAPI.AppDataContext;
<span class="hljs-keyword">using</span> TodoAPI.Interface;
<span class="hljs-keyword">using</span> TodoAPI.Middleware;
<span class="hljs-keyword">using</span> TodoAPI.Models;
<span class="hljs-keyword">using</span> TodoAPI.Services;

<span class="hljs-keyword">var</span> builder = WebApplication.CreateBuilder(args);



builder.Services.AddControllers();
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();



<span class="hljs-comment">// ....</span>



builder.Services.AddExceptionHandler&lt;GlobalExceptionHandler&gt;(); <span class="hljs-comment">// Add this line</span>

builder.Services.AddProblemDetails();  <span class="hljs-comment">// Add this line</span>

<span class="hljs-comment">// Adding of login </span>
builder.Services.AddLogging();  <span class="hljs-comment">//  Add this line</span>



<span class="hljs-keyword">var</span> app = builder.Build();


<span class="hljs-comment">// ......</span>


<span class="hljs-keyword">if</span> (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseHttpsRedirection(); <span class="hljs-comment">// Add this line</span>

app.UseExceptionHandler();
app.UseAuthorization();

app.MapControllers();

app.Run();


<span class="hljs-comment">// ...</span>
</code></pre>
<h2 id="step-8"> Step 8: Implement the Service Layer and Service Interface </h2>

<p>In .NET development, the service layer encapsulates the core business logic of an application. It serves as a bridge between the controller and the database, ensuring a clean separation of concerns.</p>
<p>First, let's define an interface for our service layer.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Interfaces/ITodoServices.cs </span>

<span class="hljs-keyword">using</span> TodoAPI.Contracts;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Interface</span>
{
     <span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">ITodoServices</span>
     {
         Task&lt;IEnumerable&lt;Todo&gt;&gt; GetAllAsync();
         <span class="hljs-function">Task&lt;Todo&gt; <span class="hljs-title">GetByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>;
         <span class="hljs-function">Task <span class="hljs-title">CreateTodoAsync</span>(<span class="hljs-params">CreateTodoRequest request</span>)</span>;
         <span class="hljs-function">Task <span class="hljs-title">UpdateTodoAsync</span>(<span class="hljs-params">Guid id, UpdateTodoRequest request</span>)</span>;
         <span class="hljs-function">Task <span class="hljs-title">DeleteTodoAsync</span>(<span class="hljs-params">Guid id</span>)</span>;
     }
}
</code></pre>
<p>Here's a brief overview of the methods defined in the <code>ITodoServices</code> interface:</p>
<ul>
<li><code>GetAllAsync</code>: Retrieves all Todo items from the database.</li>
<li><code>GetByIdAsync</code>: Fetches a specific Todo item by its <code>Id</code>.</li>
<li><code>CreateTodoAsync</code>: Adds a new Todo item to the database.</li>
<li><code>UpdateTodoAsync</code>: Modifies an existing Todo item in the database.</li>
<li><code>DeleteTodoAsync</code>: Removes a Todo item from the database.</li>
</ul>
<p>Now, let's create a service class that implements these methods. We'll use Dependency Injection to inject the <code>ITodoServices</code> interface into the service class, making our code more modular, testable, and maintainable.</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-keyword">using</span> TodoAPI.Interface;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TodoServices</span> : <span class="hljs-title">ITodoServices</span>
    {

    }
}
</code></pre>
<p>At this point, you'll encounter an error because we haven't implemented the methods from the <code>ITodoServices</code> interface in the <code>TodoServices</code> class. </p>
<p>The below image shows the error message that appears when the methods from the <code>ITodoServices</code> interface are not implemented in the <code>TodoServices</code> class.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/InterfaceError.png" alt="Error in the TodoServices class" width="600" height="400" loading="lazy"></p>
<p>To resolve this, hover over <code>ITodoServices</code>, click on the light bulb icon that appears, and select 'Implement interface'. This will automatically generate stubs for the methods defined in the <code>ITodoServices</code> interface.</p>
<p>The below image shows the 'Implement interface' option that appears when hovering over <code>ITodoServices</code> in the <code>TodoServices</code> class.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/QickFixt.png" alt="Implementing the ITodoServices interface" width="600" height="400" loading="lazy"></p>
<p>After implementing the interface, the <code>TodoServices</code> class should look like this:</p>
<pre><code class="lang-csharp">

<span class="hljs-comment">// Services/TodoServices.cs</span>
<span class="hljs-keyword">using</span> TodoAPI.Contracts;
<span class="hljs-keyword">using</span> TodoAPI.Interface;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TodoServices</span> : <span class="hljs-title">ITodoServices</span>
    {
        <span class="hljs-function"><span class="hljs-keyword">public</span> Task <span class="hljs-title">CreateTodoAsync</span>(<span class="hljs-params">CreateTodoRequest request</span>)</span>
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> Task <span class="hljs-title">DeleteTodoAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-keyword">public</span> Task&lt;IEnumerable&lt;Todo&gt;&gt; GetAllAsync()
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> Task&lt;Todo&gt; <span class="hljs-title">GetByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> Task <span class="hljs-title">UpdateTodoAsync</span>(<span class="hljs-params">Guid id, UpdateTodoRequest request</span>)</span>
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }
    }
}
</code></pre>
<h3 id="heading-how-to-enhance-the-todoservices-class-with-dependency-injection"> How to Enhance the TodoServices Class with Dependency Injection </h3>

<p>Now, let's enrich our <code>TodoServices</code> class with some essential properties. These properties will provide the necessary tools for interacting with the database, logging, and object mapping.</p>
<p>At the top of the <code>TodoServices</code> class, add the following properties:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-comment">// ...</span>

<span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> TodoDbContext _context;
<span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;TodoServices&gt; _logger;
<span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> IMapper _mapper;

<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a brief explanation of these properties:</p>
<ul>
<li><code>_context</code>: An instance of the <code>TodoDbContext</code> class, enabling us to interact with the database.</li>
<li><code>_logger</code>: An instance of the <code>ILogger</code> class, facilitating logging throughout our application.</li>
<li><code>_mapper</code>: An instance of the <code>IMapper</code> class, allowing us to perform object-to-object mapping using AutoMapper.</li>
</ul>
<p>Next, we'll update the constructor of the <code>TodoServices</code> class to inject these dependencies:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-comment">// ...</span>

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TodoServices</span>(<span class="hljs-params">TodoDbContext context, ILogger&lt;TodoServices&gt; logger, IMapper mapper</span>)</span>
{
    _context = context;
    _logger = logger;
    _mapper = mapper;
}

<span class="hljs-comment">// ...</span>
</code></pre>
<p>With these dependencies injected, we're now ready to implement the methods defined in the <code>ITodoServices</code> interface. We'll begin with the <code>GetAllAsync</code> method in the next section.</p>
<h2 id="step-9"> Step 9: Implement the CreateTodoAsync Method in the TodoServices Class </h2>

<p>Now, let's implement the <code>CreateTodoAsync</code> method in the <code>TodoServices</code> class. This method will handle the creation of new Todo items in our database.</p>
<p>Navigate to the <code>TodoServices</code> class and add the following code to the <code>CreateTodoAsync</code> method:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-comment">// ...</span>

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">CreateTodoAsync</span>(<span class="hljs-params">CreateTodoRequest request</span>)</span>
{
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-keyword">var</span> todo = _mapper.Map&lt;Todo&gt;(request);
        todo.CreatedAt = DateTime.UtcNow;
        _context.Todos.Add(todo);
        <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
    }
    <span class="hljs-keyword">catch</span> (Exception ex)
    {
        _logger.LogError(ex, <span class="hljs-string">"An error occurred while creating the Todo item."</span>);
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">"An error occurred while creating the Todo item."</span>);
    }
}

<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a breakdown of the <code>CreateTodoAsync</code> method:</p>
<ul>
<li><strong>Mapping</strong>: We use AutoMapper to convert the <code>CreateTodoRequest</code> object into a <code>Todo</code> entity.</li>
<li><strong>CreatedAt</strong>: We set the <code>CreatedAt</code> property of the <code>Todo</code> entity to the current UTC date and time.</li>
<li><strong>Adding to the Database</strong>: We add the <code>Todo</code> entity to the <code>Todos</code> DbSet in our context and save the changes asynchronously.</li>
<li><strong>Error Handling</strong>: We catch any exceptions that might occur during the process, log the error, and throw a new exception with a descriptive error message.</li>
</ul>
<p>With the <code>CreateTodoAsync</code> method implemented, we can now create new Todo items in our database.</p>
<h2 id="step-10"> Step 10: Implement the GetAllAsync Method in the Service Class </h2>

<p>Next, let's implement the <code>GetAllAsync</code> method in the <code>TodoServices</code> class. This method will retrieve all Todo items from the database.</p>
<p>Navigate to the <code>TodoServices</code> class and add the following code to the <code>GetAllAsync</code> method:</p>
<pre><code class="lang-csharp">

<span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-comment">// ...</span>


 <span class="hljs-comment">// Get all TODO Items from the database </span>
 <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IEnumerable&lt;Todo&gt;&gt; GetAllAsync()
 {
     <span class="hljs-keyword">var</span> todo= <span class="hljs-keyword">await</span> _context.Todos.ToListAsync();
     <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
     {
         <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">" No Todo items found"</span>);
     }
     <span class="hljs-keyword">return</span> todo;

 }

<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a breakdown of the <code>GetAllAsync</code> method:</p>
<ul>
<li><p><strong>Retrieving Todo Items</strong>: We use Entity Framework Core's <code>ToListAsync</code> method to fetch all Todo items from the database.</p>
</li>
<li><p><strong>Error Handling</strong>: If no Todo items are found, we throw an exception with a descriptive error message.</p>
</li>
</ul>
<p>Now Your Service class should look like this:</p>
<pre><code class="lang-csharp">


<span class="hljs-keyword">using</span> AutoMapper;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> TodoAPI.AppDataContext;
<span class="hljs-keyword">using</span> TodoAPI.Contracts;
<span class="hljs-keyword">using</span> TodoAPI.Interface;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TodoServices</span> : <span class="hljs-title">ITodoServices</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> TodoDbContext _context;
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;TodoServices&gt; _logger;
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> IMapper _mapper;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TodoServices</span>(<span class="hljs-params">TodoDbContext context, ILogger&lt;TodoServices&gt; logger, IMapper mapper</span>)</span>
        {
            _context = context;
            _logger = logger;
            _mapper = mapper;
        }




        <span class="hljs-comment">//  Create Todo for it be save in the datbase </span>

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">CreateTodoAsync</span>(<span class="hljs-params">CreateTodoRequest request</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">var</span> todo = _mapper.Map&lt;Todo&gt;(request);
                todo.CreatedAt = DateTime.Now;
                _context.Todos.Add(todo);
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(ex, <span class="hljs-string">"An error occurred while creating the todo item."</span>);
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">"An error occurred while creating the todo item."</span>);
            }
        }

        <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IEnumerable&lt;Todo&gt;&gt; GetAllAsync()
        {
            <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _context.Todos.ToListAsync();
            <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
            {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">" No Todo items found"</span>);
            }
            <span class="hljs-keyword">return</span> todo;

        }
        <span class="hljs-function"><span class="hljs-keyword">public</span> Task <span class="hljs-title">DeleteTodoAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-comment">// Get all TODO Items from the database </span>


        <span class="hljs-function"><span class="hljs-keyword">public</span> Task&lt;Todo&gt; <span class="hljs-title">GetByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> Task <span class="hljs-title">UpdateTodoAsync</span>(<span class="hljs-params">Guid id, UpdateTodoRequest request</span>)</span>
        {
            <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> NotImplementedException();
        }
    }
}
</code></pre>
<p>Now we have implemented the <code>CreateTodoAsync</code> and <code>GetAllAsync</code> methods in the <code>TodoServices</code> class. Before we proceed to implement the remaining methods, let's create routes for our API in the Controllers folder. So now let's create the TodoController class.</p>
<h2 id="step-11"> Step 11: Create the TodoController Class  </h2>

<p>In ASP.NET Core, controllers are responsible for handling incoming HTTP requests and sending responses. They serve as the entry point for our API, defining the routes and actions that clients can interact with.</p>
<p>Let's create a new file named <code>TodoController.cs</code> in the <code>Controllers</code> folder and add the following code:</p>
<pre><code class="lang-csharp">

<span class="hljs-keyword">using</span> Microsoft.AspNetCore.Mvc;
<span class="hljs-keyword">using</span> TodoAPI.Interface;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Controllers</span>
{
    [<span class="hljs-meta">ApiController</span>]
    [<span class="hljs-meta">Route(<span class="hljs-meta-string">"api/[controller]"</span>)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TodoController</span> : <span class="hljs-title">ControllerBase</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ITodoServices _todoServices;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TodoController</span>(<span class="hljs-params">ITodoServices todoServices</span>)</span>
        {
            _todoServices = todoServices;
        }

    }
}
</code></pre>
<p>The <code>TodoController</code> class inherits from <code>ControllerBase</code>, a base class provided by ASP.NET Core for creating controllers. We've also added a route prefix of <code>api/[controller]</code> to the controller, which will be used as the base route for all actions in the controller.</p>
<h2 id="step-12"> Step 12: Implement the CreateTodoAsync  Method in the TodoController Class  </h2>

<p>Now that we have our Controller class, let's implement the <code>CreateTodoAsync</code> method in the <code>TodoController</code> class. This method will handle the creation of new Todo items in our database.</p>
<p>Navigate to the <code>TodoController</code> class and add the following code to the <code>CreateTodoAsync</code> method:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Controllers/TodoController.cs</span>

<span class="hljs-comment">// ...</span>
  [<span class="hljs-meta">HttpPost</span>]
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">CreateTodoAsync</span>(<span class="hljs-params">CreateTodoRequest request</span>)</span>
  {
      <span class="hljs-keyword">if</span> (!ModelState.IsValid)
      {
          <span class="hljs-keyword">return</span> BadRequest(ModelState);
      }


      <span class="hljs-keyword">try</span>
      {

          <span class="hljs-keyword">await</span> _todoServices.CreateTodoAsync(request);
          <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"Blog post successfully created"</span> });

      }
      <span class="hljs-keyword">catch</span> (Exception ex)
      {
          <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">"An error occurred while creating the  crating Todo Item"</span>, error = ex.Message });

      }
  }
  <span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a breakdown of the <code>CreateTodoAsync</code> method:</p>
<ul>
<li><p><strong>Model Validation</strong>: We check if the request model is valid using <code>ModelState.IsValid</code>. If the model is not valid, we return a <code>BadRequest</code> response with the model state errors.</p>
</li>
<li><p><strong>Creating a Todo Item</strong>: We call the <code>CreateTodoAsync</code> method from the <code>ITodoServices</code> interface to create a new Todo item in the database.</p>
</li>
<li><p><strong>Success Response</strong>: If the Todo item is created successfully, we return an <code>Ok</code> response with a success message.</p>
</li>
<li><p><strong>Error Handling</strong>: If an error occurs during the creation process, we return a <code>500 Internal Server Error</code> response with an error message.</p>
</li>
</ul>
<p>Now let's implement the <code>GetAllAsync</code> method in the <code>TodoController</code> class. This method will retrieve all Todo items from the database.</p>
<p>Navigate to the <code>TodoController</code> class and add the following code to the <code>GetAllAsync</code> method:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Controllers/TodoController.cs </span>

<span class="hljs-comment">// ...</span>

  [<span class="hljs-meta">HttpGet</span>]
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">GetAllAsync</span>(<span class="hljs-params"></span>)</span>
  {
      <span class="hljs-keyword">try</span>
      {
          <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _todoServices.GetAllAsync();
          <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span> || !todo.Any())
          {
              <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"No Todo Items  found"</span> });
          }
          <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"Successfully retrieved all blog posts"</span>, data = todo });

      }
      <span class="hljs-keyword">catch</span> (Exception ex)
      {
          <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">"An error occurred while retrieving all Tood it posts"</span>, error = ex.Message });


      }
  }

<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a breakdown of the <code>GetAllAsync</code> method:</p>
<ul>
<li><p><strong>Retrieving Todo Items</strong>: We call the <code>GetAllAsync</code> method from the <code>ITodoServices</code> interface to fetch all Todo items from the database.</p>
</li>
<li><p><strong>Success Response</strong>: If Todo items are retrieved successfully, we return an <code>Ok</code> response with a success message and the list of Todo items.</p>
</li>
<li><p><strong>Error Handling</strong>: If an error occurs during the retrieval process, we return a <code>500 Internal Server Error</code> response with an error message.</p>
</li>
</ul>
<p>Now your <code>TodoController</code> class should look like this:</p>
<pre><code class="lang-csharp">


<span class="hljs-keyword">using</span> Microsoft.AspNetCore.Mvc;
<span class="hljs-keyword">using</span> TodoAPI.Contracts;
<span class="hljs-keyword">using</span> TodoAPI.Interface;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Controllers</span>
{
    [<span class="hljs-meta">ApiController</span>]
    [<span class="hljs-meta">Route(<span class="hljs-meta-string">"api/[controller]"</span>)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TodoController</span> : <span class="hljs-title">ControllerBase</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ITodoServices _todoServices;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TodoController</span>(<span class="hljs-params">ITodoServices todoServices</span>)</span>
        {
            _todoServices = todoServices;
        }



<span class="hljs-comment">// Creating new Todo Item</span>
[<span class="hljs-meta">HttpPost</span>]
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">CreateTodoAsync</span>(<span class="hljs-params">CreateTodoRequest request</span>)</span>
  {
      <span class="hljs-keyword">if</span> (!ModelState.IsValid)
      {
          <span class="hljs-keyword">return</span> BadRequest(ModelState);
      }


      <span class="hljs-keyword">try</span>
      {

          <span class="hljs-keyword">await</span> _todoServices.CreateTodoAsync(request);
          <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"Blog post successfully created"</span> });

      }
      <span class="hljs-keyword">catch</span> (Exception ex)
      {
          <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">"An error occurred while creating the  crating Todo Item"</span>, error = ex.Message });

      }
  }

    <span class="hljs-comment">// Get all Todo Items</span>

      [<span class="hljs-meta">HttpGet</span>]
  <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">GetAllAsync</span>(<span class="hljs-params"></span>)</span>
  {
      <span class="hljs-keyword">try</span>
      {
          <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _todoServices.GetAllAsync();
          <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span> || !todo.Any())
          {
              <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"No Todo Items  found"</span> });
          }
          <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"Successfully retrieved all blog posts"</span>, data = todo });

      }
      <span class="hljs-keyword">catch</span> (Exception ex)
      {
          <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">"An error occurred while retrieving all Tood it posts"</span>, error = ex.Message });


      }
  }

    }
}
</code></pre>
<p>At this point, we've implemented the <code>CreateTodoAsync</code> and <code>GetAllAsync</code> methods in the <code>TodoController</code> class. These methods allow us to create new Todo items and retrieve all Todo items from the database. Let's try to run the application and see if everything is working fine.</p>
<p>Run the application by running the following command:</p>
<pre><code class="lang-bash">

dotnet run
</code></pre>
<p>If you see the following output, it means your application is running successfully:</p>
<pre><code class="lang-bash">
info: Microsoft.Hosting.Lifetime[14]
      Now listening on: http://localhost:5086
info: Microsoft.Hosting.Lifetime[0]
      Application started. Press Ctrl+C to shut down.
info: Microsoft.Hosting.Lifetime[0]
      Hosting environment: Development
info: Microsoft.Hosting.Lifetime[0]
      Content root path: E:\Todo\TodoAPI4
</code></pre>
<p>While we'll be using Postman within Visual Studio Code for making API requests, it's worth noting that .NET 8 includes a built-in Swagger UI. This feature allows us to interact with our API endpoints directly from a web browser. To access the Swagger UI, open your browser and navigate to <code>https://localhost:5086/swagger/index.html</code>. You should see a page similar to the one below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/SwaggerUI.png" alt="SwaggerUI" width="600" height="400" loading="lazy">
This indicates that we've made significant progress. We've created an API that can create and retrieve Todo items. Let's test this by attempting to create a new Todo item using our API.</p>
<p>Open Postman and create a new POST request with the following URL: <code>https://localhost:5086/api/todo</code>. Set the request body to the following JSON object:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Learn ASP.NET Core"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Learn how to build web applications with ASP.NET Core"</span>,
    <span class="hljs-attr">"dueDate"</span>: <span class="hljs-string">"2022-12-31T00:00:00"</span>,
    <span class="hljs-attr">"priority"</span>: <span class="hljs-number">5</span>
}
</code></pre>
<p>Upon executing this request, you may encounter an error. This is because we haven't yet added our connection string to the <code>appsettings.json</code> file. Let's rectify this.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/PostmanError.png" alt="PostmanError" width="600" height="400" loading="lazy"></p>
<p><strong>Note</strong>: The error above is due to the absence of a connection string in the <code>appsettings.json</code> file. Let's add the connection string to the <code>appsettings.json</code> file.</p>
<p>Before we do that, let's setup or SQL Server Database. First Open your SQL Server Management Studio and you should see the below screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/SQLServerManagementStudio.png" alt="SQLServerManagementStudio" width="600" height="400" loading="lazy"></p>
<p>To connect to the SQL Server, where is says <code>Server Name</code> you can type <code>localhost</code> or <code>.</code> and click on the <code>Connect</code> button.</p>
<p>After connecting to the SQL Server, you will see the following screen:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/SQLServerManagementStudio2.png" alt="SQLServerManagementStudio2" width="600" height="400" loading="lazy"></p>
<p>Now go to your <code>appsettings.json</code> file and add the following connection string:</p>
<pre><code class="lang-json">
<span class="hljs-comment">//appsettings.json</span>
{
  <span class="hljs-attr">"DbSettings"</span>: {
    <span class="hljs-attr">"ConnectionString"</span>: <span class="hljs-string">"Server=localhost;Database=TodoAPIDb;  Integrated Security=true;  TrustServerCertificate=true;"</span>
  },
  <span class="hljs-attr">"Logging"</span>: {
    <span class="hljs-attr">"LogLevel"</span>: {
      <span class="hljs-attr">"Default"</span>: <span class="hljs-string">"Information"</span>,
      <span class="hljs-attr">"Microsoft"</span>: <span class="hljs-string">"Warning"</span>,
      <span class="hljs-attr">"Microsoft.Hosting.Lifetime"</span>: <span class="hljs-string">"Information"</span>
    },
    <span class="hljs-attr">"AllowedHosts"</span>: <span class="hljs-string">"*"</span>
  }
}
</code></pre>
<p>Let me explain the connection string above:</p>
<ul>
<li><code>Server</code>: This is the server name where the database is hosted. In this case, we're using <code>localhost</code> to connect to the local SQL Server instance.</li>
<li><code>Database</code>: This is the name of the database we want to connect to. We've set it to <code>TodoAPIDb</code>.</li>
<li><code>Integrated Security</code>: This parameter specifies that we're using Windows authentication to connect to the database.</li>
<li><code>TrustServerCertificate</code>: This parameter specifies that we trust the server certificate when connecting to the database.</li>
</ul>
<p>Now we need to register our <code>Service</code> and <code>Iservices</code> in the <code>Program.cs</code> file.</p>
<p>Add the service to the <code>Program.cs</code> file:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Program.cs</span>

<span class="hljs-comment">// ...</span>

builder.Services.AddScoped&lt;ITodoServices, TodoServices&gt;();

<span class="hljs-comment">// ...</span>
</code></pre>
<h2 id="step-13"> Step 13: Implement Migrations and Update the Database  </h2>

<p>Migrations in Entity Framework Core provide a mechanism to keep the database schema in sync with the application's data model. They generate SQL scripts that can be applied to the database to reflect changes in the data model, eliminating the need for manual database schema updates.</p>
<p>To create a migration, ensure you're in the root directory of your project and run the following command in the terminal:</p>
<pre><code class="lang-bash">dotnet ef migrations add InitialCreate
</code></pre>
<p>Upon successful execution, you'll see an output similar to the following:</p>
<pre><code class="lang-bash">dotnet ef migrations add InitialCreate
Build started...
Build succeeded.
Done. To undo this action, use <span class="hljs-string">'ef migrations remove'</span>
</code></pre>
<p>This command generates a new migration named <code>InitialCreate</code>, which contains SQL scripts derived from the changes in our data model. A new folder named <code>Migrations</code> will appear in your project directory.</p>
<p>To apply the migration and update the database, execute the following command:</p>
<pre><code class="lang-bash">dotnet ef database update
</code></pre>
<p>You might encounter an error like this:</p>
<pre><code class="lang-bash">  at Microsoft.EntityFrameworkCore.Design.OperationExecutor.UpdateDatabase.&lt;&gt;c__DisplayClass0_0.&lt;.ctor&gt;b__0()
   at Microsoft.EntityFrameworkCore.Design.OperationExecutor.OperationBase.Execute(Action action)
Only the invariant culture is supported <span class="hljs-keyword">in</span> globalization-invariant mode. See https://aka.ms/GlobalizationInvariantMode <span class="hljs-keyword">for</span> more information. (Parameter <span class="hljs-string">'name'</span>)
en-us is an invalid culture identifier.
</code></pre>
<p>This error indicates that the <code>en-us</code> culture is not supported in globalization-invariant mode. To resolve this, open the <code>TodoAPI.csproj</code> file and change <code>&lt;InvariantGlobalization&gt;true&lt;/InvariantGlobalization&gt;</code> to <code>&lt;InvariantGlobalization&gt;false&lt;/InvariantGlobalization&gt;</code>.</p>
<p>After making this change, run the <code>dotnet ef database update</code> command again. If the migration is successful, you'll see an output similar to the following:</p>
<pre><code class="lang-bash">
Build started...
Build succeeded.
Applying migration <span class="hljs-string">'20240518180222_InitialCreate'</span>.
Done.
</code></pre>
<p>This indicates that the migration has been applied successfully, and the database has been updated with the necessary schema changes.</p>
<p>Congratulations! You've successfully created a migration and updated the database schema. Now, let's test our API by creating a new Todo item using Postman.</p>
<h2 id="step-14">  Step 14: Verify Your API with Postman  </h2>

<p>Before we can interact with our API, we need to ensure that our application is up and running. Start the application by executing the following command in the terminal:</p>
<pre><code class="lang-bash">dotnet run
</code></pre>
<p>With the application running, we can now use Postman to send requests to our API. Let's create a new Todo item:</p>
<ol>
<li>Open Postman and create a new request.</li>
<li>Set the request method to <code>POST</code>.</li>
<li>Enter the following URL: <code>https://localhost:5086/api/todo</code>.</li>
<li>In the <code>Headers</code> tab, set the <code>Content-Type</code> to <code>application/json</code>.</li>
<li>In the <code>Body</code> tab, select <code>raw</code> and enter the following JSON object:</li>
</ol>
<pre><code class="lang-json">{
    <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Learn ASP.NET Core"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Learn how to build web applications with ASP.NET Core"</span>,
    <span class="hljs-attr">"dueDate"</span>: <span class="hljs-string">"2022-12-31T00:00:00"</span>,
    <span class="hljs-attr">"priority"</span>: <span class="hljs-number">5</span>
}
</code></pre>
<ol start="6">
<li>Click on the <code>Send</code> button to execute the request.</li>
</ol>
<p>If the request is successful, you'll receive a response similar to the one below:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Todo item successfully created"</span>
}
</code></pre>
<p>The image below illustrates the successful creation of a new Todo item using Postman:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/PostmanSuccess.png" alt="PostmanSuccess" width="600" height="400" loading="lazy"></p>
<p>Now that we've successfully created a new Todo item, let's retrieve all Todo items from the database using our API.</p>
<h2 id="step-15">   Step 15: Retrieve All Todo Items  </h2>

<p>To retrieve all Todo items from the database, follow these steps:</p>
<ol>
<li><p>Open Postman and create a new request.</p>
</li>
<li><p>Set the request method to <code>GET</code>. </p>
</li>
<li><p>Enter the following URL: <code>https://localhost:5086/api/todo</code>.</p>
</li>
<li><p>Click on the <code>Send</code> button to execute the request.</p>
</li>
</ol>
<p>If the request is successful, you'll receive a response similar to the one below:</p>
<pre><code class="lang-json">
   {
    <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Successfully retrieved all blog posts"</span>,
    <span class="hljs-attr">"data"</span>: [
        {
            <span class="hljs-attr">"id"</span>: <span class="hljs-string">"e9898d1b-9ad3-4482-ad65-08dc77664fab"</span>,
            <span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
            <span class="hljs-attr">"description"</span>: <span class="hljs-string">"string"</span>,
            <span class="hljs-attr">"isComplete"</span>: <span class="hljs-literal">false</span>,
            <span class="hljs-attr">"dueDate"</span>: <span class="hljs-string">"2024-05-18T16:52:22.054Z"</span>,
            <span class="hljs-attr">"priority"</span>: <span class="hljs-number">5</span>,
            <span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"2024-05-18T18:14:08.1755565+00:00"</span>,
            <span class="hljs-attr">"updatedAt"</span>: <span class="hljs-string">"0001-01-01T00:00:00"</span>
        }
    ]
}
</code></pre>
<p>The image below illustrates the successful retrieval of all Todo items using Postman:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/PostmanGetAll.png" alt="PostmanGetAll" width="600" height="400" loading="lazy"></p>
<p>Congratulations! You've successfully created an API that can create and retrieve Todo items. This marks the completion of our Todo API project. You've learned how to set up a .NET Core project, define models, create a database context, implement a service layer, and create API endpoints. You've also learned how to use Postman to interact with your API and test its functionality.</p>
<p>Now let's move on to create the <code>GetByIdAsync</code>, <code>UpdateTodoAsync</code>, and <code>DeleteTodoAsync</code> methods in the <code>TodoServices</code> class and <code>TodoController</code> class.</p>
<h2 id="step-16">  Step 16: Implement the GetByIdAsync Method  </h2>

<p>The <code>GetByIdAsync</code> method retrieves a specific Todo item by its <code>Id</code>. We'll implement this method in both the <code>TodoServices</code> and <code>TodoController</code> classes.</p>
<h3 id="heading-the-todoservices-class">  The <code>TodoServices</code> Class  </h3>


<p>In the <code>TodoServices</code> class, add the following code to the <code>GetByIdAsync</code> method:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;Todo&gt; <span class="hljs-title">GetByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
{
    <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _context.Todos.FindAsync(id);
    <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
    {
        <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> KeyNotFoundException(<span class="hljs-string">$"No Todo item with Id <span class="hljs-subst">{id}</span> found."</span>);
    }
    <span class="hljs-keyword">return</span> todo;
}
</code></pre>
<p>This method uses Entity Framework Core's <code>FindAsync</code> method to fetch a Todo item by its <code>Id</code>. If no Todo item is found, it throws a <code>KeyNotFoundException</code> with a descriptive error message.</p>
<h3 id="heading-the-todocontroller-class">   The <code>TodoController</code> Class  </h3>


<p>In the <code>TodoController</code> class, add the following code to the <code>GetByIdAsync</code> method:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Controllers/TodoController.cs</span>

[<span class="hljs-meta">HttpGet(<span class="hljs-meta-string">"{id:guid}"</span>)</span>]
<span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">GetByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
{
    <span class="hljs-keyword">try</span>
    {
        <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _todoServices.GetByIdAsync(id);
        <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
        {
            <span class="hljs-keyword">return</span> NotFound(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"No Todo item with Id <span class="hljs-subst">{id}</span> found."</span> });
        }
        <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"Successfully retrieved Todo item with Id <span class="hljs-subst">{id}</span>."</span>, data = todo });
    }
    <span class="hljs-keyword">catch</span> (Exception ex)
    {
        <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"An error occurred while retrieving the Todo item with Id <span class="hljs-subst">{id}</span>."</span>, error = ex.Message });
    }
}
</code></pre>
<p>This method calls the <code>GetByIdAsync</code> method from the <code>ITodoServices</code> interface to fetch a Todo item by its <code>Id</code>. If a Todo item is retrieved successfully, it returns an <code>Ok</code> response with a success message and the Todo item. If an error occurs during the retrieval process, it returns a <code>500 Internal Server Error</code> response with an error message.</p>
<h2 id="step-17">  Step 17: Implement the UpdateTodoAsync Method   </h2>

<p>The <code>UpdateTodoAsync</code> method in the <code>TodoServices</code> class modifies an existing Todo item in the database. Let's implement this method now.</p>
<p>Navigate to the <code>TodoServices</code> class and add the following code to the <code>UpdateTodoAsync</code> method:</p>
<pre><code class="lang-csharp">

<span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-comment">// ...</span>

 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">UpdateTodoAsync</span>(<span class="hljs-params">Guid id, UpdateTodoRequest request</span>)</span>
 {
     <span class="hljs-keyword">try</span>
     {
         <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _context.Todos.FindAsync(id);
         <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
         {
             <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">$"Todo item with id <span class="hljs-subst">{id}</span> not found."</span>);
         }

         <span class="hljs-keyword">if</span> (request.Title != <span class="hljs-literal">null</span>)
         {
             todo.Title = request.Title;
         }

         <span class="hljs-keyword">if</span> (request.Description != <span class="hljs-literal">null</span>)
         {
             todo.Description = request.Description;
         }

         <span class="hljs-keyword">if</span> (request.IsComplete != <span class="hljs-literal">null</span>)
         {
             todo.IsComplete = request.IsComplete.Value;
         }

         <span class="hljs-keyword">if</span> (request.DueDate != <span class="hljs-literal">null</span>)
         {
             todo.DueDate = request.DueDate.Value;
         }

         <span class="hljs-keyword">if</span> (request.Priority != <span class="hljs-literal">null</span>)
         {
             todo.Priority = request.Priority.Value;
         }

         todo.UpdatedAt = DateTime.Now;

         <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
     }
     <span class="hljs-keyword">catch</span> (Exception ex)
     {
         _logger.LogError(ex, <span class="hljs-string">$"An error occurred while updating the todo item with id <span class="hljs-subst">{id}</span>."</span>);
         <span class="hljs-keyword">throw</span>;
     }
 }

<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a breakdown of the <code>UpdateTodoAsync</code> method:</p>
<ul>
<li><p><strong>Retrieving a Specific Todo Item</strong>: We use Entity Framework Core's <code>FindAsync</code> method to fetch a Todo item by its <code>Id</code>.</p>
</li>
<li><p><strong>Updating the Todo Item</strong>: We update the Todo item properties based on the values provided in the <code>UpdateTodoRequest</code> object.</p>
</li>
<li><p><strong>Error Handling</strong>: If no Todo item is found with the specified <code>Id</code>, we throw an exception with a descriptive error message.</p>
</li>
</ul>
<p>Now let's implement the <code>UpdateTodoAsync</code> method in the <code>TodoController</code> class. This method will modify an existing Todo item in the database.</p>
<p>Navigate to the <code>TodoController</code> class and add the following code to the <code>UpdateTodoAsync</code> method:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Controllers/TodoController.cs</span>

<span class="hljs-comment">// ... </span>
   [<span class="hljs-meta">HttpPut(<span class="hljs-meta-string">"{id:guid}"</span>)</span>]

   <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">UpdateTodoAsync</span>(<span class="hljs-params">Guid id, UpdateTodoRequest request</span>)</span>
   {

       <span class="hljs-keyword">if</span> (!ModelState.IsValid)
       {
           <span class="hljs-keyword">return</span> BadRequest(ModelState);
       }

       <span class="hljs-keyword">try</span>
       {

           <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _todoServices.GetByIdAsync(id);
           <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
           {
               <span class="hljs-keyword">return</span> NotFound(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"Todo Item  with id <span class="hljs-subst">{id}</span> not found"</span> });
           }

           <span class="hljs-keyword">await</span> _todoServices.UpdateTodoAsync(id, request);
           <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$" Todo Item  with id <span class="hljs-subst">{id}</span> successfully updated"</span> });

       }
       <span class="hljs-keyword">catch</span> (Exception ex)
       {
           <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"An error occurred while updating blog post with id <span class="hljs-subst">{id}</span>"</span>, error = ex.Message });


       }


   }

<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a breakdown of the <code>UpdateTodoAsync</code> method:</p>
<ul>
<li><p><strong>Model Validation</strong>: We check if the request model is valid using <code>ModelState.IsValid</code>. If the model is not valid, we return a <code>BadRequest</code> response with the model state errors.</p>
</li>
<li><p><strong>Retrieving a Specific Todo Item</strong>: We call the <code>GetByIdAsync</code> method from the <code>ITodoServices</code> interface to fetch a Todo item by its <code>Id</code>.</p>
</li>
<li><p><strong>Updating the Todo Item</strong>: If the Todo item is found, we call the <code>UpdateTodoAsync</code> method from the <code>ITodoServices</code> interface to update the Todo item.</p>
</li>
<li><p><strong>Success Response</strong>: If the Todo item is updated successfully, we return an <code>Ok</code> response with a success message.</p>
</li>
<li><p><strong>Error Handling</strong>: If an error occurs during the update process, we return a <code>500 Internal Server Error</code> response with an error message.</p>
</li>
</ul>
<h2 id="step-18"> Step 18: Implement the DeleteTodoAsync Method   </h2>

<p>The <code>DeleteTodoAsync</code> method in the <code>TodoServices</code> class removes a Todo item from the database. Let's implement this method now.</p>
<p>Navigate to the <code>TodoServices</code> class and add the following code to the <code>DeleteTodoAsync</code> method:</p>
<pre><code class="lang-csharp">

<span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-comment">// ...</span>


 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">DeleteTodoAsync</span>(<span class="hljs-params">Guid id</span>)</span>
 {

     <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _context.Todos.FindAsync(id);
     <span class="hljs-keyword">if</span>(todo != <span class="hljs-literal">null</span>)
     {
          _context.Todos.Remove(todo);
         <span class="hljs-keyword">await</span> _context.SaveChangesAsync();

     }
     <span class="hljs-keyword">else</span>
     {
         <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">$"No  item found with the id <span class="hljs-subst">{id}</span>"</span>);
     }


 }

<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a breakdown of the <code>DeleteTodoAsync</code> method:</p>
<ul>
<li><p><strong>Retrieving a Specific Todo Item</strong>: We use Entity Framework Core's <code>FindAsync</code> method to fetch a Todo item by its <code>Id</code>.</p>
</li>
<li><p><strong>Removing the Todo Item</strong>: If the Todo item is found, we remove it from the <code>Todos</code> DbSet in our context and save the changes asynchronously.</p>
</li>
<li><p><strong>Error Handling</strong>: If no Todo item is found with the specified <code>Id</code>, we throw an exception with a descriptive error message.</p>
</li>
</ul>
<p>Now let's implement the <code>DeleteTodoAsync</code> method in the <code>TodoController</code> class. This method will remove a Todo item from the database.</p>
<p>Navigate to the <code>TodoController</code> class and add the following code to the <code>DeleteTodoAsync</code> method:</p>
<pre><code class="lang-csharp">
<span class="hljs-comment">// Controllers/TodoController.cs</span>

<span class="hljs-comment">// ...</span>

 [<span class="hljs-meta">HttpDelete(<span class="hljs-meta-string">"{id:guid}"</span>)</span>]
 <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">DeleteTodoAsync</span>(<span class="hljs-params">Guid id</span>)</span>
 {
     <span class="hljs-keyword">try</span>
     {
         <span class="hljs-keyword">await</span> _todoServices.DeleteTodoAsync(id);
         <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"Todo  with id <span class="hljs-subst">{id}</span> successfully deleted"</span> });

     }
     <span class="hljs-keyword">catch</span> (Exception ex)
     {
         <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"An error occurred while deleting Todo Item  with id <span class="hljs-subst">{id}</span>"</span>, error = ex.Message });

     }
 }



<span class="hljs-comment">// ...</span>
</code></pre>
<p>Here's a breakdown of the <code>DeleteTodoAsync</code> method:</p>
<ul>
<li><p><strong>Removing the Todo Item</strong>: We call the <code>DeleteTodoAsync</code> method from the <code>ITodoServices</code> interface to remove a Todo item by its <code>Id</code>.</p>
</li>
<li><p><strong>Success Response</strong>: If the Todo item is deleted successfully, we return an <code>Ok</code> response with a success message.</p>
</li>
<li><p><strong>Error Handling</strong>: If an error occurs during the deletion process, we return a <code>500 Internal Server Error</code> response with an error message.</p>
</li>
</ul>
<p>Now your <code>TodoServices</code> class should look like this:</p>
<pre><code class="lang-csharp"><span class="hljs-comment">// Services/TodoServices.cs</span>

<span class="hljs-keyword">using</span> AutoMapper;
<span class="hljs-keyword">using</span> Microsoft.EntityFrameworkCore;
<span class="hljs-keyword">using</span> TodoAPI.AppDataContext;
<span class="hljs-keyword">using</span> TodoAPI.Contracts;
<span class="hljs-keyword">using</span> TodoAPI.Interface;
<span class="hljs-keyword">using</span> TodoAPI.Models;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Services</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TodoServices</span> : <span class="hljs-title">ITodoServices</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> TodoDbContext _context;
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ILogger&lt;TodoServices&gt; _logger;
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> IMapper _mapper;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TodoServices</span>(<span class="hljs-params">TodoDbContext context, ILogger&lt;TodoServices&gt; logger, IMapper mapper</span>)</span>
        {
            _context = context;
            _logger = logger;
            _mapper = mapper;
        }




        <span class="hljs-comment">//  Create Todo for it to be saved in the datbase </span>

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">CreateTodoAsync</span>(<span class="hljs-params">CreateTodoRequest request</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">var</span> todo = _mapper.Map&lt;Todo&gt;(request);
                todo.CreatedAt = DateTime.Now;
                _context.Todos.Add(todo);
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(ex, <span class="hljs-string">"An error occurred while creating the todo item."</span>);
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">"An error occurred while creating the todo item."</span>);
            }
        }


        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;Todo&gt; <span class="hljs-title">GetByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _context.Todos.FindAsync(id);
            <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
            {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">$" No Items with <span class="hljs-subst">{id}</span> found "</span>);
            }
            <span class="hljs-keyword">return</span> todo;
        }

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">UpdateTodoAsync</span>(<span class="hljs-params">Guid id, UpdateTodoRequest request</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _context.Todos.FindAsync(id);
                <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
                {
                    <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">$"Todo item with id <span class="hljs-subst">{id}</span> not found."</span>);
                }

                <span class="hljs-keyword">if</span> (request.Title != <span class="hljs-literal">null</span>)
                {
                    todo.Title = request.Title;
                }

                <span class="hljs-keyword">if</span> (request.Description != <span class="hljs-literal">null</span>)
                {
                    todo.Description = request.Description;
                }

                <span class="hljs-keyword">if</span> (request.IsComplete != <span class="hljs-literal">null</span>)
                {
                    todo.IsComplete = request.IsComplete.Value;
                }

                <span class="hljs-keyword">if</span> (request.DueDate != <span class="hljs-literal">null</span>)
                {
                    todo.DueDate = request.DueDate.Value;
                }

                <span class="hljs-keyword">if</span> (request.Priority != <span class="hljs-literal">null</span>)
                {
                    todo.Priority = request.Priority.Value;
                }

                todo.UpdatedAt = DateTime.Now;

                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();
            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                _logger.LogError(ex, <span class="hljs-string">$"An error occurred while updating the todo item with id <span class="hljs-subst">{id}</span>."</span>);
                <span class="hljs-keyword">throw</span>;
            }
        }
        <span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IEnumerable&lt;Todo&gt;&gt; GetAllAsync()
        {
            <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _context.Todos.ToListAsync();
            <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
            {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">" No Todo items found"</span>);
            }
            <span class="hljs-keyword">return</span> todo;

        }
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task <span class="hljs-title">DeleteTodoAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {

            <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _context.Todos.FindAsync(id);
            <span class="hljs-keyword">if</span> (todo != <span class="hljs-literal">null</span>)
            {
                _context.Todos.Remove(todo);
                <span class="hljs-keyword">await</span> _context.SaveChangesAsync();

            }
            <span class="hljs-keyword">else</span>
            {
                <span class="hljs-keyword">throw</span> <span class="hljs-keyword">new</span> Exception(<span class="hljs-string">$"No  item found with the id <span class="hljs-subst">{id}</span>"</span>);
            }


        }




    }
}
</code></pre>
<p>Now your <code>TodoController</code> class should look like this:</p>
<pre><code class="lang-csharp">
<span class="hljs-keyword">using</span> Microsoft.AspNetCore.Mvc;
<span class="hljs-keyword">using</span> TodoAPI.Contracts;
<span class="hljs-keyword">using</span> TodoAPI.Interface;

<span class="hljs-keyword">namespace</span> <span class="hljs-title">TodoAPI.Controllers</span>
{
    [<span class="hljs-meta">ApiController</span>]
    [<span class="hljs-meta">Route(<span class="hljs-meta-string">"api/[controller]"</span>)</span>]
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">TodoController</span> : <span class="hljs-title">ControllerBase</span>
    {
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> ITodoServices _todoServices;

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-title">TodoController</span>(<span class="hljs-params">ITodoServices todoServices</span>)</span>
        {
            _todoServices = todoServices;
        }



        <span class="hljs-comment">// Creating new Todo Item</span>
        [<span class="hljs-meta">HttpPost</span>]
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">CreateTodoAsync</span>(<span class="hljs-params">CreateTodoRequest request</span>)</span>
        {
            <span class="hljs-keyword">if</span> (!ModelState.IsValid)
            {
                <span class="hljs-keyword">return</span> BadRequest(ModelState);
            }


            <span class="hljs-keyword">try</span>
            {

                <span class="hljs-keyword">await</span> _todoServices.CreateTodoAsync(request);
                <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"Blog post successfully created"</span> });

            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">"An error occurred while creating the  crating Todo Item"</span>, error = ex.Message });

            }
        }

        <span class="hljs-comment">// Get all Todo Items</span>

        [<span class="hljs-meta">HttpGet</span>]
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">GetAllAsync</span>(<span class="hljs-params"></span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _todoServices.GetAllAsync();
                <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span> || !todo.Any())
                {
                    <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"No Todo Items  found"</span> });
                }
                <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">"Successfully retrieved all blog posts"</span>, data = todo });

            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">"An error occurred while retrieving all Tood it posts"</span>, error = ex.Message });


            }
        }

        [<span class="hljs-meta">HttpGet(<span class="hljs-meta-string">"{id:guid}"</span>)</span>]
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">GetByIdAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {

                <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _todoServices.GetByIdAsync(id);
                <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
                {
                    <span class="hljs-keyword">return</span> NotFound(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"Now Todo item with id <span class="hljs-subst">{id}</span> not found"</span> });

                }
                <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"Successfully retrieved  todo item with id <span class="hljs-subst">{id}</span>"</span>, data = todo });

            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"An error occurred while retrieving   todo item  with id <span class="hljs-subst">{id}</span>"</span>, error = ex.Message });

            }
        }



        [<span class="hljs-meta">HttpPut(<span class="hljs-meta-string">"{id:guid}"</span>)</span>]

        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">UpdateTodoAsync</span>(<span class="hljs-params">Guid id, UpdateTodoRequest request</span>)</span>
        {

            <span class="hljs-keyword">if</span> (!ModelState.IsValid)
            {
                <span class="hljs-keyword">return</span> BadRequest(ModelState);
            }

            <span class="hljs-keyword">try</span>
            {

                <span class="hljs-keyword">var</span> todo = <span class="hljs-keyword">await</span> _todoServices.GetByIdAsync(id);
                <span class="hljs-keyword">if</span> (todo == <span class="hljs-literal">null</span>)
                {
                    <span class="hljs-keyword">return</span> NotFound(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"Todo Item  with id <span class="hljs-subst">{id}</span> not found"</span> });
                }

                <span class="hljs-keyword">await</span> _todoServices.UpdateTodoAsync(id, request);
                <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$" Todo Item  with id <span class="hljs-subst">{id}</span> successfully updated"</span> });

            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"An error occurred while updating blog post with id <span class="hljs-subst">{id}</span>"</span>, error = ex.Message });


            }


        }


        [<span class="hljs-meta">HttpDelete(<span class="hljs-meta-string">"{id:guid}"</span>)</span>]
        <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">async</span> Task&lt;IActionResult&gt; <span class="hljs-title">DeleteTodoAsync</span>(<span class="hljs-params">Guid id</span>)</span>
        {
            <span class="hljs-keyword">try</span>
            {
                <span class="hljs-keyword">await</span> _todoServices.DeleteTodoAsync(id);
                <span class="hljs-keyword">return</span> Ok(<span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"Todo  with id <span class="hljs-subst">{id}</span> successfully deleted"</span> });

            }
            <span class="hljs-keyword">catch</span> (Exception ex)
            {
                <span class="hljs-keyword">return</span> StatusCode(<span class="hljs-number">500</span>, <span class="hljs-keyword">new</span> { message = <span class="hljs-string">$"An error occurred while deleting Todo Item  with id <span class="hljs-subst">{id}</span>"</span>, error = ex.Message });

            }
        }


    }
}
</code></pre>
<p>Now that we've implemented the <code>GetByIdAsync</code>, <code>UpdateTodoAsync</code>, and <code>DeleteTodoAsync</code> methods in the <code>TodoServices</code> and <code>TodoController</code> classes, we can test our API to ensure that everything is working as expected.</p>
<h2 id="step-19"> Step 19: Test Your API Endpoints with Postman   </h2>

<p>With our application up and running, we can now test all our API endpoints. We'll create new Todo items, retrieve all Todo items, fetch a specific Todo item by its <code>Id</code>, update a Todo item, and delete a Todo item using Postman. Let's start by creating three new Todo items.</p>
<p>Note that we'll be creating these Todo items one at a time, not all at once. Follow these steps for each Todo item:</p>
<ol>
<li>Open Postman and create a new request.</li>
<li>Set the request method to <code>POST</code>.</li>
<li>Enter the following URL: <code>http://localhost:5086/api/todo</code>.</li>
<li>In the <code>Headers</code> tab, set the <code>Content-Type</code> to <code>application/json</code>.</li>
<li>In the <code>Body</code> tab, select <code>raw</code> and enter one of the following JSON objects:</li>
</ol>
<p>For the first Todo item:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Learn ASP.NET Core"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Learn how to build web applications with ASP.NET Core"</span>,
    <span class="hljs-attr">"dueDate"</span>: <span class="hljs-string">"2022-12-31T00:00:00"</span>,
    <span class="hljs-attr">"priority"</span>: <span class="hljs-number">2</span>
}
</code></pre>
<p>For the second Todo item:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Learn C#"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Learn how to build web applications with C#"</span>,
    <span class="hljs-attr">"dueDate"</span>: <span class="hljs-string">"2022-12-31T00:00:00"</span>,
    <span class="hljs-attr">"priority"</span>: <span class="hljs-number">3</span>
}
</code></pre>
<p>For the third Todo item:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Learn SQL"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Learn how to build web applications with SQL"</span>,
    <span class="hljs-attr">"dueDate"</span>: <span class="hljs-string">"2022-12-31T00:00:00"</span>,
    <span class="hljs-attr">"priority"</span>: <span class="hljs-number">1</span>
}
</code></pre>
<ol start="6">
<li>Click on the <code>Send</code> button to execute the request for each Todo item.</li>
</ol>
<p>If each request is successful, you'll receive a response similar to the one below:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Todo item successfully created"</span>
}
</code></pre>
<p>This indicates that the Todo item has been successfully created. Repeat the steps for each Todo item.</p>
<h3 id="heading-how-to-retrieve-all-todo-items"> How to Retrieve All Todo Items   </h3>

<p>To fetch all Todo items from the database, follow these steps:</p>
<ol>
<li>Launch Postman and initiate a new request.</li>
<li>Set the HTTP method to <code>GET</code>.</li>
<li>Input the following URL: <code>http://localhost:5086/api/todo</code>.</li>
<li>Click the <code>Send</code> button to execute the request.</li>
</ol>
<p>The image below demonstrates a successful retrieval of all Todo items using Postman:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/PostmanGetAll-1.png" alt="PostmanGetAll-1" width="600" height="400" loading="lazy"></p>
<h3 id="heading-how-to-fetch-a-specific-todo-item-by-id">  How to Fetch a Specific Todo Item by Id  </h3>

<p>To retrieve a specific Todo item using its <code>Id</code>, follow these steps:</p>
<ol>
<li>Launch Postman and initiate a new request.</li>
<li>Set the HTTP method to <code>GET</code>.</li>
<li>Input the following URL: <code>http://localhost:5086/api/todo/{id}</code>, replacing <code>{id}</code> with the <code>Id</code> of the Todo item you wish to retrieve. For example, <code>http://localhost:5086/api/todo/e9898d1b-9ad3-4482-ad65-08dc77664fab</code>.</li>
<li>Click the <code>Send</code> button to execute the request.</li>
</ol>
<p>Upon successful execution, you'll receive a response similar to the one below:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Successfully retrieved  todo item with id e9898d1b-9ad3-4482-ad65-08dc77664fab"</span>,
    <span class="hljs-attr">"data"</span>: {
        <span class="hljs-attr">"id"</span>: <span class="hljs-string">"e9898d1b-9ad3-4482-ad65-08dc77664fab"</span>,
        <span class="hljs-attr">"title"</span>: <span class="hljs-string">"string"</span>,
        <span class="hljs-attr">"description"</span>: <span class="hljs-string">"string"</span>,
        <span class="hljs-attr">"isComplete"</span>: <span class="hljs-literal">false</span>,
        <span class="hljs-attr">"dueDate"</span>: <span class="hljs-string">"2024-05-18T16:52:22.054"</span>,
        <span class="hljs-attr">"priority"</span>: <span class="hljs-number">5</span>,
        <span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"2024-05-18T18:14:08.1755565"</span>,
        <span class="hljs-attr">"updatedAt"</span>: <span class="hljs-string">"0001-01-01T00:00:00"</span>
    }
}
</code></pre>
<p>The image below demonstrates the successful retrieval of a specific Todo item using Postman:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/PostmanGetById.png" alt="PostmanGetById" width="600" height="400" loading="lazy">)</p>
<h3 id="heading-how-to-update-a-todo-item">   How to Update a Todo Item </h3>


<p>In our Todo model, we have a property <code>isComplete</code> which is initially set to <code>false</code> when a Todo item is created. This property is used to indicate whether a task has been completed or not. To mark a task as complete, we need to update this property to <code>true</code>. Note that we can only update one Todo item at a time, and we identify the item to update by its <code>Id</code>.</p>
<p>Let's fetch all the Todo items, select one and update it by setting the <code>isComplete</code> property to <code>true</code>.</p>
<p>Follow these steps to update a Todo item:</p>
<ol>
<li>Launch Postman and initiate a new request.</li>
<li>Set the HTTP method to <code>PUT</code>.</li>
<li>Input the following URL: <code>http://localhost:5086/api/todo/{id}</code>, replacing <code>{id}</code> with the <code>Id</code> of the Todo item you wish to update. For example, <code>http://localhost:5086/api/todo/e9898d1b-9ad3-4482-ad65-08dc77664fab</code>.</li>
<li>In the <code>Headers</code> tab, set the <code>Content-Type</code> to <code>application/json</code>.</li>
<li>In the <code>Body</code> tab, select <code>raw</code> and enter the following JSON object:</li>
</ol>
<pre><code class="lang-json">{
    <span class="hljs-attr">"id"</span>: <span class="hljs-string">"21ebe2c2-79c0-45d4-4139-08dc789e3eb2"</span>,
    <span class="hljs-attr">"title"</span>: <span class="hljs-string">"Learn C#"</span>,
    <span class="hljs-attr">"description"</span>: <span class="hljs-string">"Learn how to build web applications with C#"</span>,
    <span class="hljs-attr">"isComplete"</span>: <span class="hljs-literal">true</span>, <span class="hljs-comment">// Set the isComplete to true</span>
    <span class="hljs-attr">"dueDate"</span>: <span class="hljs-string">"2022-12-31T00:00:00"</span>,
    <span class="hljs-attr">"priority"</span>: <span class="hljs-number">3</span>,
    <span class="hljs-attr">"createdAt"</span>: <span class="hljs-string">"2024-05-20T07:27:39.3730049+00:00"</span>,
    <span class="hljs-attr">"updatedAt"</span>: <span class="hljs-string">"0001-01-01T00:00:00"</span>
}
</code></pre>
<ol start="6">
<li>Click the <code>Send</code> button to execute the request.</li>
</ol>
<p>Upon successful execution, you'll receive a response similar to the one below:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Todo Item with id 21ebe2c2-79c0-45d4-4139-08dc789e3eb2 successfully updated"</span>
}
</code></pre>
<p>The image below demonstrates the successful update of a Todo item using Postman:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/PostmanUpdate.png" alt="PostmanUpdate" width="600" height="400" loading="lazy"></p>
<p><strong>Note</strong>: The <code>isComplete</code> property of the Todo item has been updated to <code>true</code>. Now, when you fetch all Todo items from the database, you will see the <code>isComplete</code> property is <code>true</code> for the updated Todo item.</p>
<p>Now let's see how to delete a Todo item from the database.</p>
<h3 id="heading-how-to-delete-a-todo-item">  How to Delete a Todo Item </h3>


<p>To remove a Todo item from the database, follow these steps: </p>
<ol>
<li>Open Postman and create a new request.</li>
<li>Set the HTTP method to <code>DELETE</code>.</li>
<li>Enter the following URL: <code>http://localhost:5086/api/todo/{id}</code>, replacing <code>{id}</code> with the <code>Id</code> of the Todo item you intend to remove. For instance, <code>http://localhost:5086/api/todo/e9898d1b-9ad3-4482-ad65-08dc77664fab</code>.</li>
<li>Click the <code>Send</code> button to execute the request.</li>
</ol>
<p>If the request is successful, you'll receive a response similar to the one below:</p>
<pre><code class="lang-json">{
    <span class="hljs-attr">"message"</span>: <span class="hljs-string">"Todo item with id 21ebe2c2-79c0-45d4-4139-08dc789e3eb2 successfully deleted"</span>
}
</code></pre>
<p>The image below illustrates the successful deletion of a Todo item using Postman:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/05/PostmanDelete.png" alt="PostmanDelete" width="600" height="400" loading="lazy"></p>
<p>Well done! You've successfully implemented the <code>GetByIdAsync</code>, <code>UpdateTodoAsync</code>, and <code>DeleteTodoAsync</code> methods in the <code>TodoServices</code> and <code>TodoController</code> classes. You've also verified your API endpoints using Postman to ensure they're functioning as expected. You can </p>
<h3 id="heading-source-code">   Source Code  </h3>


<p>The entire source code for this project is readily available in the <a target="_blank" href="https://github.com/Clifftech123/TodoAPI">TodoAPI</a> GitHub repository. I encourage you to delve into the codebase, tinker with various functionalities, and bolster your proficiency in crafting APIs using ASP.NET Core 8.</p>
<h2 id="conclusion"> Conclusion  </h2>

<p>In this guide, we've journeyed through the process of constructing a robust Todo API using the power of ASP.NET Core 8. We initiated our project from scratch, meticulously defining the essential models that form the backbone of our Todo application.</p>
<p>We then created a database context, a crucial step that facilitated our interaction with the database. To further streamline this interaction, we implemented a service layer, effectively abstracting the complexities of direct database operations.</p>
<p>Next, we created our API endpoints. These endpoints serve as the gateways for <code>creating</code>, <code>retrieving</code>, <code>updating</code>, and <code>deleting</code> Todo items, thereby providing comprehensive functionality to our application.</p>
<p>The final stage of our journey involved rigorous testing of our API using Postman. This ensured that our application was not only built as per our design but also functioned as expected, providing a reliable and efficient service.</p>
<p>As we conclude, it's important to remember that the knowledge gained here forms a solid foundation for building more complex and feature-rich APIs. The journey of learning and exploration doesn't end here – it's just the beginning. Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Object-Oriented Programming in C# – Explained With Examples ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to this comprehensive guide on object-oriented programming (OOP) using C#. This article will delve into the four fundamental pillars of OOP: Inheritance Encapsulation Polymorphism Abstraction Whether you're a seasoned programmer or a beginn... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/how-to-use-oop-in-c-sharp/</link>
                <guid isPermaLink="false">66bb570129aa951a4c0628b9</guid>
                
                    <category>
                        <![CDATA[ C ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Object Oriented Programming ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Wed, 01 May 2024 12:14:44 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/Attractive-1.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to this comprehensive guide on object-oriented programming (OOP) using C#. This article will delve into the four fundamental pillars of OOP:</p>
<ul>
<li>Inheritance</li>
<li>Encapsulation</li>
<li>Polymorphism</li>
<li>Abstraction</li>
</ul>
<p>Whether you're a seasoned programmer or a beginner stepping into the world of C#, this article aims to enhance your understanding of OOP concepts and their implementation in C#. </p>
<p>If you're new to C#, consider taking the free certification course on <a target="_blank" href="https://www.freecodecamp.org/learn/foundational-c-sharp-with-microsoft/">freeCodeCamp</a> or the free course on <a target="_blank" href="https://learn.microsoft.com/en-us/courses/browse/?term=c%23&amp;resource_type=learning%20path">Microsoft Learn</a> to familiarize yourself with the language.</p>
<p>Remember, the principles of OOP are universal and apply to most object-oriented programming languages. Therefore, the knowledge you gain from this article can be applied to learning OOP in any language.</p>
<p>Let's get started!</p>
<h1 id="heading-table-of-contents">Table of Contents</h1>
<ol start="2">
<li><p><a class="post-section-overview" href="#heading-what-is-object-oriented-programming-oop">What is Object-Oriented Programming (OOP)</a></p>
</li>
<li><p><a class="post-section-overview" href="#why-use-object-oriented-programming">Why Use Object-Oriented Programming?</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-the-four-pillars-of-object-oriented-programming">The Four Pillars of Object-Oriented Programming</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-inheritance">Inheritance</a></p>
</li>
<li><p><a class="post-section-overview" href="#types-of-inheritance">Types of Inheritance</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-encapsulation">Encapsulation</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-polymorphism">Polymorphism</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-abstraction">Abstraction</a></p>
</li>
<li><p><a class="post-section-overview" href="#heading-summary">Summary</a></p>
</li>
</ol>
<h1 id="what-is-object-oriented-programming-oop">What is Object-Oriented Programming (OOP)</h1>

<p>Object-Oriented Programming (OOP) is a programming paradigm that uses <code>objects</code> and <code>classes</code> to design and develop software applications. It is based on the concept of objects, which can contain data in the form of fields (attributes or properties) and code in the form of procedures (methods or functions).</p>
<p>Object-Oriented Programming offers several benefits, including:</p>
<ul>
<li><p><strong>Modularity</strong>: OOP promotes modularity by breaking down complex systems into smaller, manageable parts (objects). This makes it easier to maintain and update the code.</p>
</li>
<li><p><strong>Reusability</strong>: OOP allows you to reuse existing code by creating new objects based on existing ones. This saves time and effort in developing new applications.</p>
</li>
<li><p><strong>Flexibility</strong>: OOP provides flexibility in designing and implementing software systems. You can easily modify and extend the functionality of objects without affecting other parts of the system.</p>
</li>
<li><p><strong>Scalability</strong>: OOP supports scalability by allowing you to add new objects and classes as the system grows. This makes it easier to accommodate changes and enhancements in the software.</p>
</li>
</ul>
<p>As you can see, OOP offers several advantages that makes it a popular choice for developing software applications. Let's explore the four fundamental pillars of OOP in more detail.</p>
<h1 id="the-four-pillars-of-object-oriented-programming">The Four Pillars of Object-Oriented Programming</h1>

<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Add-a-heading.png" alt="Add-a-heading" width="600" height="400" loading="lazy"></p>
<p>The four pillars of Object-Oriented Programming are: </p>
<ol>
<li><strong>Inheritance</strong></li>
<li><strong>Encapsulation</strong></li>
<li><strong>Polymorphism</strong></li>
<li><strong>Abstraction</strong></li>
</ol>
<p>These pillars form the foundation of OOP and are essential concepts to understand when working with object-oriented programming languages like C#.</p>
<p>Let go deep into each of the pillars of OOP in the next sections.</p>
<p>Let's start with the first pillar of OOP: <code>Inheritance</code>.</p>
<h1 id="inheritance">Inheritance</h1>

<p>Inheritance is a concept used in most programming languages and is something you can't avoid when working with object-oriented programming. Programming languages like <code>C#</code> and Java are some of the languages that support inheritance. In this article, we will be looking at inheritance in <code>C#</code> and how to use it in your application.</p>
<h4 id="heading-what-is-inheritance">What is Inheritance?</h4>
<p>Imagine that you have a family tree, where each generation represents a class in C#. The first generation is the <code>base class</code>, which is the foundational class that provides the basic structure and properties. This could be likened to the patriarch of the family, who establishes the family's core values and characteristics.</p>
<p>As the family tree progresses, each subsequent generation inherits the traits and characteristics of the previous generation but also adds or modifies them to reflect their unique identity. These subsequent generations can be thought of as <code>derived</code> classes in C#, which inherit from the <code>base</code> class but also introduce their own unique features or modifications.</p>
<p>For example, the patriarch might have established the family's love for gardening, which becomes a fundamental trait passed down through the generations. However, as the family tree evolves, some members might develop a special interest in growing exotic plants, while others might focus on organic gardening. These special interests represent the unique characteristics of the derived classes, which inherit the basic love for gardening from the base class but also introduce their own unique features.</p>
<p>In this analogy, the <code>base</code> class is the patriarch, which represents the foundational class with its basic properties and characteristics. The <code>derived</code> classes are the subsequent generations, each with their unique features or modifications, inheriting the basic traits from the base class but also adding their own unique aspects. This process of inheritance allows for the creation of a rich and varied family tree, where each generation builds upon the previous one, introducing new traits and refining existing ones.</p>
<p>Inheritance is a mechanism that allows you to define a new <code>class</code> based on an existing <code>class</code>. The new class inherits all the members (fields, properties, and methods) of the existing class. The existing class is known as the <code>base</code> class, and the new class is known as the <code>derived</code> class.</p>
<p>Basic Syntax of inheritance in C#:</p>
<pre><code class="lang-csharp">
<span class="hljs-keyword">class</span> <span class="hljs-title">BaseClass</span>
{
    <span class="hljs-comment">// Base class members</span>
}

<span class="hljs-keyword">class</span> <span class="hljs-title">DerivedClass</span> : <span class="hljs-title">BaseClass</span>
{
    <span class="hljs-comment">// Derived class members</span>
}
</code></pre>
<p>In the above code snippet, <code>BaseClass</code> is the base class, and <code>DerivedClass</code> is the derived class. The <code>DerivedClass</code> inherits all the members of the <code>BaseClass</code>. The colon <code>(:)</code> is used to indicate that the <code>DerivedClass</code> is derived from the <code>BaseClass</code>.</p>
<p>If You are new to <code>C#</code> and you don't know what a class is, don't worry, I will explain it to you. A class is a blueprint for creating objects. It defines the properties and methods that an object of the class will have. Here is an example of a class in <code>C#</code>:</p>
<pre><code class="lang-csharp">
<span class="hljs-keyword">class</span> <span class="hljs-title">Person</span>
{
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }
    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> Age { <span class="hljs-keyword">get</span>; <span class="hljs-keyword">set</span>; }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Name: <span class="hljs-subst">{Name}</span>, Age: <span class="hljs-subst">{Age}</span>"</span>);
    }
}
</code></pre>
<p>In the above code snippet, the <code>Person</code> class has two properties (<code>Name</code> and <code>Age</code>) and a method (<code>Display</code>). The properties represent the state of the object, and the method represents the behavior of the object. You can create an object of the <code>Person</code> class and set its properties like this:</p>
<pre><code class="lang-csharp">
Person person = <span class="hljs-keyword">new</span> Person();
person.Name = <span class="hljs-string">"John"</span>;
person.Age = <span class="hljs-number">30</span>;
</code></pre>
<p>You can call the <code>Display</code> method on the <code>person</code> object to display the name and age of the person:</p>
<pre><code class="lang-csharp">
person.Display(); <span class="hljs-comment">// Output: Name: John, Age: 30</span>
</code></pre>
<p>Before moving on with the article, let's look at some keywords you're going to come across  a lot <code>base class</code>, <code>Abstract class</code> ,<code>derived class</code>, <code>parent class</code>, and <code>child class</code>.</p>
<p>Let me explain them to you.</p>
<ul>
<li><strong>Base class</strong>: This is the class whose members are inherited by another class. It is also known as the parent class.</li>
</ul>
<pre><code class="lang-csharp">
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BaseClass</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is a base class"</span>);
    }
}
</code></pre>
<ul>
<li><strong>Abstract class</strong>: This is a class that cannot be instantiated. It is used to provide a common base for all the derived classes. It can contain both abstract and non-abstract methods.</li>
</ul>
<pre><code class="lang-csharp">
<span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">AbstractClass</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>;
}
</code></pre>
<ul>
<li><strong>Derived class</strong>: This is the class that inherits the members of the base class. It is also known as the child class.</li>
</ul>
<pre><code class="lang-csharp">
<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">DerivedClass</span> : <span class="hljs-title">BaseClass</span>

{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is a derived class"</span>);
    }
}
</code></pre>
<p> So now you know what these keywords mean, let's move on to the next section.</p>
<h4 id="heading-types-of-inheritance">Types of Inheritance</h4>
<p>Inheritance can be classified into different types based on the way the classes are derived. The following are the types of inheritance: </p>
<ul>
<li><strong>Single Inheritance</strong>: Single inheritance is a fundamental concept in object-oriented programming where a class, known as the <code>derived class</code>, is based on another class, known as the <code>base class</code>. This is the simplest form of inheritance. </li>
</ul>
<p>To illustrate this, let's consider a real-world analogy. Imagine you are the only child of your father. In this scenario, you inherit characteristics from your father. This is akin to single inheritance in programming.</p>
<p>Let's look at an example in <code>C#</code>:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Father</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the father class"</span>);
    }
}
</code></pre>
<p>In the above code, <code>Father</code> is the base class with a method <code>Display</code>.</p>
<p>Now, let's create a derived class <code>Child</code> that inherits from the <code>Father</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Child</span> : <span class="hljs-title">Father</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the child class"</span>);
    }
}
</code></pre>
<p>In this code snippet, the <code>Child</code> class is derived from the <code>Father</code> class. The <code>Child</code> class inherits the <code>Display</code> method from the <code>Father</code> class. </p>
<p>You can create an object of the <code>Child</code> class and call the <code>Display</code> method. This demonstrates that the <code>Child</code> class can access the <code>Display</code> method from the <code>Father</code> class.</p>
<pre><code class="lang-csharp">Child child = <span class="hljs-keyword">new</span> Child();
child.Display(); <span class="hljs-comment">// Output: This is the father class</span>
</code></pre>
<ul>
<li><strong>Multilevel Inheritance</strong>: Multilevel inheritance is a concept in object-oriented programming where a class is derived from another derived class, creating a chain of inheritance.</li>
</ul>
<p>To better understand this, let's consider a family tree analogy. Assuming you are the <code>child</code> of your <code>father</code>, and your <code>father</code> is the <code>child</code> of your <code>grandfather</code>. In this scenario, you inherit characteristics from both your father and grandfather. This is similar to multilevel inheritance in programming.</p>
<p>Let's explore this concept with an example in <code>C#</code>:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Grandfather</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the grandfather class"</span>);
    }
}
</code></pre>
<p>In the above code, <code>Grandfather</code> is the base class with a method <code>Display</code>.</p>
<p>Next, we created a derived class <code>Father</code> that inherits from the <code>Grandfather</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Father</span> : <span class="hljs-title">Grandfather</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the father class"</span>);
    }
}
</code></pre>
<p>Here, the <code>Father</code> class is derived from the <code>Grandfather</code> class and inherits the <code>Display</code> method from it.</p>
<p>Finally, we created another derived class <code>Child</code> that inherits from the <code>Father</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Child</span> : <span class="hljs-title">Father</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayChild</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the child class"</span>);
    }
}
</code></pre>
<p>In this code snippet, the <code>Child</code> class is derived from the <code>Father</code> class. The <code>Child</code> class inherits the <code>Display</code> and <code>Show</code> methods from the <code>Father</code> class.</p>
<p>We can create an object of the <code>Child</code> class and call the <code>Display</code> and <code>Show</code> methods. This demonstrates that the <code>Child</code> class can access the <code>Display</code> and <code>Show</code> methods from the <code>Father</code> class.</p>
<pre><code class="lang-csharp">Child child = <span class="hljs-keyword">new</span> Child();
child.Display(); <span class="hljs-comment">// Output: This is the grandfather class</span>
child.Show(); <span class="hljs-comment">// Output: This is the father class</span>
child.DisplayChild(); <span class="hljs-comment">// Output: This is the child class</span>
</code></pre>
<ul>
<li><strong>Hierarchical Inheritance</strong>: Hierarchical inheritance is a concept in object-oriented programming where multiple classes are derived from a <code>single base class</code>, forming a <code>tree-like structure</code>.</li>
</ul>
<p>To illustrate this, let's consider a real-world analogy. Assuming you and your <code>siblings</code> share the <code>same parent</code>. In this scenario, all of you inherit characteristics from the same parent. This is akin to hierarchical inheritance in programming.</p>
<p>Let's explore this concept with an example in <code>C#</code>:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Parent</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the parent class"</span>);
    }
}
</code></pre>
<p>In the above code, <code>Parent</code> is the base class with a method <code>Display</code>.</p>
<p> Next, we created two derived classes <code>Child1</code> and <code>Child2</code> that inherit from the <code>Parent</code> class:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Child1</span> : <span class="hljs-title">Parent</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show1</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the first child class"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Child2</span> : <span class="hljs-title">Parent</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Show2</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"This is the second child class"</span>);
    }
}
</code></pre>
<p>In this code snippet, the <code>Child1</code> and <code>Child2</code> classes are derived from the <code>Parent</code> class. Both classes inherit the <code>Display</code> method from the <code>Parent</code> class.</p>
<p>We can create objects of the <code>Child1</code> and <code>Child2</code> classes and call the <code>Display</code>, <code>Show1</code>, and <code>Show2</code> methods. This demonstrates that both <code>Child1</code> and <code>Child2</code> classes can access the <code>Display</code> method from the <code>Parent</code> class.</p>
<pre><code class="lang-csharp">Child1 child1 = <span class="hljs-keyword">new</span> Child1();
child1.Display(); <span class="hljs-comment">// Output: This is the parent class</span>
child1.Show1(); <span class="hljs-comment">// Output: This is the first child class</span>

Child2 child2 = <span class="hljs-keyword">new</span> Child2();
child2.Display(); <span class="hljs-comment">// Output: This is the parent class</span>
child2.Show2(); <span class="hljs-comment">// Output: This is the second child class</span>
</code></pre>
<p>Congratulation you have learned the basics of inheritance in C#, let's move to the next section <code>Encapsulation</code>.</p>
<h4 id="heading-understanding-encapsulation-and-properties-in-c">Understanding Encapsulation and Properties in C</h4>
<p>As we continue our journey through the pillars of OOP, we now arrive at <code>Encapsulation</code>. Before we delve into <code>Encapsulation</code>, it's crucial to understand a common concept in C# called <code>properties</code>.</p>
<p>Properties in C# are members of a class that provide a flexible mechanism to read, write, or compute the value of a private field. They can be used as if they are public data members, but they are actually special methods called accessors. These accessors are used to get and set the values of private fields.</p>
<p>If you're new to this concept, don't worry. Let's break it down with an example:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Person</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> name;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name
    {
        <span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> name; }
        <span class="hljs-keyword">set</span> { name = <span class="hljs-keyword">value</span>; }
    }
}
</code></pre>
<p>In the above code snippet, the <code>Person</code> class has a private field <code>name</code> and a property <code>Name</code>. The property <code>Name</code> has two accessors: a <code>get</code> accessor to retrieve the value of the <code>name</code> field, and a <code>set</code> accessor to set the value of the <code>name</code> field.</p>
<p>Understanding properties is key to grasping the concept of <code>Encapsulation</code>, which we will explore in the next section. </p>
<h1 id="encapsulation">Encapsulation</h1>

<p>To understand <code>Encapsulation</code>, let's use an analogy. Consider a <code>gift box</code> that contains a <code>gift</code>. The <code>gift box</code> acts as a container that encapsulates the <code>gift</code>. The <code>gift</code> is hidden from the outside world and can only be accessed through the <code>gift box</code>. This is akin to <code>Encapsulation</code> in object-oriented programming.</p>
<p><code>Encapsulation</code> is the principle of bundling the data (fields) and methods (functions) that operate on the data into a single unit, known as a <code>class</code>. It restricts direct access to some of an object's components and allows access only through the methods of the class. In essence, <code>Encapsulation</code> conceals the internal state of an object and only exposes the necessary information to the outside world.</p>
<p>Let's see an example in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Person</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">string</span> name;
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">int</span> age;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">string</span> Name
    {
        <span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> name; }
        <span class="hljs-keyword">set</span> { name = <span class="hljs-keyword">value</span>; }
    }

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">int</span> Age
    {
        <span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> age; }
        <span class="hljs-keyword">set</span> { age = <span class="hljs-keyword">value</span>; }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Display</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Name: <span class="hljs-subst">{Name}</span>, Age: <span class="hljs-subst">{Age}</span>"</span>);
    }
}
</code></pre>
<p>In the above code snippet, the <code>Person</code> class encapsulates the data (fields <code>name</code> and <code>age</code>) and methods (<code>Display</code>) into a single unit. The fields <code>name</code> and <code>age</code> are private, meaning they cannot be accessed directly from outside the class. The properties <code>Name</code> and <code>Age</code> provide controlled access to the private fields using <code>get</code> and <code>set</code> accessors.</p>
<p>Let's add another example to further illustrate this concept:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">BankAccount</span>
{
    <span class="hljs-keyword">private</span> <span class="hljs-keyword">double</span> balance;

    <span class="hljs-keyword">public</span> <span class="hljs-keyword">double</span> Balance
    {
        <span class="hljs-keyword">get</span> { <span class="hljs-keyword">return</span> balance; }
        <span class="hljs-keyword">private</span> <span class="hljs-keyword">set</span> { balance = <span class="hljs-keyword">value</span>; }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Deposit</span>(<span class="hljs-params"><span class="hljs-keyword">double</span> amount</span>)</span>
    {
        <span class="hljs-keyword">if</span> (amount &gt; <span class="hljs-number">0</span>)
        {
            Balance += amount;
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Withdraw</span>(<span class="hljs-params"><span class="hljs-keyword">double</span> amount</span>)</span>
    {
        <span class="hljs-keyword">if</span> (amount &gt; <span class="hljs-number">0</span> &amp;&amp; Balance &gt;= amount)
        {
            Balance -= amount;
        }
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">DisplayBalance</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Balance: <span class="hljs-subst">{Balance}</span>"</span>);
    }
}
</code></pre>
<p>In this example, the <code>BankAccount</code> class encapsulates the <code>balance</code> field and the methods that operate on it (<code>Deposit</code>, <code>Withdraw</code>, <code>DisplayBalance</code>). The <code>balance</code> field is private and can only be accessed through the <code>Balance</code> property and the methods of the class. This ensures that the balance cannot be directly manipulated from outside the class, providing a secure way to manage a bank account.</p>
<p>Congratulations! You have learned about <code>Encapsulation</code> and how it is implemented in C#. Let's move on to the next section, <code>Polymorphism</code>.</p>
<h4 id="heading-understanding-polymorphism-in-c">Understanding Polymorphism in C</h4>
<p>As we delve deeper into the four pillars of OOP, we now encounter <code>Polymorphism</code>. The term <code>Polymorphism</code> originates from the Greek words <code>poly</code> (many) and <code>morphos</code> (forms), signifying "many forms". In the realm of object-oriented programming, <code>Polymorphism</code> denotes an object's ability to assume multiple forms.</p>
<p>To comprehend <code>Polymorphism</code>, let's consider a <code>music player</code>. It can play various types of music files, such as <code>MP3</code>, <code>WAV</code>, or <code>AAC</code>. Each of these file types is different, yet our music player can handle all of them. This is akin to <code>Polymorphism</code> in object-oriented programming.</p>
<h1 id="polymorphism">Polymorphism</h1>

<p><code>Polymorphism</code> is a core concept in object-oriented programming that allows objects of different classes to be treated as objects of a common superclass. It provides a single interface to represent multiple underlying forms (classes) and enables objects to be processed in a generic manner.</p>
<p>In C#, there are two types of <code>Polymorphism</code>:</p>
<ol>
<li><strong>Compile-time Polymorphism (Method Overloading)</strong></li>
<li><strong>Run-time Polymorphism (Method Overriding)</strong></li>
</ol>
<h3 id="heading-compile-time-polymorphism-method-overloading">Compile-time Polymorphism (Method Overloading)</h3>
<p><code>Compile-time Polymorphism</code>, also known as <code>Method Overloading</code>, allows a class to have multiple methods with the same name but different parameters. The compiler determines which method to invoke based on the number and types of arguments.</p>
<p>Here's an example of <code>Method Overloading</code> in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Printer</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Print</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Printing string: <span class="hljs-subst">{message}</span>"</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Print</span>(<span class="hljs-params"><span class="hljs-keyword">int</span> number</span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">$"Printing number: <span class="hljs-subst">{number}</span>"</span>);
    }

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Print</span>(<span class="hljs-params"><span class="hljs-keyword">string</span> message, <span class="hljs-keyword">int</span> copies</span>)</span>
    {
        <span class="hljs-keyword">for</span> (<span class="hljs-keyword">int</span> i = <span class="hljs-number">0</span>; i &lt; copies; i++)
        {
            Console.WriteLine(<span class="hljs-string">$"Printing string: <span class="hljs-subst">{message}</span>"</span>);
        }
    }
}
</code></pre>
<p>In this example, the <code>Printer</code> class has three <code>Print</code> methods with the same name but different parameters. This is an example of <code>Method Overloading</code> in C#.</p>
<h3 id="heading-run-time-polymorphism-method-overriding">Run-time Polymorphism (Method Overriding)</h3>
<p><code>Run-time Polymorphism</code>, also known as <code>Method Overriding</code>, allows a subclass to provide a specific implementation of a method that is already provided by its superclass.</p>
<p>Here's an example of <code>Method Overriding</code> in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">MusicPlayer</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">virtual</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Play</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"Playing music"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Mp3Player</span> : <span class="hljs-title">MusicPlayer</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Play</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"Playing MP3 music"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">WavPlayer</span> : <span class="hljs-title">MusicPlayer</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Play</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"Playing WAV music"</span>);
    }
}
</code></pre>
<p>In this example, the <code>MusicPlayer</code> class has a virtual method <code>Play</code>. The <code>Mp3Player</code> and <code>WavPlayer</code> classes override the <code>Play</code> method with specific implementations for playing MP3 and WAV music, respectively. This is an example of <code>Method Overriding</code> in C#.</p>
<p>Let's see how <code>Polymorphism</code> can be used in a program:</p>
<pre><code class="lang-csharp">MusicPlayer player = <span class="hljs-keyword">new</span> Mp3Player();
player.Play(); <span class="hljs-comment">// Output: Playing MP3 music</span>

player = <span class="hljs-keyword">new</span> WavPlayer();
player.Play(); <span class="hljs-comment">// Output: Playing WAV music</span>
</code></pre>
<p>In this code snippet, we created an object of the <code>Mp3Player</code> class and assigned it to a variable of type <code>MusicPlayer</code>. We then called the <code>Play</code> method on the <code>player</code> object, which invokes the overridden <code>Play</code> method in the <code>Mp3Player</code> class. We then created an object of the <code>WavPlayer</code> class and assigned it to the <code>player</code> variable. When we call the <code>Play</code> method again, it invokes the overridden <code>Play</code> method in the <code>WavPlayer</code> class.</p>
<p>Congratulations! You have learned about <code>Polymorphism</code> and how it is implemented in C#. Let's move on to the final pillar of OOP, <code>Abstraction</code>.</p>
<h4 id="heading-understanding-abstraction-in-c">Understanding Abstraction in C</h4>
<p>As we delve into the final pillar of OOP, we encounter <code>Abstraction</code>. <code>Abstraction</code> is the process of hiding complex implementation details and exposing only the essential features of an object. It emphasizes on what an object does rather than how it does it.</p>
<p>To comprehend <code>Abstraction</code>, let's consider a <code>smartphone</code>. When you use a smartphone, you don't need to understand the intricacies of how the internal components like the <code>processor</code> or the <code>memory</code> work. You only need to know how to interact with the user interface to make calls, send messages, or use apps. This is akin to <code>Abstraction</code> in object-oriented programming.</p>
<h2 id="abstraction">Abstraction</h2>

<p><code>Abstraction</code> is a key concept in object-oriented programming that allows you to create a blueprint for a class with some abstract methods that must be implemented by the derived classes. It enables you to define the structure of a class without providing the implementation details.</p>
<p>In C#, <code>Abstraction</code> can be achieved using <code>abstract</code> classes and <code>interfaces</code>. Let's explore both concepts:</p>
<h3 id="heading-abstract-classes">Abstract Classes</h3>
<p>An <code>abstract class</code> is a class that cannot be instantiated and can contain both abstract and non-abstract methods. An abstract method is a method without a body that must be implemented by the derived classes.</p>
<p>Here's an example of an <code>abstract class</code> in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Animal</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">abstract</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Speak</span>(<span class="hljs-params"></span>)</span>;
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Dog</span> : <span class="hljs-title">Animal</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Speak</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The dog barks"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Cat</span> : <span class="hljs-title">Animal</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">override</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Speak</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The cat meows"</span>);
    }
}
</code></pre>
<p>In this example, the <code>Animal</code> class is an abstract class with an abstract method <code>Speak</code>. The <code>Dog</code> and <code>Cat</code> classes inherit from the <code>Animal</code> class and provide specific implementations for the <code>Speak</code> method. This is an example of <code>Abstraction</code> using abstract classes in C#.</p>
<h3 id="heading-interfaces">Interfaces</h3>
<p>An <code>interface</code> is a reference type in C# that defines a contract for classes to implement. It contains only the declaration of the methods, properties, events, or indexers, without providing the implementation.</p>
<p>Here's an example of an <code>interface</code> in C#:</p>
<pre><code class="lang-csharp"><span class="hljs-keyword">public</span> <span class="hljs-keyword">interface</span> <span class="hljs-title">IFlyable</span>
{
    <span class="hljs-function"><span class="hljs-keyword">void</span> <span class="hljs-title">Fly</span>(<span class="hljs-params"></span>)</span>;
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Bird</span> : <span class="hljs-title">IFlyable</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Fly</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The bird flies"</span>);
    }
}

<span class="hljs-keyword">public</span> <span class="hljs-keyword">class</span> <span class="hljs-title">Airplane</span> : <span class="hljs-title">IFlyable</span>
{
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">Fly</span>(<span class="hljs-params"></span>)</span>
    {
        Console.WriteLine(<span class="hljs-string">"The airplane flies"</span>);
    }
}
</code></pre>
<p>In this example, the <code>IFlyable</code> interface defines a contract with a method <code>Fly</code>. The <code>Bird</code> and <code>Airplane</code> classes implement the <code>IFlyable</code> interface and provide specific implementations for the <code>Fly</code> method. This is an example of <code>Abstraction</code> using interfaces in C#.</p>
<p>Congratulations! You have now learned about <code>Abstraction</code> and how it is implemented in C#. The key takeaway is that <code>Abstraction</code> allows us to hide the complexity of the system and expose only the necessary details to the user.</p>
<h1 id="summary">Summary</h1>

<p>In this article, we have explored the four fundamental pillars of object-oriented programming (OOP) in C#: <code>Inheritance</code>, <code>Encapsulation</code>, <code>Polymorphism</code>, and <code>Abstraction</code>. </p>
<p>These pillars form the foundation of OOP and are essential concepts to understand when working with object-oriented programming languages like C#. The knowledge gained from this article will help you enhance your understanding of OOP concepts and their implementation in C#. </p>
<p>Thank you for reading this article, I hope you find it helpful. If you have any questions or feedback, feel free to reach out to me. Happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Use Git and GitHub – a Guide for Beginners and Experienced Developers ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to Git and GitHub for Beginners! This comprehensive guide is tailored to help you navigate the world of version control and collaboration.  Whether you're a newbie just starting out or an experienced developer looking to brush up on your skil... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/guide-to-git-github-for-beginners-and-experienced-devs/</link>
                <guid isPermaLink="false">66bb56fe0da5b03e481107c4</guid>
                
                    <category>
                        <![CDATA[ beginner ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Git ]]>
                    </category>
                
                    <category>
                        <![CDATA[ GitHub ]]>
                    </category>
                
                    <category>
                        <![CDATA[ version control ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Sat, 06 Apr 2024 01:38:29 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/04/Attractive.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to Git and GitHub for Beginners! This comprehensive guide is tailored to help you navigate the world of version control and collaboration. </p>
<p>Whether you're a newbie just starting out or an experienced developer looking to brush up on your skills, this guide offers a step-by-step approach to understanding and effectively using Git and GitHub.</p>
<p>By the end of this journey, you'll have a solid foundation in Git and GitHub. You'll be equipped with practical knowledge to streamline your coding workflow, collaborate seamlessly with teams, and contribute to open-source projects. </p>
<p>So, let's dive in and get started on your Git and GitHub adventure!</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-who-is-this-guide-for">Who is this guide for?</a></li>
<li><a class="post-section-overview" href="#heading-technologies">Technologies</a></li>
<li><a class="post-section-overview" href="#heading-terms">Terms</a></li>
<li><a class="post-section-overview" href="#heading-what-is-github">What is GitHub?</a></li>
<li><a class="post-section-overview" href="#heading-what-is-github-used-for">What is GitHub used for?</a></li>
<li><a class="post-section-overview" href="#heading-common-tasks-youll-perform-with-git">Common tasks you'll perform with Git</a></li>
<li><a class="post-section-overview" href="#heading-how-to-install-git">How to install Git</a></li>
<li><a class="post-section-overview" href="#heading-how-to-configure-git">How to configure Git</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-the-default-editor">How to set the default editor</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-repository-using-the-github-website">How to create a repository using the Github website</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-repository-using-the-git-command-line">How to create a repository using the Git command line</a></li>
<li><a class="post-section-overview" href="#heading-how-to-connect-a-local-repository-to-a-remote-repository-on-github">How to connect a local repository to a remote repository on GitHub</a></li>
<li><a class="post-section-overview" href="#heading-how-to-pull-changes-from-a-remote-repository-to-a-local-repository">How to pull changes from a remote repository to a local repository</a></li>
<li><a class="post-section-overview" href="#heading-how-to-work-with-git-commands">How to work with Git commands</a></li>
<li><a class="post-section-overview" href="#heading-how-to-make-changes-to-a-file">How to make changes to a file</a></li>
<li><a class="post-section-overview" href="#heading-how-to-check-the-status-of-the-current-branch">How to check the status of the current branch</a></li>
<li><a class="post-section-overview" href="#heading-how-to-stage-changes">How to stage changes</a></li>
<li><a class="post-section-overview" href="#heading-how-to-commit-changes">How to commit changes</a></li>
<li><a class="post-section-overview" href="#heading-how-to-push-changes-to-a-remote-repository">How to push changes to a remote repository</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-branch">How to create a branch</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-pull-request">How to create a pull request</a></li>
<li><a class="post-section-overview" href="#heading-how-to-merge-a-pull-requset">How to merge a pull request</a></li>
<li><a class="post-section-overview" href="#heading-wrapping-up">Wrapping Up</a></li>
</ul>
<h2 id="who-is-this-guide-for">Who is This Guide For?</h2>

<p>This guide is for everyone who wants to level up their coding skills and become proficient in using Git and GitHub. </p>
<p>Whether you're:</p>
<ul>
<li>just starting your tech career and need to learn the basics of version control.</li>
<li>an aspiring developer eager to integrate <code>Git</code> into your workflow.</li>
<li>an experienced programmer looking to refresh your knowledge or discover new features.</li>
<li>a team lead or manager interested in fostering a culture of collaboration and efficient code management.</li>
</ul>
<p>Regardless of your background or experience, this guide is designed to empower you with the tools and knowledge you need to excel in your coding endeavors.</p>
<h2 id="technologies">Technologies</h2>

<p>Before you start, make sure:</p>
<ul>
<li>You have a <a target="_blank" href="https://github.com/">GitHub account</a></li>
<li><a target="_blank" href="https://git-scm.com/">Git</a> is installed on your machine</li>
<li>You have a text editor, such as <a target="_blank" href="https://code.visualstudio.com/">Visual Studio Code</a> installed</li>
<li><a target="_blank" href="https://nodejs.org/en/">Node.js</a> is installed on your machine</li>
</ul>
<h2 id="terms">Terms</h2>

<p>They are a lot of terms around Git and Github that you may meet when you're working with version control. Let me break it down for you before we start:</p>
<ul>
<li><strong>Branch</strong>: A version of the codebase that diverges from the main branch to isolate changes for specific features, fixes, or experiments.</li>
<li><strong>Commit</strong>: A snapshot of your changes, saved to your local repository. Each commit is uniquely identified by a checksum.</li>
<li><strong>Stage</strong>: The area where Git tracks changes that are ready to be included in the next commit. Files in the staging area are prepared (staged) for the next commit.</li>
<li><strong>Merge</strong>: The process of integrating changes from one branch into another, typically the main branch.</li>
<li><strong>Pull Request</strong>: A proposal to merge changes from one branch into another, often used in collaborative environments to review and discuss changes before they are merged.</li>
<li><strong>Fork</strong>: A personal copy of someone else's project that lives on your GitHub account.</li>
<li><strong>Clone</strong>: The act of downloading a repository from a remote source to your local machine.</li>
<li><strong>Remote</strong>: A common repository that all team members use to exchange their changes.</li>
<li><strong>Origin</strong>: The default name Git gives to the server from which you cloned.</li>
<li><strong>Upstream</strong>: The original repository that was cloned.</li>
<li><strong>Master</strong>: The default branch name given to a repository when it is created. In modern practice, it is often replaced with <code>main</code>.</li>
<li><strong>Repository</strong>: A storage location where your project lives, containing all the files and revision history.</li>
<li><strong>Working Directory</strong>: The directory on your computer where you are making changes to your project.</li>
<li><strong>Staging Area</strong>: Also known as the "Index," it's an area where Git tracks changes that are ready to be committed.</li>
<li><strong>Index</strong>: Another name for the staging area, where Git tracks changes that are ready to be committed.</li>
<li><strong>HEAD</strong>: A reference to the last commit in the currently checked-out branch.</li>
<li><strong>Checkout</strong>: The action of switching from one branch to another or to a specific commit.</li>
<li><strong>Push</strong>: The action of sending your commits to a remote repository.</li>
<li><strong>Pull</strong>: The action of fetching changes from a remote repository and merging them into your current branch.</li>
<li><strong>Fetch</strong>: The action of retrieving updates from a remote repository without merging them into your current branch.</li>
</ul>
<h2 id="what-is-github">What is GitHub?</h2>

<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/GitHub-1.png" alt="GitHub-1" width="600" height="400" loading="lazy"></p>
<p>GitHub is a platform that hosts code, providing version control and collaboration features. It enables you and others to work together on projects from anywhere in the world. </p>
<p>This guide will introduce you to essential GitHub concepts such as <code>repositories</code>, <code>branches</code>, <code>commits</code>, and <code>Pull Requests</code>. You will learn how to create your own 'Hello World' repository and understand GitHub's Pull Request workflow, a widely-used method for creating and reviewing code. </p>
<p>By the end of this guide, you'll be equipped with the knowledge and skills to collaborate effectively on GitHub.</p>
<h2 id="what-is-github-used-for">What is GitHub Used For?</h2>

<p>GitHub is more than just a code hosting platform. It's a tool that allows for seamless collaboration and version control. Here are some of its uses:</p>
<ul>
<li>Hosting and sharing your code with others.</li>
<li>Tracking and assigning issues to maintain an organized workflow.</li>
<li>Managing pull requests to review and incorporate changes into your project.</li>
<li>Creating your own website using GitHub Pages, a static site hosting service.</li>
<li>Collaborating with others on projects, making it an excellent tool for open-source contributions.</li>
</ul>
<h2 id="what-is-git">What is Git?</h2>

<p>Git is a free and open-source distributed version control system. It's designed to handle everything from small to very large projects with speed and efficiency</p>
<p>Git is easy to learn and has a tiny footprint with lightning-fast performance. It outclasses SCM tools like Subversion, CVS, Perforce, and ClearCase with features like cheap local branching, convenient staging areas, and multiple workflows</p>
<p>Git was initially designed and developed by Linus Torvalds for Linux kernel development.</p>
<p>Some features/benefits of Git:</p>
<ul>
<li>Allows you to track changes to your code over time.</li>
<li>Enables you to collaborate with others on the same codebase.</li>
<li>You can easily revert to a previous version of your code or experiment with new features without affecting the main codebase.</li>
<li>Provides a record of all changes made to your code, including who made them and when which can be useful for auditing and debugging.</li>
</ul>
<h2 id="common-tasks-youll-perform-with-git"> Common Tasks You'll Perform with Git </h2>

<ul>
<li>Create a repository</li>
<li>Create a branch</li>
<li>Make changes to a file</li>
<li>Stage changes</li>
<li>Commit changes</li>
<li>Push changes to a remote repository</li>
<li>Merge changes</li>
<li>Revert changes</li>
<li>Delete a branch</li>
</ul>
<h2 id="how-to-install-git">  How to Install Git </h2>

<p>To install Git on your local machine, you need to follow these steps:</p>
<ol>
<li><p>Download Git from the official website: <a target="_blank" href="https://git-scm.com/downloads">Git Downloads</a></p>
</li>
<li><p>Install Git on your local machine by following the instructions provided on the official website: <a target="_blank" href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git">Installing Git</a></p>
</li>
</ol>
<p><em>Congratulations!</em> You have successfully installed Git on your local machine. You are now ready to start using Git for your projects.</p>
<h2 id="how-to-configure-git">  How to Configure Git </h2>

<p>Git offers a variety of configurations that can streamline your workflow. In this section, I will guide you through the process of setting up Git on your local machine. Let's get started.</p>
<p>Configuring your <code>name</code> and <code>email</code> address on your local machine is an essential step in setting up Git. These details are attached to each commit you make, providing context and ownership. Let's learn how to use the <code>git config --global</code> command to set your name and email globally on your local machine.</p>
<p>To set up your name, you need to type the following command in your terminal:</p>
<pre><code class="lang-bash">
<span class="hljs-comment"># Set a name that is identifiable for credit when reviewing version history</span>

$ git config --global user.name <span class="hljs-string">"Your Name"</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/userNameEmail.png" alt="userNameEmail" width="600" height="400" loading="lazy"></p>
<p>As you can see in the image above, I have entered my name.</p>
<p>After entering your name, press <code>Enter</code> to save it. You won't receive any response, but rest assured, your name has been stored successfully.</p>
<p>Just like we set up the user name, we also need to set up the user email. This email will be associated with each commit you make. Let's learn how to use the <code>git config --global</code> command to set your email globally on your local machine.</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Set an email address that will be associated with each history marker</span>
$ git config --global user.email <span class="hljs-string">"your-email@example.com"</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Email.png" alt="Email" width="600" height="400" loading="lazy"></p>
<p>Make sure to replace this with your actual email used in your GitHub account.</p>
<p>Now that we have finished setting up your username and email for Git and GitHub, let's verify that everything is configured correctly.</p>
<p>To do this, use the following command:</p>
<pre><code class="lang-bash">git config --global --list
</code></pre>
<p>This command will list the username and email being used in the console for you to see.</p>
<p>You should see some information displayed in your terminal.</p>
<h2 id="how-to-set-the-default-editor"> How to Set the Default Editor</h2>

<p>In modern development, having a code editor can significantly simplify your workflow, especially when you're focused on coding.</p>
<p>Now, let's see how to configure Git to use a default editor by using this command:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># Set the default editor for Git</span>
$ git config --global core.editor <span class="hljs-string">"code --wait"</span>
</code></pre>
<p><em>Congratulations!</em> You have successfully configured Git on your local machine. You are now ready to start using Git for your projects.</p>
<h2 id="how-to-create-a-repository-using-the-github-website">  How to Create a Repository Using the Github Website </h2>

<p>Creating a repository is the first step in using Git. A repository is a storage location where your projects live, containing all the files and revision history. </p>
<p>In this section, I will guide you through the process of creating a repository on GitHub. </p>
<p>There are two ways to create a repository: using the <code>GitHub website</code> or the command line. Let's get started. In this section, we'll focus on creating a repository using the GitHub website and the command line.</p>
<p>After logging into your GitHub account, you can create a new repository by following these steps:</p>
<ol>
<li>Click on the <code>+</code> sign in the top right corner of the page and select <code>New Repository</code> from the dropdown menu.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Github-create-repo.png" alt="Github-create-repo" width="600" height="400" loading="lazy"></p>
<p>Above is an image of the new repository button on GitHub.</p>
<ol start="2">
<li><p>You will be directed to a new page where you can fill in the details of your new repository. You will need to enter the following information:</p>
</li>
<li><p><code>Repository name</code>: This is the name of your repository. It should be unique and descriptive.</p>
</li>
<li><code>Description</code>: A brief description of your repository.</li>
<li><code>Public or Private</code>: You can choose to make your repository public or private. Public repositories are visible to everyone, while private repositories are only visible to you and the people you share them with.</li>
<li><code>Initialize</code> this repository with a README: You can choose to initialize your repository with a README file. This is useful if you want to provide information about your project or instructions on how to use it.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/github-repo-infor.png" alt="github-repo-infor" width="600" height="400" loading="lazy"></p>
<p>The image above shows the form where you'll fill in the details of your new repository.</p>
<ol start="3">
<li>Once you have filled in the details, click on the <code>Create Repository</code> button to create your new repository.</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/github-create-repo-button.png" alt="github-create-repo-button" width="600" height="400" loading="lazy"></p>
<p>The image above shows the <code>Create Repository</code> button_.</p>
<p><em>Congratulations!</em> You have successfully created a new repository on GitHub. You can now start adding files and making changes to your repository.</p>
<p>You should see a page like the one below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/github-new-repo.png" alt="github-new-repo" width="600" height="400" loading="lazy"></p>
<p>Now let's create a repository using the command line.</p>
<h2 id="how-to-create-a-repository-using-the-git-command-line">  How to Create a Repository Using the Git Command Line </h2>


<p>To create a new <code>repository</code> using the command line, you need to follow these steps:</p>
<ol>
<li><p>Open your terminal and navigate to the directory where you want to create your new repository.</p>
</li>
<li><p>Use the <code>git init</code> command to create a new repository. This command will create a new directory called <code>.git</code> in your current directory, which will contain all the necessary files for your repository.</p>
</li>
</ol>
<pre><code class="lang-bash">
<span class="hljs-comment"># initialize a new repository called my-project</span>

$ git init my-project
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/terminal-init.png" alt="terminal-init" width="600" height="400" loading="lazy"></p>
<p>The image above shows the command to initialize a new repository called <code>my-project</code>.</p>
<ol start="3">
<li>Once you have created your new repository, you can start adding files and making changes to it. You can also connect your local repository to a remote repository on GitHub by following the instructions provided on the GitHub website.</li>
</ol>
<p><em>Congratulations!</em> You have successfully created a new repository using the command line. </p>
<p>Now we have successfully created a repository using the GitHub website and the command line – but how do we connect them? Now let's learn how to connect a local repository to a remote repository on GitHub.</p>
<h2 id="how-to-connect-a-local-repository-to-a-remote-repository-on-github">  How to Connect a Local Repository to a Remote Repository on GitHub </h2>

<p>To connect your local repository to a remote repository on GitHub, you need to follow these steps:</p>
<ol>
<li><p>On GitHub, navigate to the main page of the repository you created earlier.</p>
</li>
<li><p>Click on the <code>Code</code> button to copy the URL of your repository.</p>
</li>
</ol>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/Github-code-url-cope.png" alt="Github-code-url-cope" width="600" height="400" loading="lazy"></p>
<p>The image above shows the code button to copy the URL of your repository.</p>
<ol start="3">
<li><p>In your terminal, navigate to the directory of your local repository.</p>
</li>
<li><p>Use the <code>git remote add origin</code> command to connect your local repository to the remote repository on GitHub. Replace repository-URL with the URL of your repository.</p>
</li>
</ol>
<pre><code class="lang-bash">$ git remote add origin repository-url
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/terminal-remote-add-origin.png" alt="terminal-remote-add-origin" width="600" height="400" loading="lazy"></p>
<p>The image above shows the command to connect your local repository to the remote repository on GitHub.</p>
<ol start="5">
<li>Once you have connected your local repository to the remote repository on GitHub, you can start pushing your changes to the remote repository using the <code>git push</code> command.</li>
</ol>
<p><em>Congratulations!</em> You have successfully connected your local repository to the remote repository on GitHub.</p>
<h2 id="how-to-pull-changes-from-a-remote-repository-to-a-local-repository">   How to Pull Changes from a Remote Repository to a Local Repository </h2>

<p>To pull changes from the remote repository to the local repository, you need to follow these steps:</p>
<ol>
<li><p>In your terminal, navigate to the directory of your local repository.</p>
</li>
<li><p>Use the <code>git pull</code> command to pull changes from the remote repository to the local repository.</p>
</li>
</ol>
<pre><code class="lang-bash">
$ git pull origin main
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/terminal-git-pull.png" alt="terminal-git-pull" width="600" height="400" loading="lazy"></p>
<p>The image above shows the command to pull changes from the remote repository to the local repository.</p>
<p>After that, navigate the main branch by using the following command:</p>
<pre><code class="lang-bash">
$ git checkout main
</code></pre>
<p><em>Congratulations!</em> You have successfully pulled changes from a remote repository to a local repository. Your local repository is now up-to-date with the remote repository on GitHub*.</p>
<h2 id="how-to-work-with-git-commands"> How to Work with Git Commands </h2>

<p>In this section, we will cover some of the most commonly used Git commands and their functions. These commands will help you navigate your way through the Git workflow in your GitHub repository. Let's get started. </p>
<p>First, I will add some files so that we can start using the Git commands.</p>
<h2 id="how-to-make-changes-to-a-file"> How to Make Changes to a File </h2>

<p>To make changes to a file in Git, you need to follow these steps:</p>
<ol>
<li><p>Open your terminal and navigate to the directory of your local repository.</p>
</li>
<li><p>Use a text editor to make changes to the file. For example, you can use the <code>code</code> command to open the file in Visual Studio Code.</p>
</li>
</ol>
<pre><code class="lang-bash">
$ code file-name  <span class="hljs-comment"># For example, code index.html</span>
</code></pre>
<ol start="3">
<li>Once you have made your changes, save the file and close the text editor.</li>
</ol>
<p><em>Congratulations!</em> You have successfully made changes to a file in your local repository. Next, let's proceed to the next step: staging changes.</p>

<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/file-cahnge-added.png" alt="file-cahnge-added" width="600" height="400" loading="lazy"></p>
<p>The image above shows the new file I added which is a React and TypeScript app.</p>
<p>Visual Studio Code (VS Code) includes a source control feature that allows you to interact directly with your GitHub repository. This feature supports a variety of operations, including staging, committing, pushing, and pulling changes. </p>
<p>In addition to the source control feature, you can also use the integrated terminal in VS Code to interact with your GitHub repository. </p>
<p>Currently, if you look at the source control section in VS Code, you'll see the file we added listed under changes. </p>
<p>Next, let's explore how to use the terminal to interact with our GitHub repository.</p>
<p>Open your terminal and navigate to the directory of your local repository.</p>
<p>Now, let's use the <code>git status</code> command to check the status of the current branch.</p>
<h2 id="how-to-check-the-status-of-the-current-branch">  How to Check the Status of the Current Branch </h2>

<p>The <code>git status</code> command shows the status of the current branch, including any changes that have been made to the files in the repository. It provides information about which files have been modified, which files have been staged, and which files are untracked. </p>
<p>This command is useful for understanding the current state of your repository and determining which files need to be staged and committed.</p>
<pre><code class="lang-bash"><span class="hljs-comment">#  Check the status of the current branch</span>

$ git status  <span class="hljs-comment"># On branch master</span>
</code></pre>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/terminal-git-status.png" alt="terminal-git-status" width="600" height="400" loading="lazy"></p>
<p>The image above shows the command to check the status of the current branch.</p>
<p>You may notice that parts of the file are highlighted in different colors. The <code>red</code> color indicates that the file has been modified, while the <code>green</code> color signifies that the file has been added to the staging area. </p>
<p>Currently, all files should be highlighted in <code>red</code> because we have not yet added any files to the staging area.</p>
<p>Let's add the file to the staging area using the <code>git add</code> command.</p>
<h2 id="how-to-stage-changes">  How to Stage Changes </h2>

<p>The <code>git add</code> command adds files to the staging area, preparing them for the next commit. You can add all the files in the current directory to the staging area using the <code>git add .</code> command. </p>
<p>If you want to add a specific file, use the <code>git add &lt;file-name&gt;</code> command, replacing <code>&lt;file-name&gt;</code> with the name of your file. This process is known as staging, which prepares files for the next commit.</p>
<pre><code class="lang-bash">
<span class="hljs-comment"># Add files to the staging area</span>

$ git add .  <span class="hljs-comment"># Changes to be committed:</span>

or 

$ git add file-name  <span class="hljs-comment"># Changes to be committed:</span>
</code></pre>
<p>Think of it like this: getting into the car is like adding files to the staging area, and driving the car is like making a commit. </p>
<p>Now, let's use the <code>git commit</code> command to commit the changes to the current branch.</p>
<h2 id="how-to-commit-changes">  How to Commit Changes </h2>

<p>The <code>git commit</code> command commits the changes to the current branch. You can use the <code>-m</code> flag to add a message to your commit. This message should provide a brief summary of the changes you've made.</p>
<p>For instance, "Initial commit" could be your commit message. This command is used to save the changes to the local repository.</p>
<pre><code class="lang-bash">

<span class="hljs-comment"># Commit changes to the current branch</span>

$ git commit -m <span class="hljs-string">"Commit message"</span>   <span class="hljs-comment"># For example, git commit -m "Initial commit"</span>
</code></pre>
<p>We've successfully committed the changes to the current branch. Next, we'll push these changes to the remote repository on GitHub using the <code>git push</code> command.</p>
<h2 id="how-to-push-changes-to-a-remote-repository">  How to Push Changes to a Remote Repository </h2>

<p>The <code>git push</code> command pushes changes from your local repository to a remote repository on GitHub. You can use the <code>git push</code> command to push changes from your local repository to the remote repository on GitHub. This process is essential for updating the remote repository with the changes you've made locally.</p>
<pre><code class="lang-bash">
<span class="hljs-comment"># Push changes to a remote repository</span>

$ git push origin main  <span class="hljs-comment"># For example, git push origin master</span>
</code></pre>
<p><em>Congratulations!</em> You have successfully pushed your changes to the remote repository on GitHub. You can now view your changes on the GitHub website.  </p>
<p>Now that we've successfully pushed our changes to the remote repository on GitHub, let's proceed to the next step: creating a branch. </p>
<p>Depending on your PC environment, your local repository may have a default branch named either <code>main</code> or <code>master</code>. In this guide, we'll use <code>main</code> as the default branch name, aligning with GitHub's recent change from <code>master</code> to <code>main</code>.</p>
<p>Before we start adding files, let's ensure our local repository is up-to-date with the remote repository by pulling any changes. </p>
<p>If the term <code>branch</code> seems unfamiliar, don't worry. In the next section, we'll cover how to create a branch and how to pull changes from the remote repository to the local repository.</p>
<h2 id="how-to-create-a-branch">  How to Create a Branch </h2>

<p>Branching is a fundamental concept in Git. It allows you to diverge from the main line of development and continue working without impacting the main codebase. </p>
<p>In this section, I'll guide you through the process of creating a new branch using the <code>git branch</code> command. This command creates a new branch but does not switch to it. In the following steps, we'll also cover how to switch to your newly created branch using the <code>git checkout</code> command. Let's dive in.</p>
<p>To create a new branch, you need to follow these steps:</p>
<ol>
<li><p>Open your terminal and navigate to the directory of your local repository.</p>
</li>
<li><p>Use the <code>git branch</code> command to create a new branch. Replace <code>&lt;branch-name&gt;</code> with the name of your new branch.</p>
</li>
</ol>
<pre><code class="lang-bash">
<span class="hljs-comment"># Create a new branch</span>

$ git branch &lt;branch-name&gt;  <span class="hljs-comment"># For example, git branch feature-branch</span>
</code></pre>
<p>The <code>git branch</code> command creates a new branch but does not switch to it. To switch to your newly created branch, use the <code>git checkout</code> command.</p>
<pre><code class="lang-bash">
<span class="hljs-comment"># Switch to the newly created branch</span>

$ git checkout &lt;branch-name&gt;  <span class="hljs-comment"># For example, git checkout feature-branch</span>
</code></pre>
<p>The <code>git checkout</code> command is used to switch from one branch to another. Replace <code>&lt;branch-name&gt;</code> with the name of your new branch. In this case, we're switching to the <code>feature-branch</code> branch. But we if want to delete the branch, we can use the following command:</p>
<pre><code class="lang-bash">

<span class="hljs-comment"># Delete a branch</span>

$ git branch -d &lt;branch-name&gt;  <span class="hljs-comment"># For example, git branch -d feature-branch</span>
</code></pre>
<p>The <code>git branch -d</code> command is used to delete a branch. Replace <code>&lt;branch-name&gt;</code> with the name of the branch you want to delete. In this case, we're deleting the <code>feature-branch</code> branch.</p>
<p><em>Congratulations!</em> You have successfully created a new branch and switched to it. You can now start adding files and making changes to your new branch.</p>
<p>Now you know how to create GitHub repository, connect a local repository to a remote repository on GitHub, pull changes from a remote repository to a local repository, work with Git commands, and create a branch. </p>
<p>Let's proceed to the next section, where we'll cover how to create a pull request. This is a crucial step in the collaborative workflow, as it allows you to propose changes and request a review from other collaborators.</p>
 <h2 id="how-to-create-a-pull-request"> How to Create a Pull Request  </h2>

<p>A pull request is a proposal to merge changes from one branch into another. It's a widely-used method for creating and reviewing code. In this section, I'll guide you through the process of creating a pull request using the GitHub website. </p>
<p>For instance, let's say you have a branch named <code>feature-branch</code> and you want to merge it into the <code>main</code> branch. We'll walk you through how to create a pull request for this scenario. Let's get started.</p>
<p>First, let's make a change to our feature branch by adding a file to it:</p>
<pre><code class="lang-bash">
$ git checkout feature-branch
</code></pre>
<p>You should see something like this in your terminal:</p>
<pre><code class="lang-bash">
git checkout feature-branch
Switched to a new branch <span class="hljs-string">'feature-branch'</span>
branch <span class="hljs-string">'feature-branch'</span> <span class="hljs-built_in">set</span> up to track <span class="hljs-string">'origin/feature-branch'</span>.
</code></pre>
<p>Now, let's add a file to the feature branch. </p>
<pre><code class="lang-bash">
$ touch feature-branch-file.txt
</code></pre>
<p>After running the command, you should see a new file called <code>feature-branch-file.txt</code> in your directory.</p>
<p>The <code>touch</code> command is used to create a new file. Replace <code>feature-branch-file.txt</code> with the name of your file. In this case, we're creating a new file called <code>feature-branch-file.txt</code>.</p>
<p>Now, let's add some content to the file.</p>
<pre><code class="lang-bash">
$ <span class="hljs-built_in">echo</span> <span class="hljs-string">"This is a file in the feature branch"</span> &gt;&gt; feature-branch-file.txt
</code></pre>
<p>This command adds the text "This is a file in the feature branch" to the <code>feature-branch-file.txt</code> file.</p>
<p>The <code>echo</code> command is used to add content to a file. In this case, we're adding the text "This is a file in the feature branch" to the <code>feature-branch-file.txt</code> file.</p>
<p>Now that we have some text in the file, let's stage and commit the changes to the feature branch.</p>
<pre><code class="lang-bash">
$ git add .
</code></pre>
<p>The <code>git add .</code> command stages all the changes in the current directory.</p>
<pre><code class="lang-bash">

$ git commit -m <span class="hljs-string">"Add file to feature branch"</span>
</code></pre>
<p>The <code>git commit -m</code> command commits the changes to the current branch. Replace <code>Add file to feature branch</code> with your own descriptive message. This message should provide a brief summary of the changes you've made. In this case, we're committing the changes to the feature branch.</p>
<p>Now, let's push the changes to the remote repository on GitHub.</p>
<pre><code class="lang-bash">
$ git push origin feature-branch
</code></pre>
<p>The <code>git push</code> command is used to push changes from your local repository to the remote repository on GitHub. Replace <code>feature-branch</code> with the name of your branch. In this case, we're pushing the changes to the <code>feature-branch</code> branch.</p>
<p><em>Congratulations!</em> You have successfully pushed your changes to the remote repository on GitHub. You can now view your changes on the GitHub website.</p>
<p>Now when you open your GitHub repository, you should see a message indicating that you recently pushed a new branch. You can click on the <code>Compare &amp; pull request</code> button to create a pull request for the <code>feature-branch</code> branch. </p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/github-compare-pull-request.png" alt="github-compare-pull-request" width="600" height="400" loading="lazy"></p>
<p>The image above shows the <code>Compare &amp; pull request</code> button on GitHub.</p>
<p>After clicking on the <code>Compare &amp; pull request</code> button, you will be directed to a new page where you can fill in the details of your pull request. </p>
<p>You will need to enter the following information:</p>
<ul>
<li>Title: a brief summary of your pull request.</li>
<li>Description: a detailed description of your pull request, including information about the changes you've made and why you've made them.</li>
<li>Reviewers: you can choose to request a review from specific collaborators.</li>
<li>Assignees: you can choose to assign your pull request to specific collaborators.</li>
<li>Labels: you can choose to add labels to your pull request to categorize it.</li>
<li>Projects: you can choose to add your pull request to a project board.</li>
<li>Milestone: you can choose to add your pull request to a milestone.</li>
</ul>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/github-pull-request-form.png" alt="github-pull-request-form" width="600" height="400" loading="lazy"></p>
<p>The image above shows the form to fill in the details of your pull request.</p>
<p>You can decide to file the details of your pull request or create the pull request. After creating the pull request, you can view it on the GitHub website. You can also request a review from specific collaborators and make changes to your pull request if necessary. </p>
<p>Once your pull request has been reviewed and approved, you can merge it into the <code>main</code> branch. In our case we not going to file the form but we are going to create the pull request.</p>

<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/github-pull-request-created.png" alt="github-pull-request-created" width="600" height="400" loading="lazy"></p>
<p>The image above shows the pull request created on GitHub.</p>
<p>Now that we have created a pull request, let's proceed to the next section, where we'll cover how to merge a pull request. This is the final step in the collaborative workflow, as it allows you to incorporate changes into the main codebase.</p>
<h2 id="how-to-merge-a-pull-request">How to Merge a Pull Requset  </h2>

<p>Merging a pull request signifies the integration of changes from one branch into another, often the main branch. This step is pivotal in collaborative workflows, enabling the assimilation of modifications into the primary codebase. </p>
<p>In this section, we'll navigate the process of merging a pull request via the GitHub website. </p>
<p>After creating a pull request, you can merge it into the <code>main</code> branch by following these steps:</p>
<ol>
<li><p>On GitHub, navigate to the main page of the repository where you created the pull request.</p>
</li>
<li><p>Click on the <code>Pull requests</code> tab to view the list of pull requests.</p>
</li>
</ol>

<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/github-pull-request-tab.png" alt="github-pull-request-tab" width="600" height="400" loading="lazy"></p>
<p>The image above shows the <code>Pull requests</code> tab on GitHub.</p>
<ol start="3">
<li><p>Click on the pull request you want to merge.</p>
</li>
<li><p>Click on the <code>Merge pull request</code> button to merge the pull request into the <code>main</code> branch.</p>
</li>
<li><p>Click on the <code>Confirm merge</code> button to confirm the merge.</p>
</li>
</ol>
<p>After that you should see a message indicating that the pull request has been successfully merged. You can also delete the branch after merging the pull request.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/04/github-pull-request-merged.png" alt="github-pull-request-merged" width="600" height="400" loading="lazy"></p>
<p>Now you have successfully merged the pull request into the <code>main</code> branch. You can now delete the <code>feature-branch</code> branch, as it is no longer needed.  </p>
 <h2 id="wrapping-up"> Wrapping Up </h2>

<p>Throughout this guide, we've delved into the core concepts of Git and GitHub, equipping you with a robust understanding of version control and collaborative practices. </p>
<p>We've navigated the essential Git operations, including setting up a repository, linking the local repository to its remote counterpart on GitHub, synchronizing changes between the local and remote repositories, executing Git commands, branching, initiating pull requests, and merging those requests. </p>
<p>Mastering these principles will significantly enhance your coding workflow, facilitate seamless team collaboration, and enable meaningful contributions to open-source projects. </p>
<p>I trust that this guide has instilled in you the knowledge and confidence to excel in your programming journey and start contributing to open source projects. Here's to your success in coding!</p>
<p>You can contact me on <a target="_blank" href="https://twitter.com/Clifftech_Dev">Twitter</a> or <a target="_blank" href="https://www.linkedin.com/in/isaiah-clifford-opoku/">LinkedIn</a> for any questions or feedback. I'd love to hear from you!</p>
 ]]>
                </content:encoded>
            </item>
        
            <item>
                <title>
                    <![CDATA[ How to Build a CRUD REST API with NestJS, Docker, Swagger, and Prisma ]]>
                </title>
                <description>
                    <![CDATA[ Welcome to this in-depth guide on crafting a RESTful API with NestJS, Docker, Swagger, and Prisma. My goal here is to teach you how to build robust and efficient backends, regardless of whether you're a seasoned developer or a beginner just dipping y... ]]>
                </description>
                <link>https://www.freecodecamp.org/news/build-a-crud-rest-api-with-nestjs-docker-swagger-prisma/</link>
                <guid isPermaLink="false">66bb56f70da5b03e481107bf</guid>
                
                    <category>
                        <![CDATA[ crud ]]>
                    </category>
                
                    <category>
                        <![CDATA[ Docker ]]>
                    </category>
                
                    <category>
                        <![CDATA[ handbook ]]>
                    </category>
                
                    <category>
                        <![CDATA[ nestjs ]]>
                    </category>
                
                    <category>
                        <![CDATA[ REST API ]]>
                    </category>
                
                <dc:creator>
                    <![CDATA[ Isaiah Clifford Opoku ]]>
                </dc:creator>
                <pubDate>Tue, 23 Jan 2024 00:17:33 +0000</pubDate>
                <media:content url="https://www.freecodecamp.org/news/content/images/2024/01/Nestjs_Free_code.png" medium="image" />
                <content:encoded>
                    <![CDATA[ <p>Welcome to this in-depth guide on crafting a RESTful API with NestJS, Docker, Swagger, and Prisma. My goal here is to teach you how to build robust and efficient backends, regardless of whether you're a seasoned developer or a beginner just dipping your toes into the world of coding.</p>
<p>In this journey, we'll be creating a delightful recipe management system. We'll explore the power of NestJS, Docker, Swagger, and Prisma, and harness these cutting-edge technologies to implement CRUD (Create, Read, Update, Delete) operations for managing recipes.</p>
<p>But this tutorial isn't just for the culinary enthusiasts or recipe collectors out there. It's for anyone who's passionate about learning and growing their development skills. </p>
<p>So, buckle up and get ready for an exciting coding adventure as we dive in and start building your very own recipe management system together.</p>
<p>This is what we'll build:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/all-for-swagger-end-product.png" alt="REST API ALL  " width="600" height="400" loading="lazy">
<em>A snapshot of the Swagger UI showcasing all the implemented endpoints.</em></p>
<p>And here's what we'll cover:</p>
<h2 id="heading-table-of-contents">Table of Contents</h2>
<ul>
<li><a class="post-section-overview" href="#heading-technologies">Technologies</a></li>
<li><a class="post-section-overview" href="#heading-prerequisites">Prerequisites</a></li>
<li><a class="post-section-overview" href="#heading-development-environment">Development Environment</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-the-nestjs-project">How to Set Up the NestJS Project</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-postgresql-instance-with-docker">How to Create a PostgreSQL Instance with Docker</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-prisma">How to Set Up Prisma</a></li>
<li><a class="post-section-overview" href="#heading-how-to-initialize-prisma">How to Initialize Prisma</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-your-environment-variable">How to Set Your Environment Variable</a></li>
<li><a class="post-section-overview" href="#heading-understanding-the-prisma-schema">Understanding the Prisma Schema</a></li>
<li><a class="post-section-overview" href="#heading-how-to-model-the-data">How to Model the Data</a></li>
<li><a class="post-section-overview" href="#heading-how-to-migrate-the-database">How to Migrate the Database</a></li>
<li><a class="post-section-overview" href="#heading-how-to-seed-the-database">How to Seed the Database</a></li>
<li><a class="post-section-overview" href="#heading-how-to-create-a-prisma-service">How to Create a Prisma Service</a></li>
<li><a class="post-section-overview" href="#heading-how-to-set-up-swagger">How to Set Up Swagger</a></li>
<li><a class="post-section-overview" href="#heading-how-to-implement-crud-operations-for-the-recipe-model">How to Implement CRUD Operations for the Recipe Model</a></li>
<li><a class="post-section-overview" href="#heading-how-to-generate-rest-resources-with-nestjs-cli">How to Generate REST Resources with NestJS CLI</a></li>
<li><a class="post-section-overview" href="#heading-how-to-add-prismaclient-to-the-recipe-module">How to Add PrismaClient to the Recipe Module</a></li>
<li><a class="post-section-overview" href="#heading-how-to-define-the-get-recipes-endpoint">How to Define the GET /recipes Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-how-to-define-the-get-recipesid-endpoint">How to Define the GET /recipes/:id Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-how-to-define-the-post-recipes-endpoint">How to Define the POST /recipes Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-how-to-define-the-patch-recipesid-endpoint">How to Define the PATCH /recipes/:id Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-how-to-define-the-delete-recipesid-endpoint">How to Define the DELETE /recipes/:id Endpoint</a></li>
<li><a class="post-section-overview" href="#heading-summary-and-final-remarks">Summary and Final Remarks</a></li>
</ul>
<h2 id="heading-technologies">Technologies</h2>
<p>To build this application, we'll be leveraging the power of the following tools:</p>
<ul>
<li><strong><a target="_blank" href="https://nestjs.com/">NestJS</a></strong>: A progressive Node.js framework for building efficient, reliable, and scalable server-side applications.</li>
<li><strong><a target="_blank" href="https://www.prisma.io/">Prisma</a></strong>: An open-source database toolkit that makes it easy to reason about your data and how you interact with it.</li>
<li><strong><a target="_blank" href="https://www.postgresql.org/">PostgreSQL</a></strong>: A powerful, open source object-relational database system.</li>
<li><strong><a target="_blank" href="https://www.docker.com/">Docker</a></strong>: An open platform for developing, shipping, and running applications. Docker enables you to separate your applications from your infrastructure so you can deliver software quickly.</li>
<li><strong><a target="_blank" href="https://swagger.io/">Swagger</a></strong>: A tool for designing, building, and documenting RESTful APIs.</li>
<li><strong><a target="_blank" href="https://www.typescriptlang.org/">TypeScript</a></strong>: A statically typed superset of JavaScript that adds optional types, classes, and modules to the language.</li>
</ul>
<p>Each of these technologies plays a crucial role in creating a robust, scalable, and maintainable application. We'll dive deeper into each one as we proceed.</p>
<h2 id="heading-prerequisites">Prerequisites</h2>
<h3 id="heading-assumed-knowledge">Assumed Knowledge</h3>
<p>This tutorial is designed to be beginner-friendly, but I do make a few assumptions about what you already know:</p>
<ul>
<li>Fundamentals of TypeScript</li>
<li>Basics of NestJS</li>
<li>Docker</li>
</ul>
<p>If you're not familiar with these, don't fret! I've got you covered. This tutorial will guide you through everything you need to know. </p>
<p>But here are some more resources if you'd like to learn more:</p>
<ul>
<li>For a deeper dive into NestJS, feel free to explore the <a target="_blank" href="https://docs.nestjs.com/">official NestJS documentation</a>.</li>
<li>To learn more about Docker, here's a <a target="_blank" href="https://www.freecodecamp.org/news/the-docker-handbook/">full handbook for beginners</a>.</li>
<li>And for more info on TypeScript, here's a <a target="_blank" href="https://www.freecodecamp.org/news/learn-typescript-with-this-crash-course/">helpful crash course</a>.</li>
</ul>
<h2 id="heading-development-environment">Development Environment</h2>
<h3 id="heading-tools-and-technologies">Tools and Technologies</h3>
<p>In this tutorial, we'll use the following tools:</p>
<ul>
<li><a target="_blank" href="https://nodejs.org/en/download/">Node.js</a> – Our runtime environment</li>
<li><a target="_blank" href="https://www.docker.com/get-started/">Docker</a> – For containerizing our database</li>
<li><a target="_blank" href="https://code.visualstudio.com/Download">Visual Studio Code</a> – Our code editor</li>
<li><a target="_blank" href="https://www.postgresql.org/download/">PostgreSQL</a> – Our database</li>
<li><a target="_blank" href="https://docs.nestjs.com/">NestJS</a> – Our Node.js framework</li>
</ul>
<p><strong>Note:</strong> Don't forget to install the Prisma extension for Visual Studio Code. It enhances your coding experience by highlighting Prisma-specific syntax and keywords.</p>
<h2 id="heading-how-to-set-up-the-nestjs-project">How to Set Up the NestJS Project</h2>
<p>NestJS is a progressive Node.js framework that comes with a plethora of advantages, including a powerful Command Line Interface (CLI). This CLI simplifies the process of creating a new NestJS application, making it easy to start a new project anytime, anywhere.</p>
<p>One of the key benefits of NestJS is its rich set of built-in functionalities that significantly streamline the development process, making your life as a developer much easier.</p>
<p>Let's begin by installing the NestJS CLI on your system:</p>
<pre><code class="lang-bash">npm i -g @nestjs/cli
</code></pre>
<p>With the NestJS CLI installed, you're all set to whip up our recipe project. The CLI streamlines the creation of a new NestJS application, making it simple to get started. </p>
<p>To spin up a new project, execute the following command:</p>
<pre><code class="lang-bash">nest new recipe
</code></pre>
<p>After running this command, you'll encounter a prompt like the one you see below:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Settting-nest.png" alt="Nest CLI Package Manager Prompt" width="600" height="400" loading="lazy">
<em>The Nest CLI prompting for a package manager selection during project setup.</em></p>
<p>As illustrated in the image, the Nest CLI will prompt you to select a package manager. For this project, we'll opt for <code>npm</code>. Once you've made your selection, the CLI will proceed with the project setup, and you'll see a series of operations being performed in your terminal.</p>
<p>Now you can open you project in VSCode (or the editor of your choice). You should see the following files:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/After-setting-up-nejst.png" alt="Nest CLI Package Manager Prompt" width="600" height="400" loading="lazy">
<em>The folder structure of the project after it has been created using Nest CLI.</em></p>
<p>Let break down the project structure:</p>
<table>
<thead>
<tr>
<th>Directory/File</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>recipe/</code></td>
<td>Root directory of the project.</td>
</tr>
<tr>
<td><code>├── node_modules/</code></td>
<td>Contains all the npm packages required for the project.</td>
</tr>
<tr>
<td><code>├── src/</code></td>
<td>Contains the source code of the application.</td>
</tr>
<tr>
<td><code>│ ├── app.controller.spec.ts</code></td>
<td>Contains the tests for <code>app.controller.ts</code>.</td>
</tr>
<tr>
<td><code>│ ├── app.controller.ts</code></td>
<td>Contains a basic controller with a single route.</td>
</tr>
<tr>
<td><code>│ ├── app.module.ts</code></td>
<td>The root module of the application.</td>
</tr>
<tr>
<td><code>│ ├── app.service.ts</code></td>
<td>Contains the services used by <code>app.controller.ts</code>.</td>
</tr>
<tr>
<td><code>│ └── main.ts</code></td>
<td>The entry point of the application.</td>
</tr>
<tr>
<td><code>├── test/</code></td>
<td>Contains the end-to-end tests for the application.</td>
</tr>
<tr>
<td><code>│ ├── app.e2e-spec.ts</code></td>
<td>Contains the end-to-end tests for <code>app.controller.ts</code>.</td>
</tr>
<tr>
<td><code>│ └── jest-e2e.json</code></td>
<td>Contains the configuration for the end-to-end tests.</td>
</tr>
<tr>
<td><code>├── README.md</code></td>
<td>The readme file for the project.</td>
</tr>
<tr>
<td><code>├── nest-cli.json</code></td>
<td>Contains the configuration for the NestJS CLI.</td>
</tr>
<tr>
<td><code>├── package-lock.json</code></td>
<td>Contains the exact versions of the npm packages used in the project.</td>
</tr>
<tr>
<td><code>├── package.json</code></td>
<td>Lists the npm packages required for the project.</td>
</tr>
<tr>
<td><code>└── tsconfig.build.json</code></td>
<td>Contains the TypeScript compiler options for the build.</td>
</tr>
</tbody>
</table>

<p>The <code>src</code> directory is the nerve center of our application, hosting the bulk of our codebase. The NestJS CLI has already set the stage for us with several key files:</p>
<ul>
<li><code>src/app.module.ts</code>: This is the root module of our application, serving as the main junction for all other modules.</li>
<li><code>src/app.controller.ts</code>: This file houses a basic controller with a single route: <code>/.</code> When accessed, this route will return a simple 'Hello World!' message.</li>
<li><code>src/main.ts</code>: This is the gateway to our application. It's tasked with bootstrapping and launching the NestJS application.</li>
</ul>
<p>To start your project and see the 'Hello World!' message in action, execute the following command:</p>
<pre><code class="lang-bash">npm run start:dev
</code></pre>
<p>This command triggers a live-reload development server. It vigilantly monitors your files, and if it spots any modifications, it automatically recompile your code and refreshes the server. This ensures that you can see your changes in real-time, eliminating the need for manual restarts.</p>
<p>To verify that your server is operational, head over to <code>http://localhost:3000/</code> in your web browser or Postman. You should be welcomed by a minimalist page showcasing the message <code>Hello World</code>. This is your application's default landing page, a pristine canvas awaiting your creative touch.</p>
<h2 id="heading-how-to-create-a-postgresql-instance-with-docker">How to Create a PostgreSQL Instance with Docker</h2>
<p>To store our recipes REST API, we'll use a PostgreSQL database. Docker will help us containerize this database, ensuring a smooth setup and execution, regardless of the environment.</p>
<p>First, ensure Docker is installed on your system. If not, follow the instructions <a target="_blank" href="https://www.docker.com/get-started">here</a>.</p>
<p>Next, you'll need to create a <code>docker-compose.yml</code> file.</p>
<p>Open the terminal and run the following command:</p>
<pre><code class="lang-bash">touch docker-compose.yml
</code></pre>
<p>This command creates a new <code>docker-compose.yml</code> file in your project's root directory.</p>
<p>Open the <code>docker-compose.yml</code> file and add the following code:</p>
<pre><code class="lang-bash"><span class="hljs-comment"># docker-compose.yml</span>

version: <span class="hljs-string">'3.8'</span>
services:
  postgres:
    image: postgres:13.5
    restart: always
    environment:
      - POSTGRES_USER=recipe
      - POSTGRES_PASSWORD=RecipePassword
    volumes:
      - postgres:/var/lib/postgresql/data
    ports:
      - <span class="hljs-string">'5432:5432'</span>
volumes:
  postgres:
</code></pre>
<p>Here's a quick breakdown of this configuration:</p>
<ul>
<li><code>image: postgres:13.5</code>: Specifies the Docker image for the PostgreSQL database.</li>
<li><code>restart: always</code>: Ensures the container restarts if it stops.</li>
<li><code>environment</code>: Sets the username and password for the database.</li>
<li><code>volumes</code>: Mounts a volume to persist database data, even if the container is stopped or removed.</li>
<li><code>ports</code>: Exposes port <code>5432</code> on both the host machine and the container for database access.</li>
</ul>
<p>Note: If you wish to use a different port, simply change the host machine port. For example, to use port <code>5433</code>, modify the <code>ports</code> section as follows:</p>
<pre><code class="lang-bash">ports:
  - <span class="hljs-string">'5444:5432'</span>
</code></pre>
<p>Note: Before proceeding, ensure port <code>5432</code> is free on your machine. To fire up the PostgreSQL container, execute the following command in your project's root directory (and also make sure you have open the docker desktop app and it is running):</p>
<pre><code class="lang-bash">docker-compose up
</code></pre>
<p>This command spins up the PostgreSQL container and makes it accessible on port <code>5432</code> of your machine. If all goes according to plan, you should see output similar to this:</p>
<pre><code class="lang-bash">...
 | PostgreSQL init process complete; ready <span class="hljs-keyword">for</span> start up.
postgres-1  |
postgres-1  | 2024-01-12 14:59:33.519 UTC [1] LOG:  starting PostgreSQL 13.5 (Debian 13.5-1.pgdg110+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 10.2.1-6) 10.2.1 20210110, 64-bit
postgres-1  | 2024-01-12 14:59:33.520 UTC [1] LOG:  listening on IPv4 address <span class="hljs-string">"0.0.0.0"</span>, port 5432
postgres-1  | 2024-01-12 14:59:33.520 UTC [1] LOG:  listening on IPv6 address <span class="hljs-string">"::"</span>, port 5432
postgres-1  | 2024-01-12 14:59:33.526 UTC [1] LOG:  listening on Unix socket <span class="hljs-string">"/var/run/postgresql/.s.PGSQL.5432"</span>
postgres-1  | 2024-01-12 14:59:33.533 UTC [62] LOG:  database system was shut down at 2024-01-12 14:59:33 UTC
postgres-1  | 2024-01-12 14:59:33.550 UTC [1] LOG:  database system is ready to accept connections
</code></pre>
<p>Remember, if you've changed the port number, the output will reflect your chosen port.</p>
<p>If the port is already in use, you'll encounter an error message like this:</p>
<pre><code class="lang-bash">Error starting userland proxy: listen tcp 0.0.0.0:5432: <span class="hljs-built_in">bind</span>: address already <span class="hljs-keyword">in</span> use
</code></pre>
<p>In such a case, free up the port or choose a different one in your <code>docker-compose.yml</code> file.</p>
<p>Note: if you close the terminal window, it will also stop the container. To prevent this, you can run the container in detached mode. This mode allows the container to run indefinitely in the background. </p>
<p>To do this, add a <code>-d</code> option at the end of the command, like so:</p>
<pre><code class="lang-bash">docker-compose up -d
</code></pre>
<p>To stop the container, use the following command:</p>
<pre><code class="lang-bash">docker-compose down
</code></pre>
<p>Congratulations 🎉. You now have your own PostgreSQL database to play around with.</p>
<h2 id="heading-how-to-set-up-prisma">How to Set Up Prisma</h2>
<p>Now that we have our PostgreSQL database up and running, we're ready to set up Prisma. Prisma is an open-source database toolkit that makes it easy to reason about your data and how you interact with it.</p>
<p>Prisma is a powerful tool that offers a wide range of features, including:</p>
<ul>
<li><strong>Database Migrations</strong>: Prisma makes it easy to evolve your database schema over time, without losing any data.</li>
<li><strong>Database Seeding</strong>: Prisma allows you to seed your database with test data.</li>
<li><strong>Database Access</strong>: Prisma provides a powerful API for accessing your database.</li>
<li><strong>Database Schema Management</strong>: Prisma allows you to define your database schema using the Prisma Schema Language.</li>
<li><strong>Database Querying</strong>: Prisma provides a powerful API for querying your database.</li>
<li><strong>Database Relationships</strong>: Prisma allows you to define relationships between your database tables.</li>
</ul>
<p>You can learn more about Prisma <a target="_blank" href="https://www.prisma.io/">here</a>.</p>
<h3 id="heading-how-to-initialize-prisma">How to Initialize Prisma</h3>
<p>To get started with Prisma, we'll need to install the Prisma CLI. This CLI allows us to interact with our database, making it easy to perform database migrations, seeding, and more.</p>
<p>To install the Prisma CLI, execute the following command:</p>
<pre><code class="lang-bash">
npm install prisma -D
</code></pre>
<p>This command installs the Prisma CLI as a development dependency in your project. The <code>-D</code> flag tells npm to install the package as a development dependency.</p>
<p>Next, initialize Prisma in your project by executing the following command:</p>
<pre><code class="lang-bash">
npx prisma init
</code></pre>
<p>This will create a new <code>prisma</code> directory with a <code>schema.prisma</code> file. This is the main configuration file that contains your database schema. This command also creates a <code>.env</code> file inside your project.</p>
<h3 id="heading-how-to-set-your-environment-variable">How to Set Your Environment Variable</h3>
<p>The <code>.env</code> file contains the environment variables required to connect to your database. Open this file and replace the contents with the following:</p>
<pre><code class="lang-bash">
DATABASE_URL=<span class="hljs-string">"postgres://recipe:RecipePassword@localhost:5444/recipe"</span>
</code></pre>
<p>Note: If you changed the port number in your <code>docker-compose.yml</code> file, ensure you update the port number in the <code>DATABASE_URL</code> environment variable with the port number you used.</p>
<p>This environment variable contains the connection string for your database. It's used by Prisma to connect to your database in the docker container.</p>
<h3 id="heading-understanding-the-prisma-schema">Understanding the Prisma Schema</h3>
<p>The <code>schema.prisma</code> file contains the schema for your database. It's written in the Prisma Schema Language, a declarative language for defining your database schema. The <code>prisma/schema.prisma</code> file is the main configuration file for your Prisma setup. It defines your database connection and the Prisma Client generator.</p>
<pre><code class="lang-ts">
<span class="hljs-comment">// prisma/schema.prisma</span>

generator client {
  provider = <span class="hljs-string">"prisma-client-js"</span>
}

datasource db {
  provider = <span class="hljs-string">"postgresql"</span>
  url      = env(<span class="hljs-string">"DATABASE_URL"</span>)
}
</code></pre>
<p>This file is written in the Prisma Schema Language, which is a language that Prisma uses to define your database schema. The <code>schema.prisma</code> file has three main components:</p>
<ul>
<li><strong>Generator</strong>: This section defines the Prisma Client generator. The Prisma Client generator is responsible for generating the Prisma Client, a powerful API for accessing your database.</li>
<li><strong>Datasource</strong>: This section defines the database connection. It specifies the database provider and the connection string. It use <code>DATABASE_URL</code> environment variable to connect to your database.</li>
<li><strong>Model</strong>: This section defines the database schema. It specifies the database tables and their fields.</li>
</ul>
<h2 id="heading-how-to-model-the-data">How to Model the Data</h2>
<p>Now that we have set up our Prisma, we're ready to model our data. We'll be building a recipe management system, so we'll need to define a <code>Recipe</code> model. This model will have various fields.</p>
<p>Open the <code>schema.prisma</code> file and add the following code:</p>
<pre><code class="lang-ts">
 <span class="hljs-comment">// prisma/schema.prisma</span>
 <span class="hljs-comment">// ...</span>
model Recipe {
  id           Int      <span class="hljs-meta">@id</span> <span class="hljs-meta">@default</span>(autoincrement())
  title        <span class="hljs-built_in">String</span>   <span class="hljs-meta">@unique</span>
  description  <span class="hljs-built_in">String</span>?
  ingredients  <span class="hljs-built_in">String</span>
  instructions <span class="hljs-built_in">String</span>
  createdAt    DateTime <span class="hljs-meta">@default</span>(now())
  updatedAt    DateTime <span class="hljs-meta">@updatedAt</span>
}
</code></pre>
<p>Here's a quick breakdown of this model:</p>
<ul>
<li><code>id</code>: This is the primary key of the <code>Recipe</code> model. It's an auto-incrementing integer that uniquely identifies each recipe. It has the <code>@id</code> attribute, which tells Prisma that this field is the primary key. It also has the <code>@default(autoincrement())</code> attribute, which tells Prisma to auto-increment this field.</li>
<li><code>title</code>: This is the title of the recipe. It's a unique string that's used to identify the recipe.</li>
<li><code>description</code>: This is the description of the recipe. It's an optional string that describes the recipe.</li>
<li><code>ingredients</code>: This is the list of ingredients used in the recipe. It's a string that contains a comma-separated list of ingredients.</li>
<li><code>instructions</code>: This is the list of instructions for preparing the recipe. It's a string that contains a comma-separated list of instructions.</li>
<li><code>createdAt</code>: This is the date and time the recipe was created. It's set to the current date and time by default. It has the <code>@default(now())</code> attribute, which tells Prisma to set this field to the current date and time by default.</li>
<li><code>updatedAt</code>: This is the date and time the recipe was last updated. It's set to the current date and time by default.</li>
</ul>
<h2 id="heading-how-to-migrate-the-database">How to Migrate the Database</h2>
<p>Now that we've defined our database schema, we're ready to migrate our database. This will create the database tables and fields defined in our <code>schema.prisma</code> file.</p>
<p>To migrate your database, execute the following command:</p>
<pre><code class="lang-bash">npx prisma migrate dev --name init
</code></pre>
<p>This command will do three things:</p>
<p><strong>Save the migration</strong>: Prisma Migrate will take a snapshot of your schema and figure out the SQL commands necessary to carry out the migration. Prisma will save the migration file containing the SQL commands to the newly created <code>prisma/migrations</code> folder.</p>
<p><strong>Execute the migration</strong>: Prisma Migrate will execute the SQL commands in the migration file, creating the database tables and fields defined in your <code>schema.prisma</code> file.</p>
<p><strong>Generate Prisma Client</strong>: Prisma will generate Prisma Client based on your latest schema. Since you did not have the Client library installed, the CLI will install it for you as well. You should see the <code>@prisma/client</code> package inside dependencies in your package.json file. </p>
<p>Prisma Client is a TypeScript query builder auto-generated from your Prisma schema. It is tailored to your Prisma schema and will be used to send queries to the database.</p>
<p>If all goes according to plan, you should see output similar to this:</p>
<pre><code class="lang-bash">The following migration(s) have been created and applied from new schema changes:

migrations/
  └─ 20220528101323_init/
    └─ migration.sql

Your database is now <span class="hljs-keyword">in</span> sync with your schema.
...
✔ Generated Prisma Client (3.14.0 | library) to ./node_modules/@prisma/client <span class="hljs-keyword">in</span> 31ms
</code></pre>
<p>Check the generated migration file to get an idea about what Prisma Migrate is doing behind the scenes:</p>
<pre><code class="lang-bash">-- prisma/migrations/20220528101323_init/migration.sql

CREATE TABLE <span class="hljs-string">"Recipe"</span> (
    <span class="hljs-string">"id"</span> SERIAL NOT NULL,
    <span class="hljs-string">"title"</span> TEXT NOT NULL,
    <span class="hljs-string">"description"</span> TEXT,
    <span class="hljs-string">"ingredients"</span> TEXT NOT NULL,
    <span class="hljs-string">"instructions"</span> TEXT NOT NULL,
    <span class="hljs-string">"createdAt"</span> TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
    <span class="hljs-string">"updatedAt"</span> TIMESTAMP(3) NOT NULL,

    CONSTRAINT <span class="hljs-string">"Recipe_pkey"</span> PRIMARY KEY (<span class="hljs-string">"id"</span>)
);

-- CreateIndex
CREATE UNIQUE INDEX <span class="hljs-string">"Recipe_title_key"</span> ON <span class="hljs-string">"Recipe"</span>(<span class="hljs-string">"title"</span>);
</code></pre>
<p>This migration file contains the SQL commands necessary to create the <code>Recipe</code> table. It also contains the SQL commands necessary to create the <code>title</code> field, which is a unique field. This ensures that the <code>title</code> field is unique, preventing duplicate recipes from being created.</p>
<h2 id="heading-how-to-seed-the-database">How to Seed the Database</h2>
<p>Now that we've migrated our database, we're ready to seed it with some test data. This will allow us to test our application without having to manually create recipes.</p>
<p>Firstly, create a seed file called <code>prisma/seed.ts</code>. This file will contain the dummy data and queries needed to seed your database.</p>
<p>Open the terminal and run the following command:</p>
<pre><code class="lang-bash">touch prisma/seed.ts
</code></pre>
<p>This command creates a new <code>prisma/seed.ts</code> file in your project's root directory.</p>
<p>Next, populate this file with the following code:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// prisma/seed.ts</span>
<span class="hljs-keyword">import</span> { PrismaClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@prisma/client'</span>;

<span class="hljs-comment">// initialize Prisma Client</span>
<span class="hljs-keyword">const</span> prisma = <span class="hljs-keyword">new</span> PrismaClient();

<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">main</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// create two dummy recipes</span>
  <span class="hljs-keyword">const</span> recipe1 = <span class="hljs-keyword">await</span> prisma.recipe.upsert({
    where: { title: <span class="hljs-string">'Spaghetti Bolognese'</span> },
    update: {},
    create: {
      title: <span class="hljs-string">'Spaghetti Bolognese'</span>,
      description: <span class="hljs-string">'A classic Italian dish'</span>,
      ingredients:
        <span class="hljs-string">'Spaghetti, minced beef, 
        tomato sauce, onions, garlic, olive oil, salt, pepper'</span>,
      instructions:
        <span class="hljs-string">'1. Cook the spaghetti. 2. Fry the minced beef. 3.
        Add the tomato sauce to the beef.
        4. Serve the spaghetti with the sauce.'</span>
    }
  });

  <span class="hljs-keyword">const</span> recipe2 = <span class="hljs-keyword">await</span> prisma.recipe.upsert({
    where: { title: <span class="hljs-string">'Chicken Curry'</span> },
    update: {},
    create: {
      title: <span class="hljs-string">'Chicken Curry'</span>,
      description: <span class="hljs-string">'A spicy Indian dish'</span>,
      ingredients:
        <span class="hljs-string">'Chicken, curry powder, onions, garlic, 
        coconut milk, olive oil, salt, pepper'</span>,
      instructions:
        <span class="hljs-string">'1. Fry the chicken. 2. Add the curry powder to the
        chicken. 3. Add the coconut milk.
        4. Serve the curry with rice.'</span>
    }
  });

  <span class="hljs-built_in">console</span>.log({ recipe1, recipe2 });
}

<span class="hljs-comment">// execute the main function</span>
main()
  .catch(<span class="hljs-function"><span class="hljs-params">e</span> =&gt;</span> {
    <span class="hljs-built_in">console</span>.error(e);
    process.exit(<span class="hljs-number">1</span>);
  })
  .finally(<span class="hljs-keyword">async</span> () =&gt; {
    <span class="hljs-comment">// close Prisma Client at the end</span>
    <span class="hljs-keyword">await</span> prisma.$disconnect();
  });
</code></pre>
<p>This file contains the dummy data and queries needed to seed your database. Let's break it down:</p>
<ul>
<li><code>import { PrismaClient } from '@prisma/client';</code>: This imports the Prisma Client, which is used to send queries to the database.</li>
<li><code>const prisma = new PrismaClient();</code>: This initializes the Prisma Client, allowing us to send queries to the database.</li>
<li><code>async function main() { ... }</code>: This is the main function that contains the dummy data and queries needed to seed your database.</li>
<li><code>const recipe1 = await prisma.recipe.upsert({ ... });</code>: This creates a new recipe. It uses the <code>upsert</code> method, which creates a new recipe if it doesn't exist, or updates the existing recipe if it does.</li>
<li><code>const recipe2 = await prisma.recipe.upsert({ ... });</code>: This creates a new recipe. It uses the <code>upsert</code> method, which creates a new recipe if it doesn't exist, or updates the existing recipe if it does.</li>
<li><code>console.log({ recipe1, recipe2 });</code>: This logs the newly created recipes to the console.</li>
<li><code>main().catch((e) =&gt; { ... });</code>: This executes the main function and catches any errors that occur.</li>
<li><code>await prisma.$disconnect();</code>: This closes the Prisma Client at the end.</li>
</ul>
<p>Now before we can seed our database, we need add a script to our <code>package.json</code> file. Open the <code>package.json</code> file and add the following script:</p>
<pre><code class="lang-json">

<span class="hljs-comment">// package.json</span>

<span class="hljs-comment">// ...</span>
  <span class="hljs-string">"scripts"</span>: {
    <span class="hljs-comment">// ...</span>
  },
  <span class="hljs-string">"dependencies"</span>: {
    <span class="hljs-comment">// ...</span>
  },
  <span class="hljs-string">"devDependencies"</span>: {
    <span class="hljs-comment">// ...</span>
  },
  <span class="hljs-string">"jest"</span>: {
    <span class="hljs-comment">// ...</span>
  },
  <span class="hljs-comment">// pasting the prisma script here</span>
  <span class="hljs-string">"prisma"</span>: {
    <span class="hljs-attr">"seed"</span>: <span class="hljs-string">"ts-node prisma/seed.ts"</span>
  }
</code></pre>
<p>The seed command will execute the <code>prisma/seed.ts</code> script that you previously defined. This command should work automatically because ts-node is already installed as a dev dependency in your <code>package.json</code>.</p>
<p>Now that we've defined our seed script, we're ready to seed the database. To seed your database, execute the following command:</p>
<pre><code class="lang-bash">npx prisma db seed
</code></pre>
<p>This command will seed your database with the dummy data defined in your <code>prisma/seed.ts</code> file. If all goes according to plan, you should see output similar to this:</p>
<pre><code class="lang-ts">Running seed command <span class="hljs-string">`ts-node prisma/seed.ts`</span> ...
{
  recipe1: {
    id: <span class="hljs-number">1</span>,
    title: <span class="hljs-string">'Spaghetti Bolognese'</span>,
    description: <span class="hljs-string">'A classic Italian dish'</span>,
    ingredients: <span class="hljs-string">'Spaghetti, minced beef, tomato sauce, onions, garlic, olive oil, salt, pepper'</span>,
    instructions: <span class="hljs-string">'1. Cook the spaghetti. 2. Fry the minced beef. 3. Add the tomato sauce to the beef. 4. Serve the spaghetti with the sauce.'</span>,
    createdAt: <span class="hljs-number">2024</span><span class="hljs-number">-01</span><span class="hljs-number">-12</span>T16:<span class="hljs-number">21</span>:<span class="hljs-number">09.133</span>Z,
    updatedAt: <span class="hljs-number">2024</span><span class="hljs-number">-01</span><span class="hljs-number">-12</span>T16:<span class="hljs-number">21</span>:<span class="hljs-number">09.133</span>Z
  },
  recipe2: {
    id: <span class="hljs-number">2</span>,
    title: <span class="hljs-string">'Chicken Curry'</span>,
    description: <span class="hljs-string">'A spicy Indian dish'</span>,
    ingredients: <span class="hljs-string">'Chicken, curry powder, onions, garlic, coconut milk, olive oil, salt, pepper'</span>,
    instructions: <span class="hljs-string">'1. Fry the chicken. 2. Add the curry powder to the chicken. 3. Add the coconut milk. 4. Serve the curry with rice.'</span>,
    createdAt: <span class="hljs-number">2024</span><span class="hljs-number">-01</span><span class="hljs-number">-12</span>T16:<span class="hljs-number">21</span>:<span class="hljs-number">09.155</span>Z,
    updatedAt: <span class="hljs-number">2024</span><span class="hljs-number">-01</span><span class="hljs-number">-12</span>T16:<span class="hljs-number">21</span>:<span class="hljs-number">09.155</span>Z
  }
}

The seed command has been executed.
</code></pre>
<p>Congratulations 🎉. You now have a fully functional database with dummy data.</p>
<h2 id="heading-how-to-create-a-prisma-service">How to Create a Prisma Service</h2>
<p>Now that we've set up Prisma, we're ready to create a Prisma service. This service will act as a wrapper around the Prisma Client, making it easy to send queries to the database.</p>
<p>The Nest CLI gives you an easy way to generate modules and services directly from the CLI. Run the following command in your terminal:</p>
<pre><code class="lang-bash">
npx nest generate module prisma
npx nest generate service prisma
</code></pre>
<p>Note that the <code>generate</code> command can be shortened to <code>g</code>. So, you can also run the following command:</p>
<pre><code class="lang-bash">
npx nest g module prisma
npx nest g service prisma
</code></pre>
<p>This command generates a new module called <code>prisma</code> and a new service called <code>prisma</code>. It also imports the <code>PrismaModule</code> into the <code>AppModule</code>.</p>
<p>So you should see something like this:</p>
<pre><code class="lang-bash">
  src/prisma/prisma.service.spec.ts
  src/prisma/prisma.service.ts
  src/prisma/prisma.module.ts
</code></pre>
<p>Note: In some cases, you may need to restart your server for the changes to take effect.</p>
<p>Next, open the <code>prisma.service.ts</code> file and replace the contents with the following:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/prisma/prisma.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> { PrismaClient } <span class="hljs-keyword">from</span> <span class="hljs-string">'@prisma/client'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> PrismaService <span class="hljs-keyword">extends</span> PrismaClient {}
</code></pre>
<p>This service is a wrapper around the Prisma Client, making it easy to send queries to the database. It's also a NestJS provider, which means it can be injected into other modules.</p>
<p>Next, open the <code>prisma.module.ts</code> file and replace the contents with the following:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/prisma/prisma.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> { PrismaService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./prisma.service'</span>;

<span class="hljs-meta">@Module</span>({
  providers: [PrismaService],
  <span class="hljs-built_in">exports</span>: [PrismaService]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> PrismaModule {}
</code></pre>
<p><strong>Note:</strong> The <code>PrismaModule</code> is a NestJS module that imports the <code>PrismaService</code>, making it readily available for use across other modules in your application. This setup allows seamless integration of the Prisma service throughout your project.</p>
<p>Congratulations 🎉! You've successfully set up your Prisma service.</p>
<p>Before we dive into writing our application logic, let's set up Swagger. Swagger is an industry-standard tool for designing, building, and documenting RESTful APIs. It empowers developers to create elegant and comprehensive API documentation effortlessly.</p>
<h2 id="heading-how-to-set-up-swagger">How to Set Up Swagger</h2>
<p>To configure Swagger, we'll leverage the <code>@nestjs/swagger</code> package. This package offers a suite of decorators and methods specifically designed to generate Swagger documentation.</p>
<p>To install this package, run the following command:</p>
<pre><code class="lang-bash">npm install --save @nestjs/swagger swagger-ui-express
</code></pre>
<p>This command adds the <code>@nestjs/swagger</code> package as a dependency in your project. It also installs the <code>swagger-ui-express</code> package, which serves the Swagger UI.</p>
<p>Next, navigate to the <code>main.ts</code> file and append the following code:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/main.ts</span>

<span class="hljs-keyword">import</span> { NestFactory } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/core'</span>;
<span class="hljs-keyword">import</span> { AppModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'./app.module'</span>;
<span class="hljs-keyword">import</span> { SwaggerModule, DocumentBuilder } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/swagger'</span>;

<span class="hljs-comment">// Define the bootstrap function</span>
<span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">bootstrap</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-comment">// Create a NestJS application instance by passing the AppModule to the NestFactory</span>
  <span class="hljs-keyword">const</span> app = <span class="hljs-keyword">await</span> NestFactory.create(AppModule);

  <span class="hljs-comment">// Use DocumentBuilder to create a new Swagger document configuration</span>
  <span class="hljs-keyword">const</span> config = <span class="hljs-keyword">new</span> DocumentBuilder()
    .setTitle(<span class="hljs-string">'Recipes API'</span>) <span class="hljs-comment">// Set the title of the API</span>
    .setDescription(<span class="hljs-string">'Recipes API description'</span>) <span class="hljs-comment">// Set the description of the API</span>
    .setVersion(<span class="hljs-string">'0.1'</span>) <span class="hljs-comment">// Set the version of the API</span>
    .build(); <span class="hljs-comment">// Build the document</span>

  <span class="hljs-comment">// Create a Swagger document using the application instance and the document configuration</span>
  <span class="hljs-keyword">const</span> <span class="hljs-built_in">document</span> = SwaggerModule.createDocument(app, config);

  <span class="hljs-comment">// Setup Swagger module with the application instance and the Swagger document</span>
  SwaggerModule.setup(<span class="hljs-string">'api'</span>, app, <span class="hljs-built_in">document</span>);

  <span class="hljs-comment">// Start the application and listen for requests on port 3000</span>
  <span class="hljs-keyword">await</span> app.listen(<span class="hljs-number">3000</span>);
}

<span class="hljs-comment">// Call the bootstrap function to start the application</span>
bootstrap();
</code></pre>
<p>This code initializes Swagger and generates the Swagger documentation. Let's break it down:</p>
<ul>
<li><code>const config = new DocumentBuilder() ... .build();</code>: This creates a new Swagger document builder. It sets the title, description, and version of the Swagger document. It also builds the Swagger document.</li>
<li><code>const document = SwaggerModule.createDocument(app, config);</code>: This creates a new Swagger document. It uses the Swagger document builder to generate the Swagger document.</li>
<li><code>SwaggerModule.setup('api', app, document);</code>: This sets up the Swagger UI. It uses the Swagger document to generate the Swagger UI.</li>
</ul>
<p>While the application is running, open your browser and navigate to <code>http://localhost:3000/api</code>. You should see the Swagger UI.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Swager-first-look.png" alt="Swagger UI " width="600" height="400" loading="lazy">
<em>The initial view of the Swagger UI after successful setup.</em></p>
<p>Now that we've set up Swagger, we're ready to start building our REST API.</p>
<h2 id="heading-how-to-implement-crud-operations-for-the-recipe-model">How to Implement CRUD Operations for the Recipe Model</h2>
<p>In this section we'll implement the CRUD operations for the <code>Recipe</code> model. We'll start by generating the REST resources for the <code>Recipe</code> model. Then we'll add the Prisma Client to the <code>Recipe</code> module. Finally, we'll implement the CRUD operations for the <code>Recipe</code> model.</p>
<h3 id="heading-how-to-generate-rest-resources-with-nestjs-cli">How to Generate REST Resources with NestJS CLI</h3>
<p>Before we can implement the CRUD operations for the <code>Recipe</code> model, we need to generate the REST resources for the <code>Recipe</code> model. This will create the boilerplate code for the <code>Recipe</code> module, controller, service, and DTOs. </p>
<p>To generate the REST resources for the <code>Recipe</code> model, execute the following command:</p>
<pre><code class="lang-bash">
npx nest generate resource recipe
</code></pre>
<p>And it will ask you what type of API you want to generate. So now we will select the <code>REST API</code> .</p>
<p>Check out the below image for reference:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Generating-CRUD.png" alt="REST API  " width="600" height="400" loading="lazy">
<em>Selecting REST API when creating the CRUD operations using the Nest CLI</em></p>
<p>This command will generate the following files:</p>
<pre><code class="lang-bash">
CREATE src/recipe/recipe.controller.ts (959 bytes)
CREATE src/recipe/recipe.controller.spec.ts (596 bytes)
CREATE src/recipe/recipe.module.ts (264 bytes)
CREATE src/recipe/recipe.service.ts (661 bytes)
CREATE src/recipe/recipe.service.spec.ts (478 bytes)
CREATE src/recipe/dto/create-recipe.dto.ts (33 bytes)
CREATE src/recipe/dto/update-recipe.dto.ts (176 bytes)
CREATE src/recipe/entities/recipe.entity.ts (24 bytes)
UPDATE src/app.module.ts (385 bytes)
</code></pre>
<p>If you open the Swagger API page again, you should see something like this:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/swagger-pplo--after-crating-crud.png" alt="SWagger UI  " width="600" height="400" loading="lazy">
<em>The Swagger UI displaying the newly created CRUD operations.</em></p>
<p>The swagger page now has a new section called <code>Recipe API</code> . This section contains the REST resources for the <code>Recipe</code> model.</p>
<p>Now when you open Swagger you will see something like this:</p>
<ul>
<li><code>POST /recipes</code>: Create a new recipe.</li>
<li><code>GET /recipes</code>: Retrieve all recipes.</li>
<li><code>GET /recipes/{id}</code>: Retrieve a specific recipe by its ID.</li>
<li><code>PATCH /recipes/{id}</code>: Update a specific recipe by its ID.</li>
<li><code>DELETE /recipes/{id}</code>: Delete a specific recipe by its ID.</li>
</ul>
<h3 id="heading-how-to-add-prismaclient-to-the-recipe-module">How to Add <code>PrismaClient</code> to the Recipe Module</h3>
<p>Now that we've generated the REST resources for the <code>Recipe</code> model, we're ready to add the Prisma Client to the <code>Recipe</code> module. This will allow us to send queries to the database.</p>
<p>Firstly, open the <code>recipe.module.ts</code> file and add the following code:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.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> { RecipeService } <span class="hljs-keyword">from</span> <span class="hljs-string">'./recipe.service'</span>;
<span class="hljs-keyword">import</span> { RecipeController } <span class="hljs-keyword">from</span> <span class="hljs-string">'./recipe.controller'</span>;
<span class="hljs-keyword">import</span> { PrismaModule } <span class="hljs-keyword">from</span> <span class="hljs-string">'../prisma/prisma.module'</span>;

<span class="hljs-meta">@Module</span>({
  imports: [PrismaModule],
  controllers: [RecipeController],
  providers: [RecipeService]
})
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> RecipeModule {}
</code></pre>
<p>So now we have imported the <code>PrismaModule</code> and added it to the <code>imports</code> array. This will make the <code>PrismaService</code> available to the <code>RecipeService</code>.</p>
<p>Next, open the <code>recipe.service.ts</code> file and add the following code:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>
<span class="hljs-keyword">import</span> { Body, Injectable, Post } <span class="hljs-keyword">from</span> <span class="hljs-string">'@nestjs/common'</span>;
<span class="hljs-keyword">import</span> { CreateRecipeDto } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dto/create--recipe.dto'</span>;
<span class="hljs-keyword">import</span> { UpdateRecipeDto } <span class="hljs-keyword">from</span> <span class="hljs-string">'./dto/update--recipe.dto'</span>;
<span class="hljs-keyword">import</span> { PrismaService } <span class="hljs-keyword">from</span> <span class="hljs-string">'src/prisma/prisma.service'</span>;

<span class="hljs-meta">@Injectable</span>()
<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> RecipesService {
  <span class="hljs-keyword">constructor</span>(<span class="hljs-params"><span class="hljs-keyword">private</span> <span class="hljs-keyword">readonly</span> prisma: PrismaService</span>) {}

  <span class="hljs-comment">//  rest of the code</span>
}
</code></pre>
<p>So now we have defined the <code>prisma</code> service as a private property of the <code>RecipeService</code> class. This will allow us to access the <code>PrismaService</code> from within the <code>RecipeService</code> class. So now we use the <code>prisma</code> service to perform the CRUD operations.</p>
<p>Sine we have defined the service for the Recipe model, we're ready to implement the CRUD operations for the Recipe model.</p>
<h3 id="heading-how-to-define-the-get-recipes-endpoint">How to Define the <code>GET /recipes</code> Endpoint</h3>
<p>Let's kickstart our journey into crafting API endpoints by defining the <code>GET /recipes</code> endpoint. This endpoint will serve as a gateway to fetch all the recipes stored in our database.</p>
<p>In your <code>recipes.controller.ts</code> file, you'll find a method named <code>findAll</code>. This method, as the name suggests, is responsible for fetching all the recipes. Here's how we'll define it:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.controller.ts</span>

<span class="hljs-comment">// Other code...</span>

<span class="hljs-meta">@Get</span>()
<span class="hljs-keyword">async</span> findAll() {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.recipeService.findAll();
}

<span class="hljs-comment">// Other code...</span>
</code></pre>
<p>In the above code:</p>
<ul>
<li>The <code>@Get()</code> decorator maps the <code>findAll</code> method to the <code>GET /recipes</code> endpoint.</li>
<li>The <code>findAll</code> method invokes the <code>findAll</code> method of the <code>recipeService</code>, which retrieves all the recipes from the database.</li>
</ul>
<p>As we've previously seen, the <code>Controller</code> is the heart of our application's logic. In this context, we're aiming to implement a <code>findAll</code> method that fetches all recipes from our database. To accomplish this, we'll harness the power of Prisma's services within our <code>recipe.service.ts</code> file.</p>
<p>When you open the <code>recipe.service.ts</code> file you will see something like this :</p>
<pre><code class="lang-ts">
<span class="hljs-comment">// Other code...</span>
<span class="hljs-comment">// src/recipes/recipes.service.ts</span>
 findAll() {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`This action returns all recipe`</span>;
  }
<span class="hljs-comment">// Other code...</span>
</code></pre>
<p>NOW we will replace the <code>findAll</code> method with the following code:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>
<span class="hljs-comment">// Other code...</span>

<span class="hljs-keyword">async</span> findAll() {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.prisma.recipe.findMany();
}
<span class="hljs-comment">// Other code...</span>
</code></pre>
<p>In the above snippet:</p>
<ul>
<li>The <code>findAll</code> method utilizes Prisma's <code>findMany</code> function to retrieve all recipes from the database.</li>
<li>The <code>await</code> keyword is not necessary here because the <code>async</code> function implicitly wraps the returned value in a Promise.</li>
</ul>
<p>We've now successfully implemented the service method that our <code>findAll</code> controller will use to fetch all recipes.</p>
<p>Given that we already have seed data in our database, opening Swagger should allow us to retrieve all the recipes. Here's what you can expect to see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/get-all-recipe-swagger.png" alt="Fetch All Recipes" width="600" height="400" loading="lazy">
<em>The Swagger UI displaying the result of the 'Fetch All Recipes' operation.</em></p>
<p>As depicted in the image above, our <code>GET /recipes</code> endpoint is functioning as expected, successfully fetching all recipes from our database. </p>
<p>This marks a significant milestone in our journey of building a robust recipe management system. Let's continue on and add some more features.</p>
<h3 id="heading-how-to-define-the-get-recipesid-endpoint">How to Define the <code>GET /recipes/{id}</code> Endpoint</h3>
<p>Let's now focus on the <code>GET /recipes/{id}</code> endpoint, which retrieves a specific recipe based on its ID. To implement this, we'll need to modify both the <code>controller</code> and the <code>service</code>.</p>
<p>First, navigate to the <code>recipes.controller.ts</code> file. Here, you'll find the <code>findOne</code> method, which is defined as follows:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.controller.ts</span>

<span class="hljs-comment">// other code ...</span>
<span class="hljs-meta">@Get</span>(<span class="hljs-string">':id'</span>)
<span class="hljs-keyword">async</span> findOne(<span class="hljs-meta">@Param</span>(<span class="hljs-string">'id'</span>) id: <span class="hljs-built_in">string</span>) {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.recipeService.findOne(+id);
}
<span class="hljs-comment">// other code ...</span>
</code></pre>
<p>In this code:</p>
<ul>
<li>The <code>@Get(':id')</code> decorator maps to the <code>GET /recipes/{id}</code> endpoint.</li>
<li>The <code>findOne</code> method accepts an <code>id</code> parameter, which is extracted from the route parameters.</li>
</ul>
<p>Next, let's turn our attention to the <code>recipes.service.ts</code> file. Here, you'll find a placeholder <code>findOne</code> method:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>
<span class="hljs-comment">// other code ...</span>
  findOne(id: <span class="hljs-built_in">number</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`This action returns a #<span class="hljs-subst">${id}</span> recipe`</span>;
  }

<span class="hljs-comment">// other code ...</span>
</code></pre>
<p>We'll replace this placeholder with a method that fetches a recipe based on its <code>id</code>:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>

findOne(id: <span class="hljs-built_in">number</span>) {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.prisma.recipe.findUnique({
    where: { id },
  });
}
</code></pre>
<p>In this code:</p>
<ul>
<li>The <code>findOne</code> method takes an <code>id</code> as an argument and uses Prisma's <code>findUnique</code> function to retrieve the recipe with the corresponding <code>id</code>.</li>
</ul>
<p>With the recent modifications, you've unlocked the ability to fetch individual recipes by their ID.</p>
<p>To see this feature in action, navigate to your Swagger page. Here's a snapshot of what you can expect:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Get-by-id.png" alt="GET BY ID" width="600" height="400" loading="lazy">
<em>The Swagger UI displaying the result of the 'GET BY ID' operation.</em></p>
<p>Having achieved this milestone, we're ready to venture into creating our own recipes, adding to the existing ones in our database.</p>
<h3 id="heading-how-to-define-the-post-recipes-endpoint">How to Define the <code>POST /recipes</code> Endpoint</h3>
<p>The NestJS CLI has conveniently generated a <code>create</code> method for us when we created the resource for the <code>Recipe</code> model. Now, we need to implement the logic for this method in the <code>recipe.service.ts</code> file.</p>
<p>First, let's look at the <code>create</code> method in the <code>recipe.controller.ts</code> file:<br>We will see something like this:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.controller.ts</span>

<span class="hljs-comment">// other code ...</span>
<span class="hljs-meta">@Post</span>()
create(<span class="hljs-meta">@Body</span>() createRecipeDto: CreateRecipeDto) {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.recipesService.create(createRecipeDto);
}
<span class="hljs-comment">// other code ...</span>
</code></pre>
<p>In this code:</p>
<ul>
<li>The <code>@Post()</code> decorator maps the method to the <code>POST /recipes</code> endpoint.</li>
<li>The <code>create</code> method accepts a <code>createRecipeDto</code> parameter, which is extracted from the request body.</li>
</ul>
<p>The NestJS CLI has thoughtfully provided us with DTO (Data Transfer Object) files within the <code>recipe</code> folder. One of these, <code>CreateRecipeDto</code>, will be our tool of choice for validating incoming client data.</p>
<p><strong>A Quick DTO Primer</strong>: If you're new to the concept of DTOs, they're essentially objects that carry data between processes. In the context of our application, we'll use DTOs to ensure the data we receive aligns with our expectations. If you're keen to delve deeper into DTOs, check out this comprehensive <a target="_blank" href="https://docs.nestjs.com/controllers#request-payloads">guide</a>.</p>
<p>Now, let's implement the <code>create</code> method in the <code>recipe.service.ts</code> file to interact with our database.</p>
<p>But before we proceed, let's harness the power of the DTO (Data Transfer Object) folder, generated by the Nest CLI, to model our data.</p>
<p>The <code>CreateRecipeDto</code> class, as shown below, is a prime example of a DTO. It's designed to validate incoming client data, ensuring it aligns with our expectations.</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/dto/create-recipe.dto.ts</span>
<span class="hljs-keyword">import</span> { IsString, IsOptional } <span class="hljs-keyword">from</span> <span class="hljs-string">'class-validator'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">class</span> CreateRecipeDto {
  <span class="hljs-meta">@IsString</span>()
  title: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@IsOptional</span>()
  <span class="hljs-meta">@IsString</span>()
  description?: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@IsString</span>()
  ingredients: <span class="hljs-built_in">string</span>;

  <span class="hljs-meta">@IsString</span>()
  instructions: <span class="hljs-built_in">string</span>;
}
</code></pre>
<p>In this class, we're using the <code>class-validator</code> package to enforce data validation. This package offers a suite of decorators, such as <code>IsString</code> and <code>IsOptional</code>, which we've employed to validate the <code>title</code>, <code>description</code>, <code>ingredients</code>, and <code>instructions</code> fields. </p>
<p>With this setup, we can confidently ensure that these fields will always be strings, with <code>description</code> being optional.</p>
<p>Now, let's implement the <code>create</code> method in the <code>recipe.service.ts</code> file to interact with our database. When you open the <code>recipe.service.ts</code> file you will see something like this:</p>
<pre><code class="lang-ts">
<span class="hljs-comment">// src/recipes/recipes.service.ts</span>

<span class="hljs-comment">// other code ...</span>
  create(createRecipeDto: CreateRecipeDto) {
    <span class="hljs-keyword">return</span> <span class="hljs-string">'This action adds a new recipe'</span>;
  }

<span class="hljs-comment">// other code ...</span>
</code></pre>
<p>Replace the <code>create</code> method with the following code:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>

<span class="hljs-comment">// other code ...</span>
create(createRecipeDto: CreateRecipeDto) {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.prisma.recipe.create({
    data: createRecipeDto,
  });
}
<span class="hljs-comment">// other code ...</span>
</code></pre>
<p>In this code:</p>
<ul>
<li>The <code>create</code> method uses Prisma's <code>create</code> function to add a new recipe to the database. The data for the new recipe is provided by the <code>createRecipeDto</code>.</li>
</ul>
<p>With these changes, you can now create new recipes in your swagger page. Here's what you can expect to see:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/Creating-POST.png" alt="Creating a Recipe" width="600" height="400" loading="lazy">
<em>The Swagger UI displaying the process of creating a new recipe.</em></p>
<p>As depicted in the image above, we've successfully added a third recipe to our collection. This demonstrates the effectiveness of our POST method in creating new recipes.</p>
<h3 id="heading-how-to-define-the-patch-recipesid-endpoint">How to Define the <code>PATCH /recipes/{id}</code> Endpoint</h3>
<p>Having implemented the endpoints to create and retrieve recipes, let's now focus on updating a recipe. We'll implement the <code>PATCH /recipes/{id}</code> endpoint, which updates a specific recipe based on its ID. This requires modifications in both the <code>controller</code> and the <code>service</code>.</p>
<p>In the <code>recipes.controller.ts</code> file, locate the <code>update</code> method. This method is mapped to the <code>PATCH /recipes/{id}</code> endpoint:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.controller.ts</span>

<span class="hljs-comment">// other code ...</span>
<span class="hljs-meta">@Patch</span>(<span class="hljs-string">':id'</span>)
update(<span class="hljs-meta">@Param</span>(<span class="hljs-string">'id'</span>) id: <span class="hljs-built_in">string</span>, <span class="hljs-meta">@Body</span>() updateRecipeDto: UpdateRecipeDto) {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.recipesService.update(+id, updateRecipeDto);
}
<span class="hljs-comment">// other code ...</span>
</code></pre>
<p>In this code:</p>
<ul>
<li>The <code>@Patch(':id')</code> decorator maps the method to the <code>PATCH /recipes/{id}</code> endpoint.</li>
<li>The <code>update</code> method accepts two parameters: <code>id</code> (extracted from the route parameters) and <code>updateRecipeDto</code> (extracted from the request body).</li>
</ul>
<p>Next, let's implement the <code>update</code> method in the <code>recipe.service.ts</code> file. When you open the <code>recipe.service.ts</code> file, you will see something like this:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>

<span class="hljs-comment">// other code ...</span>
  update(id: <span class="hljs-built_in">number</span>, updateRecipeDto: UpdateRecipeDto) {
    <span class="hljs-keyword">return</span> <span class="hljs-string">`This action updates a #<span class="hljs-subst">${id}</span> recipe`</span>;
  }

<span class="hljs-comment">// other code ...</span>
</code></pre>
<p>Replace the <code>update</code> method with the following code:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>

update(id: <span class="hljs-built_in">number</span>, updateRecipeDto: UpdateRecipeDto) {
  <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.prisma.recipe.update({
    where: { id },
    data: updateRecipeDto,
  });
}
</code></pre>
<p>In this code:</p>
<ul>
<li>The <code>update</code> method uses Prisma's <code>update</code> function to update the recipe in the database. The <code>where</code> clause specifies the recipe to update (based on <code>id</code>), and the <code>data</code> clause specifies the new data for the recipe (provided by <code>updateRecipeDto</code>).</li>
</ul>
<p>With the recent modifications, we've unlocked the ability to update individual recipes by their ID.</p>
<p>Let's put this new feature to the test by updating the recipe with an ID of 3.</p>
<p>Here's a snapshot of the current state of the recipe:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/by-id3.png" alt="Current Recipe Data" width="600" height="400" loading="lazy">
<em>Displaying the current data of a specific recipe.</em></p>
<p>As depicted above, this is the existing data for the recipe we're about to update.</p>
<p>After executing the update operation, here's how our recipe transforms:</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/after-updating-id-3-response.png" alt="Updated Recipe Data" width="600" height="400" loading="lazy">
<em>Displaying the updated data of a specific recipe after modification.</em></p>
<p>As you can see, our update operation has successfully modified the recipe, demonstrating the effectiveness of our newly implemented feature.</p>
<p>Let's now turn our attention to deleting recipes.</p>
<h3 id="heading-how-to-define-the-delete-recipesid-endpoint">How to Define the <code>DELETE /recipes/{id}</code> Endpoint</h3>
<p>Having successfully defined the <code>GET</code>, <code>POST</code>, and <code>PATCH</code> endpoints, our next task is to implement the <code>DELETE /recipes/{id}</code> endpoint. This endpoint will let us remove a specific recipe using its ID. As with the previous endpoints, we'll need to make modifications in both the <code>controller</code> and the <code>service</code>.</p>
<p>In the <code>recipes.controller.ts</code> file, we have a <code>remove</code> method. This method is mapped to the <code>DELETE /recipes/{id}</code> endpoint:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.controller.ts</span>

<span class="hljs-meta">@Delete</span>(<span class="hljs-string">':id'</span>)
<span class="hljs-keyword">async</span> remove(<span class="hljs-meta">@Param</span>(<span class="hljs-string">'id'</span>, ParseIntPipe) id: <span class="hljs-built_in">number</span>) {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.recipesService.remove(id);
}
</code></pre>
<p>In this updated code:</p>
<ul>
<li>The <code>@Delete(':id')</code> decorator maps the method to the <code>DELETE /recipes/{id}</code> endpoint.</li>
<li>The <code>remove</code> method accepts an <code>id</code> parameter, which is extracted from the route parameters and parsed to a number using <code>ParseIntPipe</code>.</li>
</ul>
<p>Next, let's implement the <code>remove</code> method in the <code>recipe.service.ts</code> file. Now with the <code>remove</code> method you see this:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>
<span class="hljs-comment">// other code ...</span>
 <span class="hljs-meta">@Delete</span>(<span class="hljs-string">':id'</span>)
  remove(<span class="hljs-meta">@Param</span>(<span class="hljs-string">'id'</span>) id: <span class="hljs-built_in">string</span>) {
    <span class="hljs-keyword">return</span> <span class="hljs-built_in">this</span>.recipeService.remove(+id);
  }

  <span class="hljs-comment">// other code ...</span>
</code></pre>
<p>Replace the <code>remove</code> method with this code:</p>
<pre><code class="lang-ts"><span class="hljs-comment">// src/recipes/recipes.service.ts</span>


<span class="hljs-comment">// other code </span>
<span class="hljs-keyword">async</span> remove(id: <span class="hljs-built_in">number</span>) {
  <span class="hljs-keyword">return</span> <span class="hljs-keyword">await</span> <span class="hljs-built_in">this</span>.prisma.recipe.delete({
    where: { id },
  });
}

<span class="hljs-comment">// other code ..</span>
</code></pre>
<p>In this code, the <code>remove</code> method uses Prisma's <code>delete</code> function to remove the recipe with the specified <code>id</code> from the database.</p>
<p>In this code:</p>
<ul>
<li>The <code>remove</code> method uses Prisma's <code>delete</code> function to remove the recipe with the corresponding <code>id</code> from the database.</li>
</ul>
<p>With these changes, you can now delete individual recipes by their ID. Check the Swagger page to see the updated API documentation.</p>
<p><img src="https://www.freecodecamp.org/news/content/images/2024/01/delet-by-id.png" alt="Delete Recipe Data" width="600" height="400" loading="lazy">
<em>Displaying the process of deleting a specific recipe.</em></p>
<h2 id="heading-summary-and-final-remarks">Summary and Final Remarks</h2>
<p>In this handbook, we've journeyed through the process of building a REST API using NestJS and Prisma. </p>
<p>We started by setting up a NestJS project, configuring a PostgreSQL database using Docker, and integrating Prisma.</p>
<p>We then dove into the heart of our application, creating a <code>Recipe</code> model and implementing CRUD operations for it. This involved generating RESTful routes, integrating the Prisma Client into our <code>Recipe</code> service, and crafting the logic for each operation.</p>
<p>This guide serves as a solid foundation for your future projects. Feel free to expand upon it, adding more features and functionalities to suit your needs. Thank you for following along, and happy coding!</p>
 ]]>
                </content:encoded>
            </item>
        
    </channel>
</rss>
