SlideShare a Scribd company logo
NEST.JS API
DEVELOPMENT
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
Posts Controller
Users Controller
/products
Orders Service
Posts 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
injec
t
UsersModul
e
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
Posts 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”: [] }
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
@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
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
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
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
Babel Coder
Babel Coder
https://www.babelcoder.com
PAGINATION
page = 3
limit = 5
skip: 10
take: 5
FILE UPLOADER
Babel Coder
Babel Coder
https://www.babelcoder.com
Babel Coder
Babel Coder
https://www.babelcoder.com
FILE INTERCEPTOR
URL
Method
MIME Type
name
price
categoryIds[]
categoryIds[]
image
/products
POST
multipart/form-data
Lorem
200
12
34
File
Form
Data
File
Interceptor
Babel Coder
Babel Coder
https://www.babelcoder.com
limit
FILE INTERCEPTOR
$ pnpm add -D @types/multer
fileFilter
storage
กำหนดขนาดไฟล์สูงสุด
กำหนดชนิดของไฟล์ที่รองรับ
กำหนดตำแหน่งจัดเก็บไฟล์ที่รองรับ
Babel Coder
Babel Coder
https://www.babelcoder.com
FILE INTERCEPTOR
limit
fileFilter
storage
ขนาดไฟล์สูงสุด 1 MB
Babel Coder
Babel Coder
https://www.babelcoder.com
FILE INTERCEPTOR
limit
fileFilter
storage
รองรับไฟล์ jpg, jpeg, png
คืนข้อผิดพลาดเป็น 422 UNPROCESSIBLE ENTITY
เมื่ออัพโหลดไฟล์ที่ไม่รองรับ
Babel Coder
Babel Coder
https://www.babelcoder.com
FILE INTERCEPTOR
limit
fileFilter
storage
อัพโหลดไฟล์ลงโฟลเดอร์ uploads
สุ่มชื่อไฟล์ด้วย UUID แต่ใช้นามสกุลไฟล์แบบเดียวกับไฟล์ต้นฉบับ
Babel Coder
Babel Coder
https://www.babelcoder.com
FILE INTERCEPTOR
uploads
products
0f8a73b8-d1e4-4a6f-970c-39569ca42063.png
0f8a73b8-d1e4-4a6f-970c-39569ca42063.png
Babel Coder
Babel Coder
https://www.babelcoder.com
SERVE STATIC
uploads
products
0f8a73b8-d1e4-4a6f-970c-39569ca42063.png
<HOST_IP>/uploads/products/0f8a73b8-d1e4-4a6f-970c-39569ca42063.png
$ pnpm add @nestjs/serve-static
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
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 Fullstack Nest.js and Next.js.pdfFullstack Nest.js and Next.js.pdfFullstack Nest.js and Next.js.pdf (18)

Modern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdf
Modern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdf
Modern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdf
NuttavutThongjor1
 
4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf
4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf
4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf
NuttavutThongjor1
 
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdfRecap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
NuttavutThongjor1
 
Modern DevOps Day 4.pdfModern DevOps Day 4.pdf
Modern DevOps Day 4.pdfModern DevOps Day 4.pdfModern DevOps Day 4.pdfModern DevOps Day 4.pdf
Modern DevOps Day 4.pdfModern DevOps Day 4.pdf
NuttavutThongjor1
 
Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...
Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...
Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...
NuttavutThongjor1
 
Synnex update รู้ไว้ใช่ว่า windows server 2012 ขายยังไง
 Synnex update  รู้ไว้ใช่ว่า windows server 2012 ขายยังไง Synnex update  รู้ไว้ใช่ว่า windows server 2012 ขายยังไง
Synnex update รู้ไว้ใช่ว่า windows server 2012 ขายยังไง
Avirot Mitamura
 
Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...
Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...
Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...
NuttavutThongjor1
 
Php dreamwaver
Php dreamwaverPhp dreamwaver
Php dreamwaver
phochai
 
7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf
7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf
7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf
NuttavutThongjor1
 
Websocket & HTML5
Websocket & HTML5Websocket & HTML5
Websocket & HTML5
Bhuridech Sudsee
 
GraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdf
GraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdf
GraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdf
NuttavutThongjor1
 
IT Trends eMagazine Vol 4. No.12
IT Trends eMagazine  Vol 4. No.12IT Trends eMagazine  Vol 4. No.12
IT Trends eMagazine Vol 4. No.12
IMC Institute
 
