<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: adewale-codes</title>
    <description>The latest articles on DEV Community by adewale-codes (@adewalecodes).</description>
    <link>https://dev.to/adewalecodes</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1292769%2F9375cd3b-c265-4580-b909-03ca73fa54f4.jpeg</url>
      <title>DEV Community: adewale-codes</title>
      <link>https://dev.to/adewalecodes</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/adewalecodes"/>
    <language>en</language>
    <item>
      <title>gRPC with NestJS: A Comprehensive Beginner's Guide</title>
      <dc:creator>adewale-codes</dc:creator>
      <pubDate>Sat, 08 Jun 2024 17:34:50 +0000</pubDate>
      <link>https://dev.to/adewalecodes/grpc-with-nestjs-a-comprehensive-beginners-guide-4mi9</link>
      <guid>https://dev.to/adewalecodes/grpc-with-nestjs-a-comprehensive-beginners-guide-4mi9</guid>
      <description>&lt;p&gt;The world of software development is changing quickly, and creating scalable and effective microservices is crucial. It is frequently difficult to communicate across different services, particularly when low latency and great performance are desired. Introducing gRPC, a potent, open-source RPC framework developed by Google. When paired with NestJS, an advanced Node.js framework, gRPC offers a reliable inter-service communication solution. You will learn the basics of gRPC, how to integrate it with NestJS, and develop a basic chat service as an example by following this guide.&lt;/p&gt;

&lt;h2&gt;
  
  
  Understanding the Fundamentals
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;What is gRPC?&lt;/strong&gt;&lt;br&gt;
Google created the open-source gRPC (Google Remote Procedure Call) RPC (Remote Procedure Call) framework. It uses Protocol Buffers (protobuf) for serialization and HTTP/2 for transport to facilitate effective, language-neutral communication between distributed systems.&lt;/p&gt;

&lt;p&gt;Key Features of gRPC:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Language Independence: Supports multiple programming languages.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;HTTP/2 Support: Provides features like multiplexing and header compression.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Bidirectional Streaming: Supports streaming of data between client and server.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Automatic Code Generation: Reduces boilerplate code through protobuf definitions.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  What is NestJS?
&lt;/h2&gt;

&lt;p&gt;NestJS is a Node.js framework for creating scalable, dependable, and effective server-side applications. It makes use of both TypeScript and contemporary JavaScript features to offer a powerful development environment.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Features of NestJS:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Modular Architecture: Encourages a modular approach to application design.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Dependency Injection: Simplifies management of dependencies.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Extensive CLI: Provides tools to generate boilerplate code and manage the project.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Support for Multiple Transport Layers: Includes HTTP, WebSocket, and gRPC.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Setting Up the Project
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Creating a New NestJS Project&lt;/strong&gt;&lt;br&gt;
First, let's use the Nest CLI to establish a new NestJS project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;nest new grpc-chat-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Navigate into the project directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd grpc-chat-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Installing Necessary Dependencies&lt;/strong&gt;&lt;br&gt;
To integrate gRPC with NestJS, install the necessary dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install @nestjs/microservices grpc @grpc/proto-loader
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Defining the Protocol Buffers File
&lt;/h2&gt;

&lt;p&gt;Protocol Buffers (protobuf) is an extendable, platform- and language-neutral method for serializing structured data. To specify our service contract, create a file called chat.proto in the src directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;syntax = "proto3";

service ChatService {
  rpc SendMessage (Message) returns (Empty);
}

message Message {
  string content = 1;
}

message Empty {}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this definition:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Service: ChatService contains an RPC method SendMessage.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Messages: Defines the structure of Message and Empty.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Implementing the Server
&lt;/h2&gt;

&lt;p&gt;Let's now put the server-side logic for our chat service into practice.&lt;br&gt;
&lt;strong&gt;Step 1: Create a Controller&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Create a new file named chat.controller.ts in the src directory:
import { Controller } from '@nestjs/common';
import { GrpcMethod } from '@nestjs/microservices';
import { Empty, Message } from './chat.grpc.pb';

