Backend Init
สิ่งที่จะสร้าง
หัวข้อที่มีชื่อว่า “สิ่งที่จะสร้าง”แอปพลิเคชัน NestJS ที่ apps/api ต่อสายให้อ่านพอร์ตจาก root .env ของ monorepo ผ่าน @nestjs/config พร้อม dependency ทุกตัวที่คอร์สที่เหลือต้องการติดตั้งไว้แล้ว
Nest CLI (nest new) สร้างโครงสร้าง module/controller/service, tsconfig.json และการตั้งค่าเทสต์ที่ทุกบทเรียนถัดไปต่อยอด การเขียน boilerplate ชุดนั้นเองไม่ได้อะไรเพิ่ม แถมเสี่ยงได้ config ที่เพี้ยนจากที่คอร์สคาดไว้นิดหน่อย ส่วน @nestjs/config รวมการเข้าถึง environment ไว้ที่เดียวผ่าน ConfigService ที่มี type แทนที่จะปล่อยให้อ่าน process.env ดิบ ๆ กระจายไปทั่วโค้ด
ข้อดีข้อเสีย
หัวข้อที่มีชื่อว่า “ข้อดีข้อเสีย”nest new เทียบกับ npm init เอง CLI ต่อสาย ESLint, Jest, tsconfig.json และ nest-cli.json ของ Nest ให้ในขั้นตอนเดียว และทุก scaffold ออกมาหน้าตาเหมือนกัน ซึ่งสำคัญมากตอนเรียนตามคอร์ส ต้นทุนคือ CLI มองว่านี่เป็นโปรเจกต์เดี่ยว ๆ ค่าเริ่มต้นจึงสร้าง git repo ของตัวเองขึ้นมา ซึ่งเราไม่ต้องการใน monorepo ที่ git init ไว้ที่ root แล้ว จึงใส่ --skip-git เพื่อเลี่ยง repository ซ้อนกัน และ --package-manager npm เพื่อเลี่ยง prompt แบบโต้ตอบ
ติดตั้ง dependency รวดเดียว เทียบกับติดตั้งทีละตัวตอนใช้จริง ติดตั้งทุกอย่างตอนนี้เลย (GraphQL, Mongoose, auth, validation) แปลว่าขั้นตอน npm install ของทุกโมดูลถัดไปเสร็จไปแล้ว และสร้าง package-lock.json ครั้งเดียวจบ สิ่งที่แลกคือการติดตั้งรอบแรกนานขึ้น และ package.json มี dependency ของ GraphQL กับ auth ตั้งแต่ยังไม่มี resolver หรือ guard สักตัว ตรงนี้ยอมรับได้ เพราะลิสต์ dependency ของคอร์สคงที่และรู้ล่วงหน้าอยู่แล้ว
ติดตั้ง
หัวข้อที่มีชื่อว่า “ติดตั้ง”Scaffold API เข้าไปที่ apps/api โดยข้าม git repo ที่ซ้อนกัน เพราะ root ของ monorepo มี git ของตัวเองอยู่แล้ว:
cd devblognest new apps/api --package-manager npm --skip-gitcd apps/apinest new เพิ่ม @nestjs/core, @nestjs/common และ @nestjs/platform-express ลงใน package.json ให้แล้ว ไม่ต้องติดตั้งซ้ำ ที่เหลือติดตั้งตามนี้ จัดกลุ่มตามหน้าที่ของแต่ละชุด:
# env vars from the root .env, via ConfigServicenpm install @nestjs/config
# code-first GraphQL, served at /graphql by Apollo Servernpm install @nestjs/graphql @nestjs/apollo @apollo/server graphql
# MongoDB models and schemas via Mongoosenpm install @nestjs/mongoose mongoose
# JWT auth: Passport strategy, JWT signing/verification, password hashingnpm install @nestjs/passport passport passport-jwt @nestjs/jwt bcrypt
# DTO and GraphQL input validationnpm install class-validator class-transformer
# deterministic, URL-safe post slugsnpm install slugify
# type definitions for the auth packages abovenpm install -D @types/passport-jwt @types/bcryptแก้ src/app.module.ts ให้โหลด root .env แบบ global:
import { Module } from '@nestjs/common';import { ConfigModule } from '@nestjs/config';import { AppController } from './app.controller';import { AppService } from './app.service';
@Module({ imports: [ ConfigModule.forRoot({ isGlobal: true, envFilePath: '../../.env', }), ], controllers: [AppController], providers: [AppService],})export class AppModule {}envFilePath resolve จากตำแหน่งที่ process ของ Nest รันอยู่ (apps/api) ดังนั้น ../../.env จึงชี้ไปที่ devblog/.env ไฟล์ที่ Repo layout สร้างไว้ ส่วน isGlobal: true แปลว่าโมดูลไหนต่อจากนี้ก็ inject ConfigService ได้โดยไม่ต้อง import ConfigModule ซ้ำ
แก้ src/main.ts ให้ฟังที่ API_PORT แทนพอร์ตที่ hardcode ไว้:
import { NestFactory } from '@nestjs/core';import { ConfigService } from '@nestjs/config';import { AppModule } from './app.module';
async function bootstrap() { const app = await NestFactory.create(AppModule); const configService = app.get(ConfigService); const port = configService.get<number>('API_PORT') ?? 4000; await app.listen(port); console.log(`API listening on http://localhost:${port}`);}bootstrap();สตาร์ตแบบ watch mode:
npm run start:devตรวจสอบผล
หัวข้อที่มีชื่อว่า “ตรวจสอบผล”คอนโซลควรพิมพ์ log การ bootstrap ของ Nest จบด้วยบรรทัดที่คุณเพิ่มเอง:
[Nest] ... LOG [NestApplication] Nest application successfully startedAPI listening on http://localhost:4000ในอีก terminal หนึ่ง:
curl http://localhost:4000# Hello World!Hello World! คือ response ค่าเริ่มต้นจากคู่ AppController/AppService ที่ scaffold มาให้ เห็นข้อความนี้แปลว่าแอปบูตสำเร็จ ConfigService อ่าน API_PORT ได้ถูกต้อง (4000 จาก .env) และ HTTP server เข้าถึงได้แล้ว
apps/api คือแอปที่ Nest CLI scaffold ให้ พร้อม dependency ของคอร์สครบทุกตัวตั้งแต่ต้น จัดกลุ่มตามหน้าที่: @nestjs/config สำหรับเข้าถึง environment, GraphQL/Apollo สำหรับเลเยอร์ API, Mongoose สำหรับ MongoDB, Passport/JWT/bcrypt สำหรับ auth, class-validator/class-transformer สำหรับ validation และ slugify สำหรับ slug ของโพสต์ ตอนนี้ main.ts อ่านพอร์ตจาก root .env ผ่าน ConfigService ที่มี type แทนตัวเลข hardcode และ npm run start:dev ยืนยันแล้วว่าบูตขึ้นที่พอร์ต 4000
ถัดไป: Frontend init →