Modern DevOps Day 3.pdfModern DevOps Day 3.pdf
Modern DevOps Day 3.pdfModern DevOps Day 3.pdfModern DevOps Day 3.pdfModern DevOps Day 3.pdf
Modern DevOps Day 3.pdfModern DevOps Day 3.pdf
NuttavutThongjor1
 
Kafka for developer
Kafka for developerKafka for developer
Kafka for developer
Bhuridech Sudsee
 
php5new
php5newphp5new
php5new
Somjet Sareerom
 
SOA Using GlassFishESB and NetBeans [in Thai]
SOA Using GlassFishESB and NetBeans [in Thai]SOA Using GlassFishESB and NetBeans [in Thai]
SOA Using GlassFishESB and NetBeans [in Thai]
Thanachart Numnonda
 
Modern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdf
Modern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdf
Modern DevOps Day 1.pdfModern DevOps Day 1.pdfModern DevOps Day 1.pdf
NuttavutThongjor1
 
4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf
4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf
4 Docker.pdf 4 Docker.pdf 4 Docker.pdf 4 Docker.pdf
NuttavutThongjor1
 
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdfRecap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
Recap JavaScript and TypeScript.pdf Recap JavaScript and TypeScript.pdf
NuttavutThongjor1
 
Modern DevOps Day 4.pdfModern DevOps Day 4.pdf
Modern DevOps Day 4.pdfModern DevOps Day 4.pdfModern DevOps Day 4.pdfModern DevOps Day 4.pdf
Modern DevOps Day 4.pdfModern DevOps Day 4.pdf
NuttavutThongjor1
 
Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...
Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...
Nest.js Microservices (1).pdf Nest.js Microservices (1).pdfNest.js Microservi...
NuttavutThongjor1
 
Synnex update รู้ไว้ใช่ว่า windows server 2012 ขายยังไง
 Synnex update  รู้ไว้ใช่ว่า windows server 2012 ขายยังไง Synnex update  รู้ไว้ใช่ว่า windows server 2012 ขายยังไง
Synnex update รู้ไว้ใช่ว่า windows server 2012 ขายยังไง
Avirot Mitamura
 
Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...
Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...
Nest.js Microservices.pdfNest.js Microservices.pdfNest.js Microservices.pdfNe...
NuttavutThongjor1
 
Php dreamwaver
Php dreamwaverPhp dreamwaver
Php dreamwaver
phochai
 
7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf
7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf
7 cicd.pdf 7 cicd.pdf 7 cicd.pdf 7 cicd.pdf
NuttavutThongjor1
 
GraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdf
GraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdf
GraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdfGraphQL.pdf
NuttavutThongjor1
 
IT Trends eMagazine Vol 4. No.12
IT Trends eMagazine  Vol 4. No.12IT Trends eMagazine  Vol 4. No.12
IT Trends eMagazine Vol 4. No.12
IMC Institute
 
Modern DevOps Day 3.pdfModern DevOps Day 3.pdf
Modern DevOps Day 3.pdfModern DevOps Day 3.pdfModern DevOps Day 3.pdfModern DevOps Day 3.pdf
Modern DevOps Day 3.pdfModern DevOps Day 3.pdf
NuttavutThongjor1
 
SOA Using GlassFishESB and NetBeans [in Thai]
SOA Using GlassFishESB and NetBeans [in Thai]SOA Using GlassFishESB and NetBeans [in Thai]
SOA Using GlassFishESB and NetBeans [in Thai]
Thanachart Numnonda
 

More from NuttavutThongjor1 (14)

Modern DevOps Day 2.pdfModern DevOps Day 2.pdf
Modern DevOps Day 2.pdfModern DevOps Day 2.pdfModern DevOps Day 2.pdfModern DevOps Day 2.pdf
Modern DevOps Day 2.pdfModern DevOps Day 2.pdf
NuttavutThongjor1
 
misc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdf
misc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdf
misc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdf
NuttavutThongjor1
 
10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf
10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf
10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf
NuttavutThongjor1
 
9 logging and monitoring.pdf 9 logging and monitoring.pdf
9 logging and monitoring.pdf 9 logging and monitoring.pdf9 logging and monitoring.pdf 9 logging and monitoring.pdf
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
8 iac.pdf 8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf 8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf
8 iac.pdf 8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf
NuttavutThongjor1
 
6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf
6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf
6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf
NuttavutThongjor1
 
5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf
5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf
5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf
NuttavutThongjor1
 
3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf
3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf
3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf
NuttavutThongjor1
 
2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf
2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf
2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf
NuttavutThongjor1
 
