NestJS এ সূচনা

NestJS হচ্ছে জাভাস্ক্রিপ্ট অথবা টাইপস্ক্রিপ্ট ব্যবহার করে সার্ভার সাইড অ্যাপ তৈরি করার জন্য NodeJS ফ্রেমওয়ার্ক।

ওয়েব অ্যাপ তৈরির জন্য নোডের আরেকটা আরেকটা জনপ্রিয় ফ্রেমওয়ার্ক হচ্ছে ExpressJS । এক্সপ্রেসে আমরা নিজের মত করে যে কোন ভাবেই কোড লিখতে পারি। খুবি সহজ। এক্সপ্রেস ব্যবহার করে একটা HelloWorld API তৈরি করার জন্য ঠিক এতটুকু দরকারঃ

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

সেখানে নেস্ট দিয়ে একই রেজাল্টের জন্য একাধিক কোড লিখতে হয়। এর কারণ হচ্ছে নেস্টে আর্কিটেকচার ফলো করে কোড লিখতে হয়। যদিও নেস্ট API এর জন্য এক্সপ্রেস অথবা Fastify ব্যবহার করে। একটা স্কেলেবল অ্যাপ তৈরি করার জন্য যা কিছু দরকার, সব মডিউল নেস্টে বিল্টইন রয়েছে। এই জন্য লার্নিং কার্ভ একটু বেশি। শুরুতে একটু সব কিছু বুঝতে অসুবিধা হলেও ডেভেলপমেন্ট এবং প্রজেক্ট ম্যানেজমেন্ট অনেক সহজ করে।

নেস্ট মডেল – ভিউ – কন্ট্রোলার প্যাটার্ণ ফলো করে। কেউ যদি লারাভেলে কোড লিখে থাকেন, তাহলে সিমিলারিটি পাবেন। নেস্টের নিজস্ব কমান্ডলাইন ট্যুল রয়েছে। যা ব্যবহার করে প্রজেক্ট তৈরি, মডেল তৈরি সহ অন্যান্য কাজ করা যাবে।

NestJS ইন্সটল

NestJS কম্পিউটারে ইন্সটল করার পূর্বে NodeJS ইন্সটল করতে হবে। এরপর নিচের কমান্ড রান করবঃ

 npm install -g @nestjs/cli

এতটুকুই। এরপর আমরা next কমান্ড ব্যবহার করে প্রজেক্ট তৈরি সহ অন্যান্য কাজ করতে পারব। যেমন একটা নতুন প্রজেক্ট তৈরির জন্যঃ

nest new hello

আমাদের জিজ্ঞেস করবে কোন প্যাকেজ ম্যানেজার ব্যবহার করব। আমি সিলেক্ট করলাম npm। এরপর নেস্ট প্রজেক্ট তৈরি হবে।

এবার এই ফোল্ডারে গিয়ে প্রজেক্ট রান করতে পারব। তার জন্য লিখবঃ

cd hello
npm run start:dev

তাহলে লোকাল হোস্টের 3000 পোর্টে অ্যাপ রান হবে। ব্রাউজারে http://localhost:3000/ URL ভিজিট করলে আমরা দেখতে পাবো Hello World!

npm run start কমান্ড দিয়েও রান করা যাবে। তবে npm run start:dev কমান্ডে হট রিলোড হবে।

একটা নেস্ট প্রজেক্ট তৈরি করার পর src ফোল্ডারে নিচের ফাইল গুলো দেখতে পাবোঃ

এখানে অ্যাপের এন্ট্রি পয়েন্ট হচ্ছে main.ts

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  await app.listen(process.env.PORT ?? 3000);
}
bootstrap();

এখানে মূলত দুইটা অংশ। একটা হচ্ছে NestFactory.create(AppModule)। যা দিয়ে আমরা বলেছি অ্যাপের রুট মডিউল হচ্ছে AppModule, যা ব্যবহার করে একটা নেস্ট অ্যাপ রান করতে। আর পরবর্তী লাইনে বলেছি কোন পোর্টে অ্যাপটা ওপেন হবে।

রুট মডিউল app.module.ts

import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';

@Module({
  imports: [],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

মডিউলের কাজ হচ্ছে সব কিছুকে একত্র করা। যেমন একটা মডেল (User, Data etc) রিলেটেড সব কিছু একত্র করার কাজ করে মডিউল। @module ডেকোরেটর ব্যবহার করে মডিউল বুঝানো হয়। আর একটা নেস্ট অ্যাপে মিনিমাম একটা মডিউল থাকা লাগে। উপরে দুইটা ফাইল যোগ করেছি, একটা হচ্ছে কন্ট্রোলার, আরেকটা হচ্ছে প্রোভাইডার। রাউট গুলো থাকে কন্ট্রোলারে এবং কোন রাউট কল করলে কি ডেটা দেখাবে, মানে বিজনেস লজিক থাকে প্রোভাইডারে।

কন্ট্রোলারapp.controller.ts

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();
  }
}