@Controller()
export class ChatController {
  private messages: string[] = [];

  @GrpcMethod('ChatService', 'SendMessage')
  async sendMessage(data: Message): Promise&amp;lt;Empty&amp;gt; {
    console.log('Received message:', data.content);
    this.messages.push(data.content);
    console.log('Current messages:', this.messages);
    return {};
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;@GrpcMethod: Decorator to map the gRPC method to the NestJS method.&lt;/li&gt;
&lt;li&gt;sendMessage Method: Logs the received message, stores it in an in-memory array, and prints the current list of messages.
&lt;strong&gt;Step 2: Update the Module&lt;/strong&gt;
Update app.module.ts to include the ChatController:
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { ChatController } from './chat.controller';

@Module({
  controllers: [ChatController],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Implementing the Client
&lt;/h2&gt;

&lt;p&gt;We'll now build a client in order to communicate with our gRPC server.&lt;br&gt;
&lt;strong&gt;Step 1: Create a Client Class&lt;/strong&gt;&lt;br&gt;
Create a new file named chat.client.ts in the src directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@nestjs/common';
import { ClientGrpc, ClientProxyFactory, Transport } from '@nestjs/microservices';
import { Message } from './chat.grpc.pb';
import { join } from 'path';

@Injectable()
export class ChatClient {
  private readonly client: ClientGrpc;

  constructor() {
    this.client = ClientProxyFactory.create({
      transport: Transport.GRPC,
      options: {
        url: 'localhost:5000',
        package: 'chat',
        protoPath: join(__dirname, 'chat.proto'),
      },
    });
  }

  async sendMessage(content: string): Promise&amp;lt;void&amp;gt; {
    const message: Message = { content };
    await this.client.getService('ChatService').sendMessage(message).toPromise();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this client:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;ClientProxyFactory.create: Creates a gRPC client.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;sendMessage Method: Sends a message to the server.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Step 2: Integrate Client in Module&lt;/strong&gt;&lt;br&gt;
Update app.module.ts to include the ChatClient:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { ChatClient } from './chat.client';
import { ChatController } from './chat.controller';

@Module({
  controllers: [ChatController],
  providers: [ChatClient],
})
export class AppModule {}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Bootstrapping the Application
&lt;/h2&gt;

&lt;p&gt;Bootstrapping is the process of starting the application, initializing necessary services, and getting the server up and running.&lt;br&gt;
Update the main.ts file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { Transport } from '@nestjs/microservices';
import { join } from 'path';

async function bootstrap() {
  const app = await NestFactory.createMicroservice(AppModule, {
    transport: Transport.GRPC,
    options: {
      url: 'localhost:5000',
      package: 'chat',
      protoPath: join(__dirname, 'chat.proto'),
    },
  });
  await app.listenAsync();
}
bootstrap();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this code:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;NestFactory.createMicroservice: Creates a microservice instance.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Transport Options: Specifies gRPC as the transport and provides necessary configuration like URL, package, and path to the protobuf file&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;app.listenAsync: Starts the microservice and listens for incoming gRPC requests.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Running and Testing the Application
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Step 1: Start the Server&lt;/strong&gt;&lt;br&gt;
Run the server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start:dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Step 2: Use the Client to Send a Message&lt;/strong&gt;&lt;br&gt;
We can now use the ChatClient to send a message to our server. You can create a simple script to test this:&lt;br&gt;
Create test-client.ts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { ChatClient } from './chat.client';

async function testClient() {
  const app = await NestFactory.createApplicationContext(AppModule);
  const client = app.get(ChatClient);
  await client.sendMessage('Hello, gRPC!');
  await app.close();
}

testClient();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;`ts-node src/test-client.ts`
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the server logging the received message and maintaining a list of messages.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;We have examined how to integrate gRPC with NestJS to create effective microservices in this extensive article. We've gone over the basics of gRPC, used Protocol Buffers to build a service, used an in-memory message storage to provide server-side functionality, built a message-sending client, and bootstrapped our NestJS application. You now have the basis to use gRPC's power in your NestJS apps, allowing for high-performance and scalable inter-service communication. Just follow these instructions. Using gRPC and NestJS together provides a reliable and effective solution whether you're developing microservices, real-time apps, or intricate distributed systems.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Getting Started with NestJs: CRUD Operations</title>
      <dc:creator>adewale-codes</dc:creator>
      <pubDate>Thu, 09 May 2024 09:04:51 +0000</pubDate>
      <link>https://dev.to/adewalecodes/getting-started-with-nestjs-crud-operations-5h4h</link>
      <guid>https://dev.to/adewalecodes/getting-started-with-nestjs-crud-operations-5h4h</guid>
      <description>&lt;p&gt;NestJS is a powerful framework for building efficient, scalable Node.js server-side applications. In this beginner-friendly guide, we'll walk through the creation of a simple NestJS project to help you understand its fundamental concepts&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before diving into NestJS, ensure you have Node.js and npm (Node Package Manager) installed on your system. You can download and install them from the official Node.js website.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Setting Up Your NestJS Project&lt;/strong&gt;&lt;br&gt;
First, let's create a new NestJS project. Open your terminal and run the following commands:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -g @nestjs/cli
nest new my-nest-project
cd my-nest-project
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will set up a new NestJS project with the necessary dependencies and files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring the Project Structure
&lt;/h2&gt;

&lt;p&gt;Once your project is created, you'll find several files and folders. Let's go through them one by one:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;main.ts: This file serves as the entry point to your NestJS application. It initializes the NestJS application and starts the serve.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explanation: This file initializes the NestJS application by creating an instance of the AppModule.&lt;/li&gt;
&lt;li&gt;Why it's important: Understanding the entry point of the application helps you grasp how NestJS bootstraps and starts your server.&lt;/li&gt;
&lt;li&gt;dotenv.config(): This line loads environment variables from a .env file, allowing you to store sensitive information securely.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;app.module.ts: The root module of your application. It imports other modules, controllers, and services and defines the main configuration of your app.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;app.controller.ts: Controllers are responsible for handling incoming requests and returning responses. They are bound to specific routes and define endpoint logic.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explanation: This controller defines a single route (GET /) that returns a "Hello World!" message.&lt;/li&gt;
&lt;li&gt;Why it's important: Controllers handle incoming HTTP requests and define the endpoints of your application. They provide a clean separation of concerns by delegating actual logic to services.&lt;/li&gt;
&lt;li&gt;Dependency Injection: Notice how the AppService is injected into the controller's constructor. This allows us to use the methods defined in AppService within the controller.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;app.service.ts: Services contain the business logic of your application. They are injected into controllers to handle data processing and manipulation.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Explanation: The AppService class contains a single method getHello which returns a "Hello World!" message.&lt;/li&gt;
&lt;li&gt;Why it's important: Services encapsulate business logic and data manipulation tasks. They are reusable across multiple controllers and promote code maintainability.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Running Your NestJS Application
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run start
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will start the server, and you should see the message "Hello World!" when you navigate to &lt;a href="http://localhost:3000"&gt;http://localhost:3000&lt;/a&gt; in your browser.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring the Project Structure
&lt;/h2&gt;

&lt;p&gt;Once your project is created, you'll find several files and folders. Let's go through them one by one:&lt;/p&gt;

&lt;p&gt;main.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import * as dotenv from 'dotenv';

async function bootstrap() {
  dotenv.config();
  const app = await NestFactory.create(AppModule);
  await app.listen(3000);
}
bootstrap();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: This file is the entry point of the NestJS application. It initializes the NestJS application, loads environment variables, and starts the server.&lt;/li&gt;
&lt;li&gt;Why it's important: Understanding the entry point helps you understand how NestJS bootstraps and starts the server.&lt;/li&gt;
&lt;li&gt;dotenv.config(): This line loads environment variables from a .env file, allowing you to store sensitive information securely.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;app.module.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { ProductsModule } from './products/products.module';
import { ConfigModule, ConfigService } from '@nestjs/config';

@Module({
  imports: [
    ProductsModule,
    ConfigModule.forRoot(),
    TypeOrmModule.forRootAsync({
      imports: [ConfigModule], 
      useFactory: async (configService: ConfigService) =&amp;gt; ({
        type: 'postgres',
        host: configService.get('DB_HOST'),
        port: configService.get('DB_PORT'),
        username: configService.get('DB_USERNAME'),
        password: configService.get('DB_PASSWORD'),
        database: configService.get('DB_DATABASE'),
        entities: [__dirname + '/**/*.entity{.ts,.js}'],
        synchronize: true,
      }),
      inject: [ConfigService],
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: This file defines the root module of the NestJS application. It imports other modules, controllers, and services and configures the application.&lt;/li&gt;
&lt;li&gt;Why it's important: The root module is the core of your application. It orchestrates the various components and sets up configurations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;app.controller.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Controller, Get } from '@nestjs/common';
import { AppService } from './app.service';

@Controller()
export class AppController {
  constructor(private readonly appService: AppService) {}

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: This controller defines a single route (GET /) that returns a "Hello World!" message.&lt;/li&gt;
&lt;li&gt;Why it's important: Controllers handle incoming HTTP requests and define the endpoints of your application.&lt;/li&gt;
&lt;li&gt;Dependency Injection: Notice how the AppService is injected into the controller's constructor. This allows us to use the methods defined in AppService within the controller.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;app.service.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: The AppService class contains a single method getHello which returns a "Hello World!" message.&lt;/li&gt;
&lt;li&gt;Why it's important: Services encapsulate business logic and data manipulation tasks. They are reusable across multiple controllers and promote code maintainability.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  CRUD Operations
&lt;/h2&gt;

&lt;p&gt;Products: This folder contains modules, controllers, services, and entities related to managing products. It demonstrates how to organize code into separate modules for better maintainability. Let's go through them one by one:&lt;/p&gt;

&lt;p&gt;products/product.entity.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';

@Entity()
export class ProductEntity {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  title: string;

  @Column()
  description: string;

  @Column('decimal', { precision: 10, scale: 2 })
  price: number;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: This file defines the ProductEntity class, which represents a product entity in the database. It uses the TypeORM library for Object-Relational Mapping (ORM).&lt;/li&gt;
&lt;li&gt;Why it's important: Entities map to database tables and represent the structure of the data stored in the database. They help in defining the schema and performing CRUD operations.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;products/product.model.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;export class Product {
    constructor (
        public id: string, 
        public title: string, 
        public description: string, 
        public price: number
        ) {
    };
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: This file defines the Product class, which represents a product object in the application. It's a simple TypeScript class with properties corresponding to a product's attributes.&lt;/li&gt;
&lt;li&gt;Why it's important: Models represent the data transferred between different parts of the application, such as between the controller and the service. They help maintain a consistent data structure throughout the application.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;products/product.controller.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Body, Controller, Delete, Get, NotFoundException, Param, Patch, Post } from "@nestjs/common";
import { ProductsService } from "./products.service";

@Controller('products')
export class ProductsController {
    constructor(private readonly productsService: ProductsService) {}

    @Post()
    async addProduct(
        @Body('title') prodTitle: string,
        @Body('description') prodDesc: string,
        @Body('price') prodPrice: number
    ) {
        const productId = await this.productsService.insertProduct(prodTitle, prodDesc, prodPrice);
        return { id: productId };
    }

    @Get()
    async getAllProducts() {
        return await this.productsService.getProducts();
    }

    @Get(':id')
    async getProduct(@Param('id') prodId: string) {
        const product = await this.productsService.getSingleProduct(prodId);
        if (!product) {
            throw new NotFoundException('Product not found');
        }
        return product;
    }

    @Patch(':id')
    async updateProduct(
        @Param('id') prodId: string, 
        @Body('title') prodTitle: string, 
        @Body('description') prodDesc: string, 
        @Body('price') prodPrice: number
    ) {
        await this.productsService.updateProduct(prodId, prodTitle, prodDesc, prodPrice);
        return null;
    }

    @Delete(':id')
    async removeProduct(@Param('id') prodId: string) {
        await this.productsService.deleteProduct(prodId);
        return null;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: This controller handles HTTP requests related to products. It defines routes for adding, retrieving, updating, and deleting products, and delegates the actual logic to the ProductsService.&lt;/li&gt;
&lt;li&gt;Why it's important: Controllers define the API endpoints and handle incoming HTTP requests. They keep the endpoint logic separate from the business logic, promoting code organization and maintainability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;products/product.module.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { ProductsController } from './products.controller';
import { ProductsService } from './products.service';
import { ProductEntity } from './product.entity';

@Module({
  imports: [TypeOrmModule.forFeature([ProductEntity])],
  controllers: [ProductsController],
  providers: [ProductsService],
})
export class ProductsModule {}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: This module encapsulates the products-related components: the controller, service, and entity. It imports the TypeOrmModule to provide database-related functionalities.&lt;/li&gt;
&lt;li&gt;Why it's important: Modules help organize code into cohesive units and define the boundaries of the application. They encapsulate related functionality and promote code reusability and maintainability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;products/product.service.ts&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { Injectable, NotFoundException } from "@nestjs/common";
import { InjectRepository } from "@nestjs/typeorm";
import { Repository } from "typeorm";
import { ProductEntity } from "./product.entity";

@Injectable()
export class ProductsService {
  constructor(
    @InjectRepository(ProductEntity)
    private readonly productRepository: Repository&amp;lt;ProductEntity&amp;gt;,
  ) {}

  async insertProduct(title: string, desc: string, price: number) {
    const newProduct = await this.productRepository.create({
      title,
      description: desc,
      price,
    });
    await this.productRepository.save(newProduct);
    return newProduct.id;
  }

  async getProducts() {
    return await this.productRepository.find();
  }

  async getSingleProduct(productId: string) {
    return await this.productRepository.findOne({ where: { id: productId } });
  }


  async updateProduct(productId: string, title: string, desc: string, price: number) {
    const product = await this.productRepository.findOne({ where: { id: productId } });
    if (!product) {
      throw new NotFoundException('Could not find product');
    }
    product.title = title || product.title;
    product.description = desc || product.description;
    product.price = price || product.price;
    await this.productRepository.save(product);
  }


  async deleteProduct(prodId: string) {
    const result = await this.productRepository.delete(prodId);
    if (result.affected === 0) {
      throw new NotFoundException('Could not find product');
    }
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;Explanation: This service contains methods to perform CRUD operations on products. It interacts with the database using the ProductEntity and TypeORM.&lt;/li&gt;
&lt;li&gt;Why it's important: Services encapsulate business logic and data manipulation tasks. They provide a clean separation between data access and controller logic, promoting code maintainability and testability.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Understanding the files and their functionalities in the products folder is crucial for building a complete NestJS application with CRUD operations for managing products. These files work together to handle HTTP requests, interact with the database, and provide a seamless user experience.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Congratulations! You've successfully created and explored a basic NestJS project. This is just the beginning of your journey with NestJS. As you continue to explore the framework, you'll discover its rich features and capabilities for building robust server-side applications.&lt;/p&gt;

&lt;p&gt;In the next steps, you can experiment with adding new routes, services, and modules to extend the functionality of your NestJS application. Don't hesitate to refer to the official NestJS documentation for more in-depth explanations and examples.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

&lt;p&gt;github:&lt;a href="https://github.com/adewale-codes/nest_crud"&gt;https://github.com/adewale-codes/nest_crud&lt;/a&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Creating a responsive sidebar</title>
      <dc:creator>adewale-codes</dc:creator>
      <pubDate>Thu, 22 Feb 2024 11:01:58 +0000</pubDate>
      <link>https://dev.to/adewalecodes/creating-a-responsive-sidebar-972</link>
      <guid>https://dev.to/adewalecodes/creating-a-responsive-sidebar-972</guid>
      <description>&lt;p&gt;Developing a responsive sidebar in ReactJS usually requires a blend of CSS for styling and React components for handling state and rendering. Additionally, external libraries such as Tailwind CSS can be employed to facilitate CSS, as demonstrated in this project.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Getting started:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Initially, establish a new directory for the sidebar application. Subsequently, in the terminal, input the command npm create &lt;a href="mailto:vite@latest"&gt;vite@latest&lt;/a&gt;. Finally, execute npm run dev to launch the web application.&lt;/p&gt;

&lt;p&gt;Here is a sample&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx create-vite@latest sidebar - template react
cd sidebar
npm install
npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's proceed with the installation of Tailwind CSS. Initially, we need to install Tailwind and its dependencies by executing the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm install -D tailwindcss postcss autoprefixer
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Afterward, generate the Tailwind CSS configuration files by using the following command. This will create the default configuration files, namely tailwind.config.js and postcss.config.js, in the root directory of your project&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npx tailwindcss init -p
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure the postcss.config.js file by opening the generated file and ensuring that it resembles the following:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;module.exports = {
 plugins: {
 tailwindcss: {},
 autoprefixer: {},
 },
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Set up index.css to incorporate Tailwind CSS: Access the src/index.css file (or establish it if not present) and import Tailwind CSS.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;@import 'tailwindcss/base';
@import 'tailwindcss/components';
@import 'tailwindcss/utilities';
/* Your additional styles here */
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Start or restart your Vite development server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm run dev
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's begin developing our component in App.jsx. &lt;br&gt;
The import statement includes a particular function, useState, from the "react" library. useState is a React hook utilized for state management in functional components.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sidebar Component: This defines a functional component named "Sidebar." In React, components are reusable code blocks that encapsulate specific portions of the user interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Sidebar = () =&amp;gt; {
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;State Management: This code line initializes a state variable named "open" along with a function "setOpen" to handle the state. By using useState(true), the initial value of "open" is set to true. This state is employed to govern whether the sidebar is in an open or closed state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [open, setOpen] = useState(true);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Menu Items: A array named "Menus" is introduced, comprising objects that represent distinct menu items. Each object possesses properties such as "title" (denoting the menu item name) and "src" (indicating the icon source).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const Menus = [
 { title: "Overview", src: "Overview" },
 { title: "Transactions", src: "Transactions" },
 { title: "Loyalty Cards", src: "Card", gap: true },
 { title: "Subscriptions ", src: "Calendar" },
 { title: "Debts", src: "Debt" },
 { title: "Legal information", src: "Legal" },
 { title: "Notifications ", src: "Notifications", gap: true },
 { title: "Setting", src: "Settings" },
 ];
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Return Statement (JSX): Within the return statement, you'll find the JSX (JavaScript XML) code outlining the structure of the sidebar component. JSX is a JavaScript syntax extension frequently employed with React to define the desired appearance of the user interface.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;return (
 &amp;lt;div className="flex"&amp;gt;
 {/* … (code for sidebar structure) */}
 &amp;lt;/div&amp;gt;
);
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sidebar Structure: The primary structure of the sidebar is established by this div element. The className attribute incorporates a collection of CSS classes influencing the sidebar's appearance and functionality. The "open" variable dynamically adjusts the sidebar's width, contingent on whether it is open or closed.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;div className={` ${open ? "w-72" : "w-20 "} bg-black h-screen p-5 pt-8 relative duration-300`}&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Event Handling: A control button utilizes an image. When this button is clicked, it activates the setOpen function, toggling the value of "open" between true and false. This action produces the effect of opening and closing the sidebar.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;img
 src="/assets/control.png"
 onClick={() =&amp;gt; setOpen(!open)}
/&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rendering Menu Items: This section of the code iterates through the "Menus" array, rendering each menu item as a list item (&lt;/p&gt;
&lt;li&gt;). The presentation of each item is influenced by the state variable "open"

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{Menus.map((Menu, index) =&amp;gt; (
 // … (code for rendering each menu item)
))}
&lt;/code&gt;&lt;/pre&gt;


&lt;p&gt;In essence, this code constructs a responsive sidebar featuring a set of menu items. The sidebar's open and closed states are controlled by clicking a control button, enhancing the user's navigation experience in a web application.&lt;/p&gt;

&lt;p&gt;Here is the complete code:&lt;br&gt;
&lt;/p&gt;

&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { useState } from "react";
const Sidebar = () =&amp;gt; {
 const [open, setOpen] = useState(true);
 const Menus = [
 { title: "Overview", src: "Overview" },
 { title: "Transactions", src: "Transactions" },
 { title: "Loyalty Cards", src: "Card", gap: true },
 { title: "Subscriptions ", src: "Calendar" },
 { title: "Debts", src: "Debt" },
 { title: "Legal information", src: "Legal" },
 { title: "Notifications ", src: "Notifications", gap: true },
 { title: "Setting", src: "Settings" },
 ];
 return (
 &amp;lt;div className="flex"&amp;gt;
 &amp;lt;div
 className={` ${
 open ? "w-72" : "w-20 "
 } bg-black h-screen p-5 pt-8 relative duration-300`}
 &amp;gt;
 &amp;lt;img
 src="/assets/control.png"
 className={`absolute cursor-pointer -right-3 top-9 w-7 border-dark-purple
 border-2 rounded-full ${!open &amp;amp;&amp;amp; "rotate-180"}`}
 onClick={() =&amp;gt; setOpen(!open)}
 /&amp;gt;
 &amp;lt;div className="flex gap-x-4 items-center"&amp;gt;
 &amp;lt;img
 src="/assets/smiley.svg"
 className={`cursor-pointer duration-500 ${
 open &amp;amp;&amp;amp; "rotate-[360deg]"
 }`}
 /&amp;gt;
 &amp;lt;h1
 className={`text-white origin-left font-medium text-xl duration-200 ${
 !open &amp;amp;&amp;amp; "scale-0"
 }`}
 &amp;gt;
 AdeCodes
 &amp;lt;/h1&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;ul className="pt-6"&amp;gt;
 {Menus.map((Menu, index) =&amp;gt; (
 &amp;lt;li
 key={index}
 className={`flex rounded-md p-2 cursor-pointer hover:bg-light-white text-gray-300 text-sm items-center gap-x-4 
 ${Menu.gap ? "mt-9" : "mt-2"} ${
 index === 0 &amp;amp;&amp;amp; "bg-light-white"
 } `}
 &amp;gt;
 &amp;lt;img src={`/assets/${Menu.src}.svg`} /&amp;gt;
 &amp;lt;span className={`${!open &amp;amp;&amp;amp; "hidden"} origin-left duration-200`}&amp;gt;
 {Menu.title}
 &amp;lt;/span&amp;gt;
 &amp;lt;/li&amp;gt;
 ))}
 &amp;lt;/ul&amp;gt;
 &amp;lt;/div&amp;gt;
 &amp;lt;/div&amp;gt;
 )
}
export default Sidebar
&lt;/code&gt;&lt;/pre&gt;



&lt;p&gt;GitHub Link: &lt;a href="https://github.com/adewale-codes/responsive-sidebar"&gt;https://github.com/adewale-codes/responsive-sidebar&lt;/a&gt;&lt;/p&gt;


&lt;/li&gt;

</description>
    </item>
  </channel>
</rss>