1 devops คืออะไร.pdf 1 devops คืออะไร.pdf
1 devops คืออะไร.pdf 1 devops คืออะไร.pdf1 devops คืออะไร.pdf 1 devops คืออะไร.pdf
1 devops คืออะไร.pdf 1 devops คืออะไร.pdf
NuttavutThongjor1
 
angular fundamentals.pdf angular fundamentals.pdf
angular fundamentals.pdf angular fundamentals.pdfangular fundamentals.pdf angular fundamentals.pdf
angular fundamentals.pdf angular fundamentals.pdf
NuttavutThongjor1
 
mean stack mean stack mean stack mean stack
mean stack mean stack  mean stack  mean stackmean stack mean stack  mean stack  mean stack
mean stack mean stack mean stack mean stack
NuttavutThongjor1
 
pinia.pdf
pinia.pdfpinia.pdf
pinia.pdf
NuttavutThongjor1
 
nuxt-rendering-modes.pdf
nuxt-rendering-modes.pdfnuxt-rendering-modes.pdf
nuxt-rendering-modes.pdf
NuttavutThongjor1
 
Modern DevOps Day 2.pdfModern DevOps Day 2.pdf
Modern DevOps Day 2.pdfModern DevOps Day 2.pdfModern DevOps Day 2.pdfModern DevOps Day 2.pdf
Modern DevOps Day 2.pdfModern DevOps Day 2.pdf
NuttavutThongjor1
 
misc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdf
misc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdf
misc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdfmisc.pdf
NuttavutThongjor1
 
10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf
10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf
10 วัฒนธรรมองค์กรของ DevOps.pdf10 วัฒนธรรมองค์กรของ DevOps.pdf
NuttavutThongjor1
 
9 logging and monitoring.pdf 9 logging and monitoring.pdf
9 logging and monitoring.pdf 9 logging and monitoring.pdf9 logging and monitoring.pdf 9 logging and monitoring.pdf
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
8 iac.pdf 8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf 8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf
8 iac.pdf 8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf8 iac.pdf
NuttavutThongjor1
 
6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf
6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf
6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf 6 GitOps คืออะไร.pdf
NuttavutThongjor1
 
5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf
5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf
5 Kubernetes.pdf 5 Kubernetes.pdf 5 Kubernetes.pdf
NuttavutThongjor1
 
3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf
3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf
3 Microservices.pdf 3 Microservices 3 Microservices.pdf.pdf
NuttavutThongjor1
 
2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf
2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf
2 เทคโนโลยี cloud computing.pdf 2 เทคโนโลยี cloud computing.pdf
NuttavutThongjor1
 
1 devops คืออะไร.pdf 1 devops คืออะไร.pdf
1 devops คืออะไร.pdf 1 devops คืออะไร.pdf1 devops คืออะไร.pdf 1 devops คืออะไร.pdf
1 devops คืออะไร.pdf 1 devops คืออะไร.pdf
NuttavutThongjor1
 
angular fundamentals.pdf angular fundamentals.pdf
angular fundamentals.pdf angular fundamentals.pdfangular fundamentals.pdf angular fundamentals.pdf
angular fundamentals.pdf angular fundamentals.pdf
NuttavutThongjor1
 
mean stack mean stack mean stack mean stack
mean stack mean stack  mean stack  mean stackmean stack mean stack  mean stack  mean stack
mean stack mean stack mean stack mean stack
NuttavutThongjor1
 
Ad

Recently uploaded (6)

ระบบประสาทนร..............................................
ระบบประสาทนร..............................................ระบบประสาทนร..............................................
ระบบประสาทนร..............................................
Tanachai Junsuk
 