কন্ট্রোলার HTTP রিকোয়েস্ট গুলো হ্যান্ডেল করে। কোন ক্লাসের আগে @Controller() ডেকোরেটর দিয়ে বুঝানো হয় যে এটা একটা কন্ট্রোলার। এখানে রাউট গুলো লেখা হয়। উপরের কন্ট্রোলারে একটা গেট রাউট রয়েছে। @Get() রাউট দিয়ে GET রিকোয়েস্ট বুঝানো হয়। এই রাউটে রিকোয়েস্ট আসলে প্রোভাইডার this.appService.getHello() থেকে ডেটা রিটার্ণ করবে।

প্রোভাইডার / সার্ভিস app.service.ts

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
}

এই সার্ভিস ফাইলে সাধারণত নির্দিষ্ট মডেলের বিজনেস লজিক গুলো থাকে। সার্ভিস ফাইলে @Injectable() ডেকোরেটর ব্যবহার করা হয়। যা দিয়ে যেখানে এই ক্লাস দরকার, সেখানে NestJS এই ক্লাস ইনজেক্ট করে। এই ক্ষেত্রে AppController এ ইনজেক্ট করা হয়েছে। getHello() মেথড 'Hello World!' স্ট্রিং রিটার্ণ করেছে।

যেভাবে কাজ করেঃ

এবার hello world অ্যাপে আরেকটা রাউট যোগ করি। তাহলে নেস্ট অ্যাপ কিভাবে কাজ করে, তা আরেকটু ক্লিয়ার হবো আমরা। যেমন আমরা /about নামে আরেকতে GET রাউট যোগ করব। তার জন্য app.controller.ts ফাইলে নিচের কোড যোগ করব।

 @Get('about')
  getAbout(): string {
    return this.appService.getAboutInfo();
  }

সম্পূর্ণ ফাইলঃ

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();
  }

  @Get('about')
  getAbout(): string {
    return this.appService.getAboutInfo();
  }
}

এই /about রাউট রিকোয়েস্ট করলে সার্ভিস থেকে this.appService.getAboutInfo() মেথড কল করবে। তার জন্য এই মেথড app.service.ts যোগ করবঃ

 getAboutInfo(): string {
    return 'This is a simple NestJS app created for learning.';
  }

সম্পূর্ণ ফাইলঃ

import { Injectable } from '@nestjs/common';

@Injectable()
export class AppService {
  getHello(): string {
    return 'Hello World!';
  }
   getAboutInfo(): string {
    return 'This is a simple NestJS app created for learning.';
  }
}

এতটুকুই।

এবার অ্যাপটা আবার রান করে দেখুন।

npm run start:dev

এরপর http://localhost:3000/about ভিজিট করলে আমাদের নিউ রাউটে রিটার্ণ করবে ‘This is a simple NestJS app created for learning.’

পোস্ট রিকোয়েস্ট

/hello রাউটে একটা পোস্ট রিকোয়েস্ট যোগ করব। তার জন্য app.controller.ts এ এভাবে পোস্ট রাউটের জন্য কোড লিখবঃ


  @Post('hello')
  postContact(@Body('name') name: string): string {
    return this.appService.greetUser(name);
  }

এই কন্ট্রোলালে আগে শুধুমাত্র আমরা GET রাউট ব্যবহার করেছি। এখন POST এবং রিকোয়েস্ট বডি ব্যবহার করছি। তাই আমাদের সব কিছু ইম্পোর্ট করে নিতে হবে এভাবেঃ

import { Controller, Get, Post, Body } from '@nestjs/common';

সম্পূর্ণ app.controller.ts ফাইলঃ

import { Controller, Get, Post, Body } from '@nestjs/common';
import { AppService } from './app.service';

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

  @Get()
  getHello(): string {
    return this.appService.getHello();
  }

  @Get('about')
  getAbout(): string {
    return this.appService.getAboutInfo();
  }

  @Post('hello')
  postContact(@Body('name') name: string): string {
    return this.appService.greetUser(name);
  }
}

app.service.ts এ greetUser মেথড এভাবে লিখবঃ

  greetUser(name?: string): string {
    return name ? `Hello, ${name}!` : "Hello Guest";
  }

এই মেথড name নামে অপশনাল প্যারামিটার গ্রহণ করবে। যদি ঐ প্যারামিটার পায় তাহলে Hello + name রিটার্ণ করবে। name প্যারামিটার না পাঠালে Hello Guest রিটার্ণ করবে।

এবার যে /hello রাউটে পোস্ট রিকোয়েস্ট করে নিচের মত করে name পাঠাতে পারেনঃ

{
    "name" : "Your Name"
}

অথবা কমান্ডলাইনেও টেস্ট করতে পারেনঃ

curl -X POST -H "Content-Type: application/json" -d '{"name": "Your Name"}' http://localhost:3000/hello

Hello + Your Name! রিটার্ণ করবে।

শুরুতে যত কঠিন মনে হয়েছে, এখন আর তত কঠিন লাগছে না, তাই না?

Leave a Comment