SlideShare a Scribd company logo
NEST.JS
RESTFUL API
Babel Coder
https://www.babelcoder.com
แนะนําตัว
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
BABEL CODER
Nuttavut T
https://www.babelcoder.com
Babel Coder
https://www.babelcoder.com
แนะนําบทเรียน
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
Part I: RESTful API
Part II: GraphQL
Part III: Microservices
Part IV: Miscellaneous
Babel Coder
Babel Coder
https://www.babelcoder.com
สัดส่วน
บรรยาย
65%
แบบฝึกหัด
25%
ทดสอบโคด
9%
โปรเจค / ปฏิบัติ
1%
เน้นการบรรยายประกอบสไลด์
เน้นการมีส่วนร่วมผ่านแบบฝกหัด
RESTFUL API
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
CLIENT / SERVER
/products
Babel Coder
Babel Coder
https://www.babelcoder.com
CLIENT / SERVER
/products
Babel Coder
Babel Coder
https://www.babelcoder.com
JSON
CLIENT / SERVER
/products
Babel Coder
Babel Coder
https://www.babelcoder.com
RESTFUL API
C 1 C 2 C 2 C 2
RESTful API คือเว็บเซอร์วิสรูปแบบหนึงทีกําหนดให้ API ประกอบด้วยทรัพยากรที Client สามารถร้องขอเพือเข้าถึงได้ โดย
Client จะทําการระบุทรัพยากรทีต้องการเข้าถึงผ่าน URL และระบุการดําเนินการผ่าน HTTP Method
/products
Product
Order
User
Comment
URL
Method GET
เมือ API ประมวลผลเสร็จสินจะคืนผลลัพธ์กลับมาในฟอร์แมตต่าง ๆ เช่น JSON เพือให้ Client ทราบว่าผลลัพธ์การทํางานเปนเช่น
ไร API ต้องส่ง HTTP Status Code กลับด้วย พร้อมระบุ MIME Type เพือบอกชนิดของข้อมูลทีส่งกลับ
MIME Type
Status
Response
application/json
200 OK
Babel Coder
Babel Coder
https://www.babelcoder.com
HTTP
Method
URL ความหมาย Status เมือสําเร็จ Status เมือไม่สําเร็จ
GET /products ร้องขอข้อมูล Products ทังหมด 200 OK
GET /products/1 ร้องขอข้อมูล Product ทีมี ID เปน 1 200 OK 404 NOT FOUND
POST /products สร้างข้อมูล Product ตัวใหม่ 201 CREATED
400 BAD REQUEST
422 UNPROCESSIBLE ENTITY
PATCH /products/1 อัพเดทข้อมูลบางส่วนของ Product ทีมี ID เปน 1 200 OK
400 BAD REQUEST
422 UNPROCESSIBLE ENTITY
DELETE /products/1 ลบข้อมูลของ Product ทีมี ID เปน 1
200 OK
204 NO CONTENT
404 NOT FOUND
RESTFUL API
Babel Coder
Babel Coder
https://www.babelcoder.com
PAYLOAD
/products
Product
Order
User
Comment
URL
Method POST
MIME Type application/json
Validate
400
BAD
REQUEST
422
UNPROCESSIBLE
ENTITY
Babel Coder
Babel Coder
https://www.babelcoder.com
URL
Method
MIME Type
name
price
categoryIds[]
categoryIds[]
image
FORM DATA
/products
Product
Order
User
Comment
POST
multipart/form-data
Validate
400
BAD
REQUEST
422
UNPROCESSIBLE
ENTITY
Lorem
200
12
34
File
Form
Data
Babel Coder
Babel Coder
https://www.babelcoder.com
NEST.JS
Nest.js เปนเฟรมเวิร์กสําหรับการสร้าง API โดยใช้ภาษา TypeScript เปนหลัก โดยพืน
ฐานแล้ว Nest.js พัฒนาต่อยอดบน Express.js อีกที
Nest CLI Nest มาพร้อมกับเครืองมือในรูปแบบ CLI ทีช่วยในการสร้างโปรเจคและสร้างไฟล์ส่วนประกอบต่าง ๆ อย่าง
ง่ายดาย
Architecture Nest สนับสนุนการสร้าง API บนสถาปตยกรรมของ RESTful API และ API รูปแบบอืน เช่น GraphQL
และ gPRC รวมถึงการสร้าง Microservices ด้วยเช่นกัน
Dependency Injection Nest สามารถสร้างออปเจ็กต์และผูกความสัมพันธ์ของออปเจ็กต์ (Wiring up) อย่าง
อัตโนมัติตามความสามารถของ Dependency Injection
Babel Coder
Babel Coder
https://www.babelcoder.com
ARCHITECTURE
Orders Controller
Products Controller
Users Controller
/products
Orders Service
Products Service
Users Service
Controllers เปนส่วนจัดการเกียวกับระบบ
Routing เพือจัดการงานด้าน Request และ
Response
Services เปนส่วนจัดการ Logic หลักของ API เช่น
การเชือมต่อกับฐานข้อมูลและงานด้านการคํานวณ
ต่าง ๆ เปนต้น Services สามารถถูกเรียกใช้จาก
Controllers ได้
Database
Babel Coder
Babel Coder
https://www.babelcoder.com
imports
Products
Products Controller Products Service
inject
UsersModule
providers ProductsService
imports
Auth
Auth Controller Auth Service
inject
UsersModule
providers AuthService
exports AuthService
@Global()
MODULES
Users Controller Users Service
providers
exports
Users
inject
UsersService
UsersService
inject
Global Modules สามารถใช้งานได้เลยโดยไม่ต้อง
ทําการระบุในส่วนของ imports
controllers UsersController
controllers AuthController
controllers ProductsController
Babel Coder
Babel Coder
https://www.babelcoder.com
SETTING UP
$ npx @nestjs/cli new api
Which package manager would you to use? pnpm
ทําการสร้างโปรเจคชือ api ผ่าน Nest CLI โดย
เลือกใช้ Package Manager เปน pnpm
api
nest-cli.json
src
app.controller.ts
app.module.ts
app.service.ts
main.ts
App Module
ไฟล์การทํางานหลัก สามารถตังค่าการทํางานแบบ Global ได้ในไฟล์นี
ไฟล์ตังค่าการทํางานของ Nest CLI
CRUD
NEST.JS
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
app.module.ts
PRODUCTS MODULE
$ npx nest g module products
สร้าง ProductsModule และ
ProductsController ตามลําดับ
api
src
app.controller.ts
app.service.ts
main.ts
products
products.controller.ts
products.module.ts
$ npx nest g controller products
Babel Coder
Babel Coder
https://www.babelcoder.com
app.module.ts
PRODUCTS MODULE
api
src
app.controller.ts
app.service.ts
main.ts
products
products.controller.ts
products.module.ts
Babel Coder
Babel Coder
https://www.babelcoder.com
PRODUCTS CONTROLLER
GET /products หรือ /products?page=2&limit=10
GET /products/:id เช่น /products/1
POST /products
PATCH /products/:id เช่น /products/1
DELETE /products/:id เช่น /products/1
Babel Coder
Babel Coder
https://www.babelcoder.com
PARAM AND PIPES
GET /products/:id เช่น /products/1
แปลงจาก ‘1’ เปน 1
Babel Coder
Babel Coder
https://www.babelcoder.com
Orders Controller
Products Controller
CreateProduct
Dto
Payload
DATA TRANSFER OBJECT
POST /products
Product
ResponseDto
Babel Coder
Babel Coder
https://www.babelcoder.com
DATA TRANSFER OBJECT
$ pnpm add @nestjs/mapped-types
ทําการติดตังแพคเกจ @nestjs/mapped-types ก่อนการใช้
PartialType
Babel Coder
Babel Coder
https://www.babelcoder.com
dtos
find-all-query.dto.ts
DTO
DATA TRANSFER OBJECT
api
src
products
products.controller.ts
products.module.ts
types
GET /products?page=2&limit=10
Babel Coder
Babel Coder
https://www.babelcoder.com
PRODUCT SERVICE
api
src
products
products.controller.ts
products.module.ts
products.service.ts
$ npx nest g service products
คําสังสําหรับการสร้าง Service
Babel Coder
Babel Coder
https://www.babelcoder.com
PRODUCT SERVICE
api
src
products
products.controller.ts
products.module.ts
products.service.ts
Service ใช้เพือการ inject สู่ Controller
Babel Coder
Babel Coder
https://www.babelcoder.com
Products Service
DEPENDENCY INJECTION
inject
Providers
Babel Coder
Babel Coder
https://www.babelcoder.com
Status Code
201 CREATED
204 NO_CONTNET
HTTP RESPONSE STATUS
Status Code
400 BadRequestException
401 UnauthorizedException
403 ForbiddenException
422 UnprocessableEntityException
Success Failed
PAYLOAD
VALIDATION
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
Posts Controller
CreateProduct
Dto
Validation
Payload
PAYLOAD VALIDATION
POST /products
Payload Validation คือกระบวนการตรวจสอบว่าส่วนของ Payload ทีส่งเข้า
มาจาก Request นันมีโครงสร้างข้อมูลอย่างถูกต้องหรือใหม่ การตรวจสอบดัง
กล่าวนีจะส่งกลับ Status เปน 422 UNPROCESSIBLE ENTITY เมือ Payload
ทีส่งเข้ามาไม่ถูกต้อง
Babel Coder
Babel Coder
https://www.babelcoder.com
PAYLOAD VALIDATION
$ pnpm add class-validator class-transformer
กระบวนการของ Payload Validation จําเปนต้องติดตังแพคเกจคือ
class-validator และ class-transformer
กฎของการ Validate นํามาจากแพคเกจ
class-validator
Babel Coder
Babel Coder
https://www.babelcoder.com
PIPES
Controller Handlers
DTOs Pipes
validate
transform
CreateProductDto ValidationPipe ProductsController
create
Pipes คือคลาสทีมีการใช้ Decorator ชือ @Injectable ประกอบ เพือให้สามารถนําไป inject หรือใช้งานต่อได้ใน Controller route handler คลาสดังกล่าวมีการ
implement interface ชือ PipeTransform มีหน้าทีหลักสองประการคือ การตรวจสอบข้อมูล input (validate) และการเปลียนแปลงข้อมูล input (transform)
Babel Coder
Babel Coder
https://www.babelcoder.com
VALIDATION PIPE
ValidationPipe มาจากแพคเกจ
@nestjs/common
Controller route handler
Babel Coder
Babel Coder
https://www.babelcoder.com
GLOBAL SCOPED PIPES
main.ts
เนืองจากการตรวจสอบ Payload นันเปนเรืองพืนฐานทีควรกระทําในทุก ๆ Controller route handlers
ดังนัน Nest จึงควรตรวจสอบ Payload ด้วยการใช้งาน ValidationPipe โดยอัตโนมัติ
ส่วนนีสามารถกระทําได้โดยการตังค่าการใช้งาน ValidationPipe ให้เปนแบบ Global scoped pipes
คือให้ Pipes ดังกล่าวถูกใช้งานโดยอัตโนมัติในตลอดทังแอปพลิเคชันสําหรับทุก ๆ Controllers และ Route handlers
Babel Coder
Babel Coder
https://www.babelcoder.com
PAYLOAD VALIDATION
ValidationPipe
Babel Coder
Babel Coder
https://www.babelcoder.com
Transform
TRASFORMATION
GET /products?page=2&limit=10
page
limit
‘2’
‘10’
page
limit
2
10
validate
route handler
SERIALIZATION
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
SERIALIZATION
Users Controller
Serialization
Serialization เปนกระบวนการทีเกิดขึนก่อนส่งผลลัพธ์กลับสู่ Client โดยกระบวนการดังกล่าวสามารถกรองผลลัพธ์ทีไม่ต้องการออก
ไป และยังสามารถแปลงข้อมูลเปนผลลัพธ์สุดท้ายทีต้องการได้ Serialization สามารถกระทําได้ผ่านการกําหนดเงือนไขบน DTOs ทีเปน
ตัวแทนของ Response
response
interceptors
handlers
Babel Coder
Babel Coder
https://www.babelcoder.com
INTERCEPTIONS
Controller Handlers
Interceptors
Interceptors
request
response
Interceptors เปนคลาสทีมี decorator คือ @Injectable และ implement interface ชือ NestInterceptor มีหน้าทีในการจัดกับ
กับ request ก่อนเข้าสู่ Controller handlers และจัดการกับ response หลัง Controller handlers ทํางานเสร็จก่อนส่งผลลัพธ์
กลับสู่ Client
Babel Coder
Babel Coder
https://www.babelcoder.com
SERIALIZATION
หาก Property ใดไม่มีการใช้ @Expose()
จะไม่คืนค่า Property นันสู่ Client
Babel Coder
Babel Coder
https://www.babelcoder.com
SERIALIZATION
กรณีของการคืนค่ากลับเปน Array ให้ทําการใช้
map เพือแปลงแต่ละค่าเปน DTO
[ user, user, user ]
[ DTO, DTO, DTO]
Babel Coder
Babel Coder
https://www.babelcoder.com
GLOBAL INTERCEPTORS
CLASS-VALIDATOR
AND
CLASS-TRANSFORMER
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
Rule Description Example Correct Input Incorrect Input
@IsNotEmpty() จําเปนต้องระบุค่า Property นี
@IsNotEmpty()
email: string;
{ “email”:
“admin@babelcoder.com” }
{}
@IsEmail() Property ต้องมีฟอร์แมตเปน email
@IsEmail()
email: string;
{ “email”:
“admin@babelcoder.com” }
{ “email”:
“admin” }
@MinLength(number)
Property ต้องมีความยาวขันตําตามที
กําหนด
@MinLength(8)
password: string;
{ “password: “12345678” } { “password: “1” }
@IsObject()
Property ต้องมีชนิดข้อมูลเปนออปเจ็กต์
นิยมใช้คู่กับ @Type
@IsObject()
@Type(() => UserAddressDto)
address?: UserAddressDto;
{ “address”: { “road”:
“Petchaburi” } }
{ “address”: “” }
VALIDATORS
Babel Coder
Babel Coder
https://www.babelcoder.com
Rule Description Example Correct Input Incorrect Input
@IsOptional() Property จะระบุหรือไม่ระบุก็ได้
@IsOptional()
facebook?: string;
{ “facebook”:
undefined }
-
@IsString() Property ต้องมีชนิดข้อมูลเปน string
@IsString()
facebook: string;
{ “facebook”:
“babelcoder” }
{ “facebook”:
undefined }
@Length(min, max)
Property มีความยาวตําสุดคือ min สูงสุด
คือ max
@Length(5, 50)
name: string;
{ “name”:
“babelcoder” }
{ “name”: “bab” }
@IsNumber() Property ต้องมีชนิดข้อมูลเปน number
@IsNumber()
price: number;
{ “price”: 2000 } { “price”: “2000" }
VALIDATORS
Babel Coder
Babel Coder
https://www.babelcoder.com
Rule Description Example Correct Input Incorrect Input
@IsNumberString()
Property ต้องเปน string ของ
number
@IsNumberString()
page: string;
{ “page”: “1” } { “page”: “x” }
@Min(number)
Property เปนตัวเลขทีมีค่าขันตํา
ตามทีกําหนด
@Min(0)
port: number; { “port”: 3000 } { “port”: -3000 }
@Max(number)
Property เปนตัวเลขทีมีค่าขันสูง
ตามทีกําหนด
@Max(65535)
port: number;
{ “port”: 3000 } { “port”: 66535 }
@IsIn(array) Property ต้องมีค่าอยู่ในอาร์เรย์
@IsIn([’notice’, ‘info’, ‘debug’])
logLevel: string;
{ “logLevel”: “info” } { “logLevel”: “trace” }
VALIDATORS
Babel Coder
Babel Coder
https://www.babelcoder.com
Rule Description Example Correct Input Incorrect Input
@IsArray() Property ต้องมีค่าเปนอาร์เรย์
@IsArray()
categoryIds: number[]
{ “categoryIds”: [1, 2] } { “categoryIds”: “1,2” }
@ArrayMinSize(number)
Property ต้องมีค่าเปนอาร์เรย์ทีมีขนาดขัน
ตําตามทีกําหนด
@ArrayMinSize(1)
categoryIds: number[]
{ “categoryIds”: [1, 2] } { “categoryIds”: [] }
@IsDateString()
ตรวจสอบว่าเปน string ของ ISO8601
หรือไม่
@IsDateString()
publishedAt: Date;
2024-06-18T09:17:07Z
“Tue Jun 18 2024
19:32:37 GMT+0700
(Indochina Time)”
VALIDATORS
Babel Coder
Babel Coder
https://www.babelcoder.com
Rule Description Example Correct Input Incorrect Input
@IsInt Property ต้องมีค่าเปน Integer
@IsInt()
id: number
{ “id”: 1 } { “id”: 1.2 }
@IsBoolean Property ต้องมีค่าเปน true หรือ false
@IsBoolean()
isAdmin: boolean
{ “isAdmin”: true } { “isAdmin”: “true” }
VALIDATORS
Babel Coder
Babel Coder
https://www.babelcoder.com
VALIDATORS
Correct Incorrect
Babel Coder
Babel Coder
https://www.babelcoder.com
@TYPE
Input
PRISMA
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
SQL
PRISMA ORM
Prisma ORM เปนไลบรารีประเภท Object-Relational Mapping ทีทําหน้าทีในการติดต่อกับฐานข้อมูลได้หลากหลายประเภท
โดยทําการแปลงผลลัพธ์จากฐานข้อมูลให้อยู่ในรูปแบบของ Model ทีนิยามไว้ในไฟล์ schema.prisma โดย Model เหล่านัน
มีคุณสมบัติคือ Type-safe บนภาษา TypeScript
Babel Coder
Babel Coder
https://www.babelcoder.com
PRISMA ORM
api
prisma
schema.prisma
$ pnpm add -D prisma
$ npx prisma init --datasource-provider postgresql
$ npx prisma init --datasource-provider sqlserver
data source
ต้องกําหนดค่า DATABASE_URL เพือให้สามารถเชือมต่อไปยังฐานข้อมูลได้
Babel Coder
Babel Coder
https://www.babelcoder.com
MODELS
Primary Key
กําหนดค่าเริมต้นเมือไม่มีการระบุเข้ามา
ค่าเพิมขึนโดยอัตโนมัติ
ค่าไม่สามารถซํากันได้
รูปแบบการกําหนดความสัมพันธ์ระหว่าง
โมเดล (Relationship)
Babel Coder
Babel Coder
https://www.babelcoder.com
ONE-TO-ONE RELATIONSHIP
Babel Coder
Babel Coder
https://www.babelcoder.com
ONE-TO-MANY RELATIONSHIP
Babel Coder
Babel Coder
https://www.babelcoder.com
MANY-TO-MANY RELATIONSHIP
Babel Coder
Babel Coder
https://www.babelcoder.com
CASCADE
Cascade ใช้กําหนดเหตุการณ์ทีจะเกิดขึนเมือ Record ทีสัมพันธ์กันได้รับการอัพเดทหรือถูกลบ
กรณีของ onUpdate เมือ User เปลียนแปลง id ค่าของ userId บน Address จะเปลียนแปลงตาม
กรณีของ onDelete เมือ User ถูกลบจะส่งผลให้ Address ทีสัมพันธ์กันถูกลบตาม
Babel Coder
Babel Coder
https://www.babelcoder.com
@PRISMA/CLIENT
$ npx prisma generate
Generated Prisma Client (v5.15.0) to
.node_modules.pnpm@prisma+client@5.15.0_prisma
@5.15.0node_modules@prismaclient
api
node_modules
@prisma
client
หมายเหตุ: คําสังหลาย ๆ คําสังของ Prisma
จะมีการสร้าง Prisma Client ให้อัตโนมัติ เรา
จึงไม่จําเปนต้องออกคําสัง prisma
generate ด้วยตนเอง
Babel Coder
Babel Coder
https://www.babelcoder.com
id
DATABASE PUSING
name
id
name
slug
npx prisma db push
npx prisma db push
คําสังดังกล่าวจะทําให้เกิดการเปลียนแปลงโครงสร้างของฟลด์ในตารางโดยอัตโนมัติจึงควรใช้เฉพาะบน Development เท่านัน
Babel Coder
Babel Coder
https://www.babelcoder.com
DATABASE SEEDING
Database Seeding คือกระบวนการเตรียมข้อมูลไว้ในฐานข้อมูลบน Development เพือให้มีข้อมูลพร้อม
สําหรับการทดสอบ API โดยไม่ต้องทําการสร้างขึนมาทีละ Record ด้วยตนเอง
api
prisma
seed.ts
Babel Coder
Babel Coder
https://www.babelcoder.com
DATABASE SEEDING
Database Seeding คือกระบวนการเตรียมข้อมูลไว้ในฐานข้อมูลบน Development เพือให้มีข้อมูลพร้อม
สําหรับการทดสอบ API โดยไม่ต้องทําการสร้างขึนมาทีละ Record ด้วยตนเอง
api
package.json
$ pnpm add -D ts-node
$ npx prisma db seed
Babel Coder
Babel Coder
https://www.babelcoder.com
PRISMA STUDIO
$ npx prisma studio
Babel Coder
Babel Coder
https://www.babelcoder.com
DATABASE MIGRATION
development qa production
name
User
age
gender
name
User
age
name
User
Database Migration คือกระบวนการจัดโครงสร้างและข้อมูลของฐานข้อมูลปลายทางเพือให้มีผลลัพธ์เปนไป
ตามทีต้องการโดยอาศัย Script ทีรวมชุดคําสังในการแก้ไขเปลียนแปลงนัน ๆ
Babel Coder
Babel Coder
https://www.babelcoder.com
DATABASE MIGRATION
development qa production
name
User
age
gender
หากยังไม่เคยนําส่ง Migration scripts ไปยัง Environment อืนมาก่อน เมือเสร็จสินกระบวนการพัฒนาและพร้อมทีจะ
นําส่งไปยัง Environment อืน ให้ทําการสร้าง Migration แรกขึนมาก่อนทีจะทําการนําส่งสู่ Environment อืนต่อไป
$ npx prisma migrate dev --name init
api
prisma
migrations
20240613163955_init
migration.sql
Babel Coder
Babel Coder
https://www.babelcoder.com
npx prisma migrate deploy
MIGRATION DEPLOYMENT
development qa production
name
User
age
gender
เมือทําการ Deploy โค้ดไปยัง Environment อืนแล้ว เพือให้ฐานข้อมูลของ Environment ปลายทางมีโครงสร้างและ
ข้อมูลเปนไปตาม Migration scripts ให้ทําการใช้คําสัง npx prisma migrate deploy
$
name
User
age
gender
Babel Coder
Babel Coder
https://www.babelcoder.com
DATABASE MIGRATION
development qa production
fullname
User
age
gender
หากมีการสร้าง Migration scripts ขึนมาแล้วครังหนึง การเปลียนแปลงข้อมูลหรือ Model ใน schema.prisma ใด ๆ
จะต้องทําการสร้าง Migration scripts ทีสอดคล้องขึนมาใหม่เสมอ ๆ
$ npx prisma migrate dev --name changed_name_to_fullname_in_users
Babel Coder
Babel Coder
https://www.babelcoder.com
RESET DATABASE
$ npx prisma migrate reset
ใช้คําสังนีเพือล้างข้อมูลในฐานข้อมูลทังหมด
พร้อมรัน Migration และทํา Seeding ใหม่
Babel Coder
Babel Coder
https://www.babelcoder.com
DEVELOPMENT
$ npx prisma migrate dev
$ npx prisma db seed
กรณีทีมีนักพัฒนาหลายคนในทีม แน่นอนว่าฐานข้อมูลของแต่ละคนอาจมีโครงสร้างและข้อมูลแตกต่างกัน เพือให้ฐานข้อมูล
ของเราตรงกับ Migration scripts ปจจุบันในโค้ด ให้ใช้คําสัง prisma migrate dev และสามารถใช้ prisma db seed
เพือทํา Database seeding ได้
development
Babel Coder
Babel Coder
https://www.babelcoder.com
_prisma_migrations
20240610075129_init
1
MIGRATE DEV VS DB PUSH
$ npx prisma migrate dev
Real Database Shadow Database
prisma
migrations
20240610075129_init
20240611075218_change_name_to_fullname_in_user
20240613095117_add_address_tabler
model Article {
// ...
}
schema.prisma
Table
existing migrations
pending migrations
new migration
2
new migration
new migration
3
3
4
$ npx prisma generate 5
Babel Coder
Babel Coder
https://www.babelcoder.com
MIGRATE DEV VS DB PUSH
Prisma จะสร้าง shadow database ขึนมาเพือรัน migrations ทีระบุอยู่ใน Table คือ _prisma_migrations
ใหม่ทังหมด ทําให้เกิดโครงสร้างตารางใน shadow database
1.
ทําการเพิมเปลียนแปลงโครงสร้าง showdow database ตามไฟล์ migrations ทีมีอยู่ในโฟลเดอร์ migrations แต่
ไม่ระบุใน _prisma_migrations หรือกล่าวอย่างง่ายคือทําการ run migrations ทียังไม่ได้ถูก run นันเอง
2.
เปลียนเทียบการเปลียนแปลงทีระบุใน schema.prisma กับโครงสร้างข้อมูลทีเปนจริงใน shadow database แล้วจึง
ทําการสร้างไฟล์ migration เพือบันทึกการเปลียนแปลงนันเปนคําสัง SQL
3.
ทําการ run migration ใหม่นันทันทีทําให้เกิดการอัพเดท _prisma_migrations โดยใส่เลขเวอร์ชันของ migration
ใหม่นันลงไป
4.
สร้าง Prisma Client ผ่านคําสัง prisma generate และทํากระบวนการ seeding ข้อมูล
5.
Babel Coder
Babel Coder
https://www.babelcoder.com
QUERY
findUnique ใช้สําหรับการค้นหา Record เพียงตัวเดียว โดยต้องระบุเงือนไขใน where เพือค้นหาเฉพาะฟลด์ทีเปน
unique หรือ ID เท่านัน
Babel Coder
Babel Coder
https://www.babelcoder.com
QUERY
findFirst ใช้สําหรับการค้นหา Record แรก โดยต้องระบุเงือนไขใน where เพือค้นหา
Babel Coder
Babel Coder
https://www.babelcoder.com
QUERY
findMany ใช้สําหรับการค้นหา Record หลายจํานวน สามารถระบุเงือนไขการค้นหาผ่าน where หรือไม่ระบุก็ได้
Babel Coder
Babel Coder
https://www.babelcoder.com
33
LIMIT AND SKIP
24 11 24 24 33 24 24
24 24 24 24 24
24
24
24 24 24
age = 24
skip: 2
limit: 3
Babel Coder
Babel Coder
https://www.babelcoder.com
ORDER BY
desc เรียงลําดับจากค่ามากไปหาค่าน้อย
asc เรียงลําดับจากค่าน้อยไปหาค่ามาก
Babel Coder
Babel Coder
https://www.babelcoder.com
INCLUDE
Babel Coder
Babel Coder
https://www.babelcoder.com
INCLUDE
Babel Coder
Babel Coder
https://www.babelcoder.com
NESTED INCLUDE
Babel Coder
Babel Coder
https://www.babelcoder.com
NESTED INCLUDE
Babel Coder
Babel Coder
https://www.babelcoder.com
SELECT
Babel Coder
Babel Coder
https://www.babelcoder.com
SELECT
Babel Coder
Babel Coder
https://www.babelcoder.com
SELECT
Babel Coder
Babel Coder
https://www.babelcoder.com
SELECT
Babel Coder
Babel Coder
https://www.babelcoder.com
SELECT
select และ include จะไม่สามารถใช้งานในลําดับชันเดียวกันได้ กรณีทีต้องการเลือก fields และรวมผลลัพธ์จากความ
สัมพันธ์ด้วยสามารถใช้เพียงแค่ select อย่างเดียวได้
Babel Coder
Babel Coder
https://www.babelcoder.com
CREATE
Babel Coder
Babel Coder
https://www.babelcoder.com
UPDATE
กรณีทีระบุค่าเปน undefined มีผลทําให้ค่าของฟลด์นัน
ในฐานข้อมูลไม่เปลียนแปลง
Babel Coder
Babel Coder
https://www.babelcoder.com
UPSERT
upsert เปนคําสังทีรวมผลของ update และ insert ไว้
ด้วยกัน โดยใช้ส่วนของ where ในการค้นหาข้อมูลก่อน
หากข้อมูลจะทําการอัพเดท Record ด้วยส่วนของฟลด์
จาก update กรณีทีหา Record ไม่พบจะใช้ส่วนของ
ฟลด์ใน create เพือสร้าง Record ใหม่ต่อไป
Babel Coder
Babel Coder
https://www.babelcoder.com
DELETE
delete ใช้ในกรณีทีต้องการลบข้อมูลเดียว กรณีที
ต้องการลบข้อมูลหลายตัวให้ใช้ deleteMany แทน
Babel Coder
Babel Coder
https://www.babelcoder.com
PAGINATION
page = 3
limit = 5
skip: 10
take: 5
Babel Coder
Babel Coder
https://www.babelcoder.com
ERROR MESSAGE
กรณีที Query ทําให้เกิดข้อผิดพลาดประเภททีคาดเดาได้ เช่น Record ทีค้นหาไม่มีอยู่จริง Prisma จะทําการคืนข้อผิด
พลาดเปน PrismaClientKnownRequestError
PrismaClientKnownRequestError ประกอบด้วย Property ต่าง ๆ ได้แก่
code เปนรหัสทีใช้จําแนกข้อผิดพลาด
meta ประกอบด้วยข้อมูลเพิมเติมเพือขยายความข้อผิดพลาดนัน ๆ
message คือข้อความทีสัมพันธ์กับข้อผิดพลาดนัน ๆ
clientVersion คือเลขระบุเวอร์ชันของ Prisma Client
Babel Coder
Babel Coder
https://www.babelcoder.com
ERROR CODE
ต่อไปนีเปนตัวอย่างของ error code ทีสําคัญ
P2002 เปนข้อผิดพลาดจาก Unique constraint เช่น ตาราง User ไม่อนุญาตให้อีเมล์ซํากัน แต่คําสังนันทําให้
เกิดอีเมล์ทีซํากันได้ ข้อมูลของ field ทีผิดพลาดนันจะอยู่ภายใน e.meta.target เมือ e คือข้อผิดพลาดนัน
P2025 เปนข้อผิดพลาดเมือร้องขอข้อมูลจาก Record ทีไม่มีอยู่จริง
AUTHENTICATION
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
AUTHENTICATION
Authentication คือกระบวนการทีว่าด้วยการยืนยันตัวตนให้ระบบทราบว่าผู้ใช้งานปจจุบันคือใคร ประกอบด้วยกระบวนการลง
ทะเบียนผู้ใช้งาน (Register) การเข้าสู่ระบบ (Login) การร้องขอโทเคนใหม่ (Refresh Token) การอัพเดทและเข้าถึงข้อมูลส่วน
บุคคล (Profile) และการออกจากระบบ (Logout)
POST /auth/register
POST /auth/login
POST /auth/refresh-token
GET /auth/profile
PATCH /auth/profile
DELETE /auth/logout
การสมัครสมาชิก
การเข้าสู่ระบบ
การร้องขอโทเคนใหม่
การเข้าถึงโปรไฟล์
การอัพเดทโปรไฟล์
การออกจากระบบ
email
User
password
refreshToken
Babel Coder
Babel Coder
https://www.babelcoder.com
passport-local
PASSPORT
Passport.js เปน Middleware สําหรับแอปพลิเคชันทีพัฒนาบน Express.js เพือใช้สําหรับงานด้าน Authentication เปนหลัก
สามารถใช้ควบคู่กับการเข้าสู่ระบบด้วย username และ password หรือการเข้าสู่ระบบด้วย Social และ OAuth2 เช่น
Facebook Twitter (X) Google และอืน ๆ
passport-jwt
ใช้กับการเข้าสู่ระบบด้วย username (email)
และ password
ใช้กับการยืนยันตัวตนผ่านโทเค็นประเภท
JSON Web Token (JWT)
Babel Coder
Babel Coder
https://www.babelcoder.com
REGISTER
POST /auth/register
{
"name": "Admin",
"email": "admin@babelcoder.com",
"password": "passw0rd"
}
passport local
email
User
refreshToken
password
email
bcrypt.hash(password, 12)
ใช้สําหรับการลงทะเบียนเพือดึง email
และ password ออกจาก Payload
เข้ารหัส password โดยใช้ bcrypt
AuthGuard
auth service
Babel Coder
Babel Coder
https://www.babelcoder.com
REGISTER
$ pnpm add bcrypt passport-local @nestjs/passport
$ pnpm add -D @types/passport-local
ส่ง payload ไปเปนค่าแรกใน validate
{
"name": "Admin",
"email": "admin@babelcoder.com",
"password": "passw0rd"
}
Babel Coder
Babel Coder
https://www.babelcoder.com
REGISTER
ทําการเรียกใช้ RegisterStrategy โดยอัตโนมัติ
CurrentUser เปน Decorator ใหม่ทีเราสร้างขึน
มาเพือใช้ในการดึงค่า user ใหม่ทีได้จากการลง
ทะเบียนเสร็จสินแล้วออกมา
Babel Coder
Babel Coder
https://www.babelcoder.com
REGISTER
เมือ passport-local ทํางานเสร็จสิน จะทําการนํา
user ใหม่บรรจุลง req.user
สําหรับ CurrentUser จึงเปนการดึงค่า user ออก
จาก req.user นันเอง
Babel Coder
Babel Coder
https://www.babelcoder.com
passport local
email
1
LOGIN
POST /auth/login
{
"email": "admin@babelcoder.com",
"password": "passw0rd"
}
User
refreshToken
password
email
bcrypt.compare(password, user.password)
ใช้สําหรับการเข้าสู่ระบบเพือดึง email
และ password ออกจาก Payload
เปรียบเทียบรหัสผ่านทีส่งเข้ามา
กับรหัสผ่านของผู้ใช้งานในระบบ
AuthGuard
ค้นหาผู้ใช้งานจากฐานข้อมูลทีมีอีเมล์
ตรงกับทีส่งเข้ามาใน payload
2
3 จัดเก็บ refreshToken
Babel Coder
Babel Coder
https://www.babelcoder.com
{
"profile": {
"id": 1,
"email": "admin@babelcoder.com",
}
"accessToken": "xxx",
"refreshToken": "yyy",
"expiresIn": 1719238180092,
}
401 email
LOGIN
POST /auth/login
User
refreshToken
password
โทเค็นทังสองสร้างขึนด้วยรูปแบบของ JSON Web
Token (JWT) เพือใช้เปนตัวแทนของผู้ใช้งาน
accessToken เปนโทเค็นทีมีอายุสัน ใช้ส่งทุกครังที
ติดต่อกับ API เพือให้ API ทราบว่าผู้ใช้งานคือใคร
refreshToken เปนโทเค็นทีมีอายุยาว กรณีที accessToken
หมดอายุจะใช้ refreshToken ส่งกลับมายัง API เพือร้องขอให้
API สร้างและส่งคืน accessToken มาใหม่ เปนการปองกันไม่ให้
ผู้ใช้งานต้องเข้าสู่ระบบใหม่ทุกครังที accessToken หมดอายุ
UNAUTHORIZED
201 CREATED Login สําเร็จ
email หรือ password ผิด
Babel Coder
Babel Coder
https://www.babelcoder.com
JWT
JWT เปนโทเค็นทีมีการ Encode ประเภทหนึงทีใช้สือสารระหว่างสองระบบในรูปแบบของ client / server เพือส่งข้อมูลอย่าง
ปลอดภัยโดยปองกันการแก้ไขจากบุคคลภายนอกแต่ไม่ได้ปองกันการอ่านข้อมูลที Encode ไว้ JWT จึงไม่ควรบันทึกข้อมูลทีเปนความ
ลับไว้ในส่วนของ Payload
Header Payload Signature
จัดเก็บชนิดของโทเค็นคือ JWT และ algorithm ใน
การสร้าง Signature
จัดเก็บ claims คือข้อมูลต่าง ๆ ทีต้องการบรรจุในโท
เค็น เช่น Role หรือ User ID โดยมี claims ทีนิยามไว้
สําหรับสถานการณ์บางอย่างไว้แล้ว เช่น ใช้ sub
สําหรับการจัดเก็บ User ID เปนต้น
เปนส่วนลายเซ็นต์ของโทเค็น ใช้เพือยืนยันว่าโทเค็นดัง
กล่าวมิได้ถูกปลอมแปลงโดยอาศัยกุญแจ (Secret
Key) ทางฝงเซิฟเวอร์เปนตัวยืนยัน
Babel Coder
Babel Coder
https://www.babelcoder.com
JWT
Babel Coder
Babel Coder
https://www.babelcoder.com
Access Token
sub
JWT
Header Payload Signature
role
image
ข้อมูล User ID ใช้เพือระบุตัวตนผู้ใช้งาน
ใช้เพือการตรวจสอบสิทธิว่า Role นีมีสิทธิเข้าถึงสิงที
ร้องขอหรือไม่
ใช้เพือนํารูปภาพไปแสดงผลบน Client (ไม่จําเปนต้อง
มี)
$ pnpm add @nestjs/jwt
Babel Coder
Babel Coder
https://www.babelcoder.com
JWT
5m
Babel Coder
Babel Coder
https://www.babelcoder.com
PASSPORT JWT
$ pnpm add passport-jwt
$ pnpm add -D @types/passport-jwt
Authorization Bearer xxxxxxxxx
Headers
sub
role
Babel Coder
Babel Coder
https://www.babelcoder.com
ACCESS TOKEN GUARD
id
role
Babel Coder
Babel Coder
https://www.babelcoder.com
REFRESH TOKEN
POST /auth/refresh-token
{
"refreshToken": "yyyyyyy"
}
ค่าที return จะกําหนดให้กับ req.user
Babel Coder
Babel Coder
https://www.babelcoder.com
REFRESH TOKEN GUARD
ดึงค่าออกจาก req.user
Babel Coder
Babel Coder
https://www.babelcoder.com
Headers
LOGOUT
email
DELETE /auth/logout
User
refreshToken
password
Authorization Bearer xxxxxxxxx
Logout เปนกระบวนการทีจะทําการลบ refresh token ของผู้ใช้งานนันออกจากฐานข้อมูล นันทําให้เมือ access token หมดอายุ
จะไม่สามารถใช้ refresh token ทีมีอยู่เดิมเพือขอ access token ใหม่ได้
AUTHORIZATION
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
Headers
Headers
order.userId = sub
role = Admin
RolesGuard
OrdersController
Role-Based Access Control (RBAC)
AUTHORIZATION
Authorization เปนกระบวนการตรวจสอบสิทธิว่าผู้เข้าใช้งานระบบมีสิทธิเข้าถึงทรัพยากรทีร้องขออยู่ขณะนันหรือไม่
Authorization จะเปนกระบวนการทีเกิดขึนหลัง Authentication เสมอ กรณีทีไม่มีสิทธิเข้าถึง ระบบจะคืนค่า HTTP Status
Code เปน 403 FORBIDDEN
Authorization Bearer xxxxxxxxx
Authorization Bearer xxxxxxxxx
False
403 FORBIDDEN
False
403 FORBIDDEN
DELETE /products/1
GET /orders/1
Attribute-Based Access Control (ABAC)
Babel Coder
Babel Coder
https://www.babelcoder.com
ROLES DECORATOR
Roles ใช้เปนตัวกําหนดว่า Handler ตัวนัน ๆ จะสามารถทํางานได้เมือผู้ใช้
งานมี Role เปนอะไร Roles ด้วยตัวของมันเองนันไม่สามารถทํางานได้ เปน
เพียงแค่การตังค่า Metadata เพือให้โค้ดส่วนอืน เช่น Guard มาอ่านค่า
อีกทีนึง
Babel Coder
Babel Coder
https://www.babelcoder.com
ROLES DECORATOR
Babel Coder
Babel Coder
https://www.babelcoder.com
ROLES GUARD
ใช้ Roles เปนตัวกําหนดว่าใครมีสิทธิบ้าง แล้วจึงใช้
RolesGuard ในการอ่านค่า Roles ทีตังค่าไว้เพือพิจารณา
ว่าผู้ใช้งานมีสิทธิเข้าถึงทรัพยากรนันหรือไม่
Babel Coder
Babel Coder
https://www.babelcoder.com
AUTH GUARD
การใช้ Roles ควบคู่กับ RolesGuard นันอาจไม่สะดวก เนืองจากต้องใช้สองคําสังเพือให้ได้ผลลัพธ์ในการ
ตรวจสอบสิทธิ เราจึงทําการสร้าง AuthGuard เพือให้คําสังนันสันลง
Babel Coder
Babel Coder
https://www.babelcoder.com
AUTH GUARD
Babel Coder
Babel Coder
https://www.babelcoder.com
ABAC
CACHING
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
1
CACHING HTTP RESPONSE
การแคชค่าผลลัพธ์จาก API เปนหนึงเทคนิคทีช่วยให้ API มีประสิทธิภาพมากขึน นันเปนเพราะแทนที API จะต้องประมวลผลใหม่
ทังหมดทุกครังทีมีการร้องขอข้อมูล เมือมีการทําแคชเราสามารถคืนผลลัพธ์เก่าทีเคยทํางานสําเร็จแล้วกลับไปยังผู้เรียกใช้งานได้
ในทีนีเราจะทําการแคชค่าข้อมูลโดยจัดเก็บผลลัพธ์ไว้ใน Redis ซึงเปนฐานข้อมูลประเภท In-memory Database ทีมีการ
ทํางานอย่างรวดเร็วและจัดเก็บข้อมูลในลักษณะ Key / Value
2
3
4
5
6
GET /categories
บันทึกผลลัพธ์ในแคช
คืนผลลัพธ์กลับ
GET /categories
คืนผลลัพธ์จากแคชโดยไม่ทํางาน
ใหม่ใน Controller
คืนผลลัพธ์กลับจากแคช
Babel Coder
Babel Coder
https://www.babelcoder.com
CACHING HTTP RESPONSE
Babel Coder
Babel Coder
https://www.babelcoder.com
CACHE MANAGER
$ pnpm add @nestjs/cache-manager cache-manager cache-manager-redis-yet redis
ดําเนินการติดตังแพคเกจต่าง ๆ สําหรับการแคช ดังนี
สําหรับใช้งาน cache-manager กับ
Nest.js
ตัวจัดการแคช
ตัวจัดการแคชบน Redis
สําหรับการเชือมต่อการทํางานไปยัง Redis
Babel Coder
Babel Coder
https://www.babelcoder.com
CACHE MODULE
ทําการตังค่าการแคชผ่าน CacheModule ใน CoreModule เพือให้สามารถใช้งานระบบแคช
ได้ในทุก ๆ Module โดยไม่ต้อง import ทังนีให้ทําการระบุใน CacheModule ว่าจัดเก็บข้อมูล
แคชใน redis ผ่านการติดตัง store ด้วย redisStore
กําหนดค่า REDIS_HOST และ REDIS_PORT เพือเชือมต่อไปยัง Redis ผ่าน .env
Babel Coder
Babel Coder
https://www.babelcoder.com
AUTO-CACHING RESPONSES
Nest.js มาพร้อมกับ CacheInterceptor ทีทําให้เราสามารถแคชผลลัพธ์ของทุก GET methods ในคลาสได้ โดย
CacheInterceptor จะกําหนดค่า key ของแคชเปน Path ของ request ทีวิงเข้าสู่ method นัน ๆ
ค่าของ key คือ /categories
ค่าของ key คือ /categories/1 กรณีที request เปน /categories/1
Babel Coder
Babel Coder
https://www.babelcoder.com
CACHE STORE
แม้ว่า CacheInterceptor จะดําเนินการแคชผลลัพธ์ให้ แต่
ในขันตอนของการลบค่า cache จําเปนต้องจัดการด้วยตนเอง
เช่น เมือมีการสร้าง Category ใหม่จําเปนทีจะต้องลบผลลัพธ์
การแคชจาก key คือ /categories ทิง เพือให้ request ถัด
ไปประมวลผลข้อมูลใหม่จึงได้รายการ Category คืนกลับเปน
ค่าปจจุบัน
LOGGING
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
WINSTON
การแสดงผล Log เปนสิงหนึงทีมีความสําคัญทําให้เราทราบถึงกระบวนการทํางานของโปรแกรมไม่ว่าการทํางานนันจะเปนไปเพือ
การ debug หรือการแสดงผลข้อผิดพลาดของระบบก็ตาม
Nest.js มาพร้อมกับ built-in logger อย่างไรก็ตามหากเราต้องการฟงก์ชันการทํางานทีซับซ้อนมากขึนเราจําเปนต้องใช้งาน
แพคเกจในการจัดการ Log อย่างอืน เช่น Winston
เพือให้เราสามารถใช้งาน Winston ควบคู่กับ Nest ได้จําเปนต้องดําเนินการติดตังแพคเกจ ดังนี
$ pnpm add winston nest-winston
Babel Coder
Babel Coder
https://www.babelcoder.com
WINSTON
ในการใช้งานระบบ Log ของ Winston นันเราสามารถสังให้ Winston แสดง Log ทีระดับใดก็ได้ กรณีทีไม่มีการระบุค่าเริมต้น
จะเปน info การระบุการแสดงผล Log ทีระดับใด จะทําให้ Log ทีปล่อยออกมาในระดับนันรวมถึงระดับทีตํากว่าถูกแสดงผล เช่น
เมือเลือกแสดงผลระดับ info จะทําให้ข้อความจาก Log ระดับ info, warn และ error ได้รับการแสดงผลนันเอง
ต่อไปนีเปนการตังค่าการทํางานของ Winston บนไฟล์ main.ts การทํางานดังกล่าวประกอบด้วยเงือนไขดังนี
หากมี LOG_LEVEL ใน env จะใช้ค่านัน กรณีไม่กําหนดจะเปน info
1.
ฟอร์แมตของ Log อยู่ในรูปแบบ JSON
2.
เมือ NODE_ENV เปน production จะแสดงผล Log โดยการเขียนลงไฟล์ชือ server.log หากไม่ใช่จะทังเขียนลงไฟล์
และแสดงผลออก Console ด้วยรูปแบบการฟอร์แมตเช่นเดียวกับ Nest
3.
เราจะแปะ service: 'api' เพิมลงไปในทุก Log เพือให้ทราบว่าเปน Log ทีมาจาก api
4.
Babel Coder
Babel Coder
https://www.babelcoder.com
WINSTON
1
2
3
4
การทํางานบนระบบ Log ของเรานันบนโค้ดของแอปพลิเคชันเราจะใช้ API ของ Logger บน Nest.js เปนหลัก แต่เบืองหลังการ
ทํางานทีแท้จริงนันจะไปเรียกใช้งาน Winston อีกที เหตุเพราะ Log Level ของ Nest.js นันมีน้อยกว่าของ Winston กล่าวคือมี
เพียงแค่ 'log', 'fatal', 'error', 'warn', 'debug', และ 'verbose' เราจึงต้องใช้ Level ของ Log ต่าง ๆ เหล่านีแทน โดย Log
Level ประเภท log ของ Nest.js มีค่าเทียบเท่ากับ info บน Winston
Babel Coder
Babel Coder
https://www.babelcoder.com
LOGGER MIDDLEWARE
เพือให้ทุก Request มีการ Log ข้อมูลของ
การร้องขอผ่าน Winston เราจะทําการสร้าง
LoggerMiddleware ผ่านไฟล์
src/logger.middleware.ts ดังนี
Babel Coder
Babel Coder
https://www.babelcoder.com
LOGGER MIDDLEWARE
การจะให้ LoggerMiddleware ทํางานได้นัน เราต้องทําการ
เรียกใช้งานผ่าน configure ของ AppModule ดังนี
info: GET /products?page=2 200 {"context":"HTTP","service":"api"}
STDOUT
{"context":"HTTP","level":"info","message":"GET /products?page=2
200","service":"api"}
server.log
Babel Coder
Babel Coder
https://www.babelcoder.com
LOGGER MIDDLEWARE
การจะให้ LoggerMiddleware ทํางานได้นัน เราต้องทําการ
เรียกใช้งานผ่าน configure ของ AppModule ดังนี
Babel Coder
Babel Coder
https://www.babelcoder.com
APPLICATION LOGGING
เพือให้ Logger ของ Nest สามารถนําไปใช้งานในส่วนประกอบต่าง ๆ ของแอปพลิเคชันได้ เราจําเปนต้องระบุ
Logger ใน CoreModule
Babel Coder
Babel Coder
https://www.babelcoder.com
APPLICATION LOGGING
เราสามารถ inject Logger เพือเรียกใช้งานระบบ Log ผ่าน Log Level ต่าง ๆ ของ Nest.js
ความที Log ดังกล่าวเปน Log ประเภท debug เราจึงต้อง
ทําการเปลียน LOG_LEVEL ใน .env ดังนี
LOG_LEVEL=debug
.env
SWAGGER
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
OPENAPI
OpenAPI เปนข้อกําหนดทางเทคนิค (Specification) ของรูปแบบทีไม่อิงภาษาโปรแกรมใช้เพืออธิบายรูปแบบการเรียกใช้
งาน RESTful API โดยมี Swagger เปนเครืองมือสําหรับการนําข้อกําหนด (Specification) ไปใช้ โดยหนึงในเครืองมือ
สําคัญของ Swagger คือ Swagger UI ทีเปนเครืองมือสําหรับการสร้างเอกสารการใช้งาน RESTful API ทีมีการแสดงผลบน
เว็บเบราว์เซอร์ทําให้เราสามารถทดลองการทดสอบ API ได้จากตัว Swagger UI โดยตรง
Nest.js ได้เตรียมโมดูลสําหรับการใช้งานคู่กับ Swagger ผ่านทาง Decorators ต่าง ๆ โดยเราต้องทําการติดตังโมดูลดัง
กล่าวผ่านทางแพคเกจดังนี
$ pnpm add -D @nestjs/swagger
Babel Coder
Babel Coder
https://www.babelcoder.com
SWAGGER UI
ทําการตังค่าการใช้งาน Swagger ใน main.ts ดังนี
Babel Coder
Babel Coder
https://www.babelcoder.com
CLI PLUGIN
ลําดับถัดไปเราจะทําการตังค่า CLI Plugin ให้ทําการอ่านไฟล์นามสกุล .dto.ts แล้วสร้างข้อมูลบน Swagger UI ตามทีปรากฎ
ในไฟล์โดยทําการแก้ไขไฟล์ nest-cli.json ดังนี
Babel Coder
Babel Coder
https://www.babelcoder.com
CLI PLUGIN
แม้ส่วนใหญ่ CLI Plugin จะช่วยให้ Swagger UI แสดงผลชนิดข้อมูลของ Request / Response ได้ แต่มีหลายส่วนของ
API ทีข้อมูลส่วนนียังคงไม่ถูกต้อง ด้วยเหตุนีเราจึงต้องทําการเพิมส่วนของโค้ดเพือให้การแสดงผล Swagger เปนไปอย่าง
สมบูรณ์
ต้องเปน multipart/form-data
ชนิดข้อมูลของ Category ใน Response ไม่ถูกต้อง
Babel Coder
Babel Coder
https://www.babelcoder.com
SWAGGER UI PROBLEMS
แม้ส่วนใหญ่ CLI Plugin จะช่วยให้ Swagger UI แสดงผลชนิดข้อมูลของ Request / Response ได้ แต่มีหลายส่วนของ
API ทีข้อมูลส่วนนียังคงไม่ถูกต้อง ด้วยเหตุนีเราจึงต้องทําการเพิมส่วนของโค้ดเพือให้การแสดงผล Swagger เปนไปอย่าง
สมบูรณ์
ต้องเปน multipart/form-data
ชนิดข้อมูลของ Category ใน Response ไม่ถูกต้อง
API นีไม่ได้มีการระบุว่าต้องมี Bearer Token ในการใช้งาน
API ไม่แสดงส่วนของ file upload
Babel Coder
Babel Coder
https://www.babelcoder.com
@APIBEARERAUTH
ใช้ @ApiBearerAuth เพือเพิมส่วนสําหรับการลอคอินด้วย Bearer Token
Babel Coder
Babel Coder
https://www.babelcoder.com
@APIBEARERAUTH
ใช้ @ApiConsumes เพือบอกว่าส่วนของ Request Body ต้องส่งข้อมูลเปน multipart/form-data
Babel Coder
Babel Coder
https://www.babelcoder.com
@APIPROPERTY
เมือโครงสร้างของสิงทีคืนกลับซ้อนอยู่ในอาร์เรย์ CLI Plugin อาจตีความไม่ถูกต้อง เราสามารถกํากับชนิดข้อมูลทีถูกต้องให้กับ
Dto ได้ ดังนี
Babel Coder
Babel Coder
https://www.babelcoder.com
@APIBODY
การแสดงผล file upload นันจําเปนต้องใช้ @ApiBody โดย
@ApiBody จําเปนต้องระบุ fields ต่าง ๆ ของ Request ให้
ครบถ้วนเพือให้เกิดการแสดงผลอย่างถูกต้อง
Babel Coder
Babel Coder
https://www.babelcoder.com
@APIBODY
เนืองจากการใช้ @ApiBody ต้องระบุส่วนของ fields ต่าง ๆ ทีเปน Request Body ให้ครบ เราจึงต้องกําหนดชือของ fields ต่าง ๆ
รวมถึง categoryIds ด้วย อย่างไรก็ตามการส่ง categoryIds จากฝงของ Swagger UI จะส่งค่าข้อมูลเปน categoryIds='1,2' เมือ
1 และ 2 คือ id ทีเลือก การส่งค่ามาเช่นนีย่อมผิดพลาดเพราะการส่งข้อมูลทีถูกต้องแท้จริงแล้วต้องเปนอาร์เรย์คือ categoryIds=[1,2]
ด้วยเหตุนีเราจึงต้องทําการแก้ไขส่วนของ CreateProductDto เพืออนุญาตให้รับ categoryIds ในรูปแบบ string ได้
TASK SCHEDULING
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
SCHEDULING
บางสถานการณ์มีความจําเปนทีจะต้องทํางานบางอย่างในทุกช่วงเวลาทีกําหนด เช่น ทุกวันอาทิตย์ให้ทําการ Backup
Database เปนต้น สถานการณ์เช่นทีว่านีสามารถดําเนินการผ่านสิงทีเรียกว่า Task Scheculing บน Nest.js ได้
Task Scheculing คือความสามารถในการกําหนดช่วงของเวลาไม่ว่าจะเปนการกําหนดเวลาตายตัว หรือกําหนดเวลาเปนช่วง
เวลาวนซํา เพือดําเนินงานบางอย่างเมือเวลาทีกําหนดมาถึง สําหรับ Nest.js การดําเนินงานผ่าน Task Scheduling จําเปน
ต้องติดตังแพคเกจ ดังนี
$ pnpm add @nestjs/schedule
Babel Coder
Babel Coder
https://www.babelcoder.com
SCHEDULE MODULE
จากนันจึงทําการเพิม ScheduleModule ใน AppModule ดังนี
Babel Coder
Babel Coder
https://www.babelcoder.com
CRON JOBS
การใช้งาน Task Scheduling ในรูปแบบแรกคือ Cron Jobs ทีมีรูปแบบการกําหนดวันเวลาในลักษณะของ Patterns ดังนี
* * * * * *: ทุกวินาที
30 * * * * *: ในแต่ละนาทีจะทํางานเมือครบ 30 วินาที
0 30 * * * *: ทุก ๆ ชัวโมงจะทํางานเมือถึงนาทีที 30
0 */30 * * * *: ส่วนของ Steps */30 ทําให้รูปแบบนีหมายถึง.
ทุก 30 นาที
0 30 11 * * 1-5: วันจันทร์ถึงศุกร์เวลา 11.30 น.
0 0 22 * * 1-5: วันจันทร์ถึงศุกร์เวลา 22.00 น.
23 0-20/2 * * *: ทุก ๆ 2 ชม. จากชัวโมงที 0 - 20 หลังจากที
ทํางานไปแล้ว 23 นาที (ละเว้น seconds)
0 0 4 8-14 * *: ทุก ๆ 4.00 น. ของวันที 8 - 14
Babel Coder
Babel Coder
https://www.babelcoder.com
CRON JOBS
ต่อไปนีจะทําการเพิมโค้ดเพือให้พิมพ์ค่า hello cron jobs ทุก 5 วินาทีออกทาง log
Babel Coder
Babel Coder
https://www.babelcoder.com
CRON JOBS
นอกเหนือจากนี CronExpression ยังมีการจัดเตรียมค่า
คงทีสําหรับรูปแบบ Cron ทีใช้บ่อย เช่น
CronExpression.EVERY_30_SECONDS:
สําหรับการทํางานทุก 30 วินาที
CronExpression.EVERY_2_HOURS: สําหรับการ
ทํางานทุก 2 ชัวโมง
CronExpression.EVERY_DAY_AT_10AM:
10.00 น. ของทุกวัน
Babel Coder
Babel Coder
https://www.babelcoder.com
INTERVAL
Nest.js ได้เตรียม @Interval ไว้เพือเรียก
ทํางานทุกจํานวนมิลลิวินาทีทีกําหนด ต่อไปนีเปน
ตัวอย่างการใช้งาน @Interval ทีจะพิมพ์ค่า
hello interval ผ่าน log ทุก 10 วินาที
Babel Coder
Babel Coder
https://www.babelcoder.com
TIMEOUT
@Timeout เปน Decorator ทีใช้งานเพือระบุ
เวลาเปนหน่วยมิลลิวินาที เมือถึงเวลาดังกล่าวจะ
ทํางานเพียงครังเดียว ต่อไปนีเปนตัวอย่างผลลัพธ์
ทีจะพิมพ์ hello timeout เมือครบ 2 วินาที
TESTING
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
JEST
Jest คือ Testing Framework บนภาษา JavaScript ทีสนับสนุนรูปแบบการทดสอบทีหลาก
หลาย เช่น Snapshot Testing มาพร้อมฟเจอร์ต่าง ๆ เช่น Expect และ Matchers รวมถึงการ
ทํางานกับ Mock Functions รวมถึงการทํา Code Coverage และอืน ๆ
การทดสอบ API แบบ Unit Testing บน Nest.js สามารถดําเนินการผ่านการติดตังแพคเกจดังนี
$ pnpm add -D @nestjs/testing jest-mock-extended
Babel Coder
Babel Coder
https://www.babelcoder.com
categories.service.spec.ts
TEST CASE AND GROUP
Group
Test Case
Test Steps
src
categories
categories.service.ts
categories.service.spec.ts
Babel Coder
Babel Coder
https://www.babelcoder.com
MATCHERS
ในการทดสอบโปรแกรมย่อมมีสิงทีคาดหวัง (expect) ว่าผลลัพธ์ควรเปนเช่นไร การตรวจสอบ
ความถูกต้องของข้อมูลนีเราอาศัยสิงทีเรียกว่า Matchers บน Jest โดยใช้รูปแบบคือ
ตัวอย่าง เช่น
Babel Coder
Babel Coder
https://www.babelcoder.com
SETUP AND TEARDOWN
ในการทดสอบโปรแกรมทีมีหลาย Examples ย่อมเปนธรรมดาทีจะมีส่วนการทํางานซํากัน เช่น ก่อนการทดสอบโปรแกรมใด ๆ
จําเปนจะต้องลบค่าเก่าจากฐานข้อมูลก่อนเสมอ หากเราเขียนวิธีลบค่าดังกล่าวในทุก ๆ Examples ย่อมทําให้เกิดโค้ดซํา ยาก
ต่อการจัดระเบียบโค้ด
Jest มีฟงก์ชันทีใช้ในการแก้ปญหานีอยู่ 4 ฟงก์ชัน คือ beforeEach beforeAll afterEach และ afterAll โดยมีราย
ละเอียดการใช้งาน ดังนี
beforeAll: เปนฟงก์ชันทีจะถูกเรียกทํางานเพียงครังเดียว ก่อน Examples ทังหมดใน Suite เดียวกันจะทํางาน
beforeEach: เปนฟงก์ชันทีจะถูกเรียกทํางานก่อนทีแต่ละ Examples ใน Suite จะทํางาน
afterAll: เปนฟงก์ชันทีจะถูกเรียกทํางานเพียงครังเดียว หลัง Examples ทังหมดใน Suite ทํางานเสร็จสิน
afterEach: เปนฟงก์ชันทีจะถูกเรียกทํางานหลัง Examples แต่ละตัวใน Suite ทํางานเสร็จ
Babel Coder
Babel Coder
https://www.babelcoder.com
SETUP AND TEARDOWN
Babel Coder
Babel Coder
https://www.babelcoder.com
SETTING
การตังค่าของ Jest สําหรับการทํา Unit Testing
จะอยู่ในไฟล์ package.json
Babel Coder
Babel Coder
https://www.babelcoder.com
MODULE NAME MAPPER
โค้ดของโปรแกรมอาจมีการอ้างอิงถึงไฟล์ผ่าน Path
Alias การตังค่า moduleNameMapper จะช่วย
ทําให้ Jest รู้จักกับไฟล์ทีอ้างอิงถึงแบบ Path Alias
ได้
Babel Coder
Babel Coder
https://www.babelcoder.com
ISOLATED TESTING
โดยพืนฐานแล้ว การทดสอบแบบ Unit Testing
บน Nest.js เราสามารถสร้าง instance ของ
คลาสแล้วทําการผูกความสัมพันธ์ด้วยการส่งผ่าน
instance ทีต้องการใช้งานผ่าน constructor
เพือสร้างคลาสทีสมบูรณ์สําหรับการทดสอบ
โปรแกรมได้ เรียกวิธีการนีว่า Isolated Testing
Babel Coder
Babel Coder
https://www.babelcoder.com
MOCKING
ใช้ jest.spyOn เพือทดสอบการถูกเรียกใช้งาน
พร้อมทังสามารถเตรียมข้อมูลแทนทีเมธอดของอ
อบเจ็กต์ใด ๆ ได้
Babel Coder
Babel Coder
https://www.babelcoder.com
TESTING MODULE
Test.createTestingModule ใช้เพือจัดเตรียม Module สําหรับกระทํา Unit Testing โดยเราสามารถเรียกใช้ get เพือเข้าถึงค่า
instance ทีสนใจภายใต้ module นันได้
Babel Coder
Babel Coder
https://www.babelcoder.com
MOCKING PRISMA CLIENT
ในการทดสอบแบบ Unit Testing เราจะไม่ทําการเชือมต่อกับฐานข้อมูลโดยตรง เมือเปนเช่นนีเราต้องทําการ Mock ส่วนของ Prisma
Client เพือไม่ให้มีการติดต่อไปยังฐานข้อมูลจริง ขันตอนของการ Mock Prisma Client ประกอบด้วย
ใช้ overrideProvider เพือบอก TestingModule ว่าให้ใช้ค่าต่อไปนีแทน PrismaService
กําหนดค่าที Mock ผ่าน useValue
Mock PrismaClient ผ่าน mockDeep เปนผลให้ทุกเมธอดของ PrismaClient สามารถถูกแทนทีด้วยข้อมูลทีอยากให้คืน
กลับได้
Babel Coder
Babel Coder
https://www.babelcoder.com
MOCKING PRISMA CLIENT
Babel Coder
Babel Coder
https://www.babelcoder.com
SERVICES TESTING
categories.service.ts
Babel Coder
Babel Coder
https://www.babelcoder.com
SERVICES TESTING
categories.service.spec.ts
Babel Coder
Babel Coder
https://www.babelcoder.com
CONTROLLERS TESTING
categories.controller.ts
Babel Coder
Babel Coder
https://www.babelcoder.com
CONTROLLERS TESTING
categories.controller.spec.ts
Babel Coder
Babel Coder
https://www.babelcoder.com
categories.controller.spec.ts
CONTROLLERS TESTING
Babel Coder
Babel Coder
https://www.babelcoder.com
CONTROLLERS TESTING
Babel Coder
Babel Coder
https://www.babelcoder.com
CONTROLLERS TESTING
Babel Coder
Babel Coder
https://www.babelcoder.com
E2E TESTING
End-to-End Testing (E2E Testing) เปนกระบวนการตรวจสอบทีเน้นการทํางานครบรอบของวงจรเสมือนผู้ใช้งาน
ได้เปนผู้ทดสอบด้วยตนเอง กระบวนการทดสอบเช่นทีว่านีจึงมีการเชือมต่อฐานข้อมูลพร้อมทังมีการร้องขอ API ตังแต่
ช่วงของการส่ง Request จนกระทังถึงการตรวจสอบผลลัพธ์การทํางาน
บทเรียนนีเราจะใช้ supertest สําหรับกระบวนการทดสอบแบบ E2E
$ pnpm add -D supertest
test
categories.e2e-spec.ts
jest-e2e.json
Babel Coder
Babel Coder
https://www.babelcoder.com
DOTENV
การทดสอบแบบ E2E จะต้องมีการตังค่า Config เหมือนกับการใช้งานจริง เมือเปนเช่นนีเราจึงต้องแยก .env ออกเปน
.env.development สําหรับการใช้งานบน Development และ .env.test สําหรับการทดสอบแบบ E2E ในทีนีเรา
จําเปนต้องแก้ไขการตังค่า ConfigModule ใน AppModule ดังนี
app
.env.development
.env.test
Babel Coder
Babel Coder
https://www.babelcoder.com
DOTENV
เพือให้ Prisma สามารถอ้างอิงถึงค่า DATABASE_URL ได้อย่างถูกต้อง เราจําเปนต้องติดตังแพคเกจ dotenv-cli
พร้อมใช้งานแพคเกจดังกล่าวเพืออ้างอิงถึงไฟล์ env ให้ถูกต้องใน Development
$ pnpm add -D dotenv
package.json
Babel Coder
Babel Coder
https://www.babelcoder.com
PREPARING
เราจําเปนต้องสร้างไฟล์ docker-compose.dev.yml สําหรับใช้งาน Redis และฐานข้อมูลเพือการทดสอบแบบ E2E
จากนันจึงสัง migrate บน Environment ดังกล่าว
$ docker compose -f ./docker-compose.e2e.yml up
$ npx dotenv -e .env.test prisma migrate deploy
docker-compose.e2e.yml
Babel Coder
Babel Coder
https://www.babelcoder.com
E2E
การทดสอบแบบ E2E สิงสําคัญคือต้องมีการลบข้อมูลจากฐานข้อมูลก่อนเริมต้นการทดสอบ
Babel Coder
Babel Coder
https://www.babelcoder.com
E2E
DEPLOYMENT
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
CORS
โดยทัวไปหากเว็บเบราว์เวอร์อยู่คนละโดเมนกับ API เว็บเบราว์เซอร์จะไม่สามารถร้องขอข้อมูลจาก API ได้
เนืองจากติดหลักการความปลอดภัยของเว็บเบราว์เซอร์ทีเรียกว่า Cross Origin Resource Sharing หรือ CORS เพือให้
เว็บเบราว์เซอร์สามารถร้องขอข้อมูลจาก API ของเราทีอยู่ต่างโดเมนได้ เราจะต้องตังค่า CORS
Babel Coder
Babel Coder
https://www.babelcoder.com
1
DEPLOYMENT
2
$ npx prisma migrate deploy
development production
name
User
age
gender
name
User
age
$ pnpm build
dist
src
main.js
package.json
pnpm-lock.yaml
ทําการคัดลอกมา
3
$ pnpm install
$ node ./dist/src/main.js

More Related Content

Similar to Nest.js RESTful API development.pdf Nest.js RESTful API development.pdf (7)

PDF
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
NuttavutThongjor1
 
PDF
4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf
NuttavutThongjor1
 
PDF
Modern DevOps Day 4.pdfModern DevOps Day 4.pdf
NuttavutThongjor1
 
PDF
GraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdf
NuttavutThongjor1
 
PDF
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
NuttavutThongjor1
 
PDF
Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...
NuttavutThongjor1
 
PDF
Kafka for developer
Bhuridech Sudsee
 
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
NuttavutThongjor1
 
4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf
NuttavutThongjor1
 
Modern DevOps Day 4.pdfModern DevOps Day 4.pdf
NuttavutThongjor1
 
GraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdf
NuttavutThongjor1
 
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
NuttavutThongjor1
 
Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...
NuttavutThongjor1
 
Kafka for developer
Bhuridech Sudsee
 

More from NuttavutThongjor1 (17)

PDF
Modern DevOps Day 3.pdfModern DevOps Day 3.pdf
NuttavutThongjor1
 
PDF
Modern DevOps Day 2.pdfModern DevOps Day 2.pdf
NuttavutThongjor1
 
PDF
misc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdf
NuttavutThongjor1
 
PDF
Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...
NuttavutThongjor1
 
PDF
10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf
NuttavutThongjor1
 
PDF
9 logging and monitoring.pdf 9 logging and monitoring.pdf
NuttavutThongjor1
 
PDF
8 iac.pdf 8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf
NuttavutThongjor1
 
PDF
7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf
NuttavutThongjor1
 
PDF
6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf
NuttavutThongjor1
 
PDF
5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf
NuttavutThongjor1
 
PDF
3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf
NuttavutThongjor1
 
PDF
2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf
NuttavutThongjor1
 
PDF
1 devops คืออะไร.pdf 1 devops คืออะไร.pdf
NuttavutThongjor1
 
PDF
angular fundamentals.pdf angular fundamentals.pdf
NuttavutThongjor1
 
PDF
mean stack mean stack mean stack mean stack
NuttavutThongjor1
 
PDF
pinia.pdf
NuttavutThongjor1
 
PDF
nuxt-rendering-modes.pdf
NuttavutThongjor1
 
Modern DevOps Day 3.pdfModern DevOps Day 3.pdf
NuttavutThongjor1
 
Modern DevOps Day 2.pdfModern DevOps Day 2.pdf
NuttavutThongjor1
 
misc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdf
NuttavutThongjor1
 
Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...
NuttavutThongjor1
 
10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf
NuttavutThongjor1
 
9 logging and monitoring.pdf 9 logging and monitoring.pdf
NuttavutThongjor1
 
8 iac.pdf 8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf
NuttavutThongjor1
 
7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf
NuttavutThongjor1
 
6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf
NuttavutThongjor1
 
5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf
NuttavutThongjor1
 
3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf
NuttavutThongjor1
 
2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf
NuttavutThongjor1
 
1 devops คืออะไร.pdf 1 devops คืออะไร.pdf
NuttavutThongjor1
 
angular fundamentals.pdf angular fundamentals.pdf
NuttavutThongjor1
 
mean stack mean stack mean stack mean stack
NuttavutThongjor1
 
nuxt-rendering-modes.pdf
NuttavutThongjor1
 
Ad

Nest.js RESTful API development.pdf Nest.js RESTful API development.pdf