ขั้นตอนการให้บริการแผนกผู้ป่วยนอก (หน่วย.pdf
ขั้นตอนการให้บริการแผนกผู้ป่วยนอก (หน่วย.pdfขั้นตอนการให้บริการแผนกผู้ป่วยนอก (หน่วย.pdf
ขั้นตอนการให้บริการแผนกผู้ป่วยนอก (หน่วย.pdf
AkradechBamrungnam
 
ขั้นตอนการแทงเข็มพอร์ต A Cath ในผู้ป่วยมะเร็งที่ได้รับยาเคมีบำบัด
ขั้นตอนการแทงเข็มพอร์ต A Cath ในผู้ป่วยมะเร็งที่ได้รับยาเคมีบำบัดขั้นตอนการแทงเข็มพอร์ต A Cath ในผู้ป่วยมะเร็งที่ได้รับยาเคมีบำบัด
ขั้นตอนการแทงเข็มพอร์ต A Cath ในผู้ป่วยมะเร็งที่ได้รับยาเคมีบำบัด
AkradechBamrungnam
 
ต่อมไร้ท่อ...............................................
ต่อมไร้ท่อ...............................................ต่อมไร้ท่อ...............................................
ต่อมไร้ท่อ...............................................
Tanachai Junsuk
 
เฉลย_แบบฝึกหัดวิชาคณิตศาสตร์ระดับมัธยมศึกษาปีที่6_ความน่าจะเป็น(ตัวแปรสุ่ม)
เฉลย_แบบฝึกหัดวิชาคณิตศาสตร์ระดับมัธยมศึกษาปีที่6_ความน่าจะเป็น(ตัวแปรสุ่ม)เฉลย_แบบฝึกหัดวิชาคณิตศาสตร์ระดับมัธยมศึกษาปีที่6_ความน่าจะเป็น(ตัวแปรสุ่ม)
เฉลย_แบบฝึกหัดวิชาคณิตศาสตร์ระดับมัธยมศึกษาปีที่6_ความน่าจะเป็น(ตัวแปรสุ่ม)
Thanuphong Ngoapm
 
ไฟล์งานการวิเคราะห์ผลจากโปรแกรม SPSS ของ
ไฟล์งานการวิเคราะห์ผลจากโปรแกรม SPSS ของไฟล์งานการวิเคราะห์ผลจากโปรแกรม SPSS ของ
ไฟล์งานการวิเคราะห์ผลจากโปรแกรม SPSS ของ
AkradechBamrungnam
 
ระบบประสาทนร..............................................
ระบบประสาทนร..............................................ระบบประสาทนร..............................................
ระบบประสาทนร..............................................
Tanachai Junsuk
 
ขั้นตอนการให้บริการแผนกผู้ป่วยนอก (หน่วย.pdf
ขั้นตอนการให้บริการแผนกผู้ป่วยนอก (หน่วย.pdfขั้นตอนการให้บริการแผนกผู้ป่วยนอก (หน่วย.pdf
ขั้นตอนการให้บริการแผนกผู้ป่วยนอก (หน่วย.pdf
AkradechBamrungnam
 
ขั้นตอนการแทงเข็มพอร์ต A Cath ในผู้ป่วยมะเร็งที่ได้รับยาเคมีบำบัด
ขั้นตอนการแทงเข็มพอร์ต A Cath ในผู้ป่วยมะเร็งที่ได้รับยาเคมีบำบัดขั้นตอนการแทงเข็มพอร์ต A Cath ในผู้ป่วยมะเร็งที่ได้รับยาเคมีบำบัด
ขั้นตอนการแทงเข็มพอร์ต A Cath ในผู้ป่วยมะเร็งที่ได้รับยาเคมีบำบัด
AkradechBamrungnam
 
ต่อมไร้ท่อ...............................................
ต่อมไร้ท่อ...............................................ต่อมไร้ท่อ...............................................
ต่อมไร้ท่อ...............................................
Tanachai Junsuk
 
เฉลย_แบบฝึกหัดวิชาคณิตศาสตร์ระดับมัธยมศึกษาปีที่6_ความน่าจะเป็น(ตัวแปรสุ่ม)
เฉลย_แบบฝึกหัดวิชาคณิตศาสตร์ระดับมัธยมศึกษาปีที่6_ความน่าจะเป็น(ตัวแปรสุ่ม)เฉลย_แบบฝึกหัดวิชาคณิตศาสตร์ระดับมัธยมศึกษาปีที่6_ความน่าจะเป็น(ตัวแปรสุ่ม)
เฉลย_แบบฝึกหัดวิชาคณิตศาสตร์ระดับมัธยมศึกษาปีที่6_ความน่าจะเป็น(ตัวแปรสุ่ม)
Thanuphong Ngoapm
 
ไฟล์งานการวิเคราะห์ผลจากโปรแกรม SPSS ของ
ไฟล์งานการวิเคราะห์ผลจากโปรแกรม SPSS ของไฟล์งานการวิเคราะห์ผลจากโปรแกรม SPSS ของ
ไฟล์งานการวิเคราะห์ผลจากโปรแกรม SPSS ของ
AkradechBamrungnam
 
Ad

Fullstack Nest.js and Next.js.pdfFullstack Nest.js and Next.js.pdfFullstack Nest.js and Next.js.pdf