สวัสดีครับ ผมชื่อจ๊อบนะครับ เป็นเด็กจบไหม่ไฟแรง จบจากคณะวิศวกรรมศาสตร์ สาขาวิศวกรรมคอมพิวเตอร์ ที่มหาวิทยาลัยสีม่วงแห่งหนึ่งในเชียงใหม่
ปัจจุบันทำงานตำแหน่ง software engineer อยู่ที่ THiNKNET ครับ
ขอเกริ่นก่อนเลยนี่เป็น blog แรกของผม ฮ่าๆๆ อาจจะพูดวกไปวนมาสักหน่อย แต่ก็ฝากตัวด้วยครับ
ทุกคนคงจะเคยเขียน api กันมาบ้าง ไม่ว่าจะเป็น RESTful API หรือ graphql ก็ต้องเคยมีกันมาบ้างแหละ
วันนี้ผมจะมาแนะนำเครื่องมือที่น่าสนใจ ที่จะทำให้การเขียน api โดยใช้ graphql นั้น ง่ายและรวดเร็ว
ก่อนอื่นเลย nest.js คืออะไร
nest.js คือ nodejs server-side application framework โดยมี architecture และใช้คอนเซปต์ dependency injection ที่เหมือน angular
เพิ่มเติม ถ้าอยากอ่านเกี่ยวกับ dependency injection
โดยที่ใน Document ของ nest.js เองก็กล่าวเอาไว้ว่า
The architecture is heavily inspired by Angular.
อธิบายยืดยาวไปคงน่าเบื่อ ถ้าใครอยากลงลึกเกี่ยวกับหลักการและ philosophy มากกว่านี้สามารถไปศึกษาเพิ่มเติมใน document ของ nest.js ได้ครับ
ในที่นี้ผมจะพา workshop สั้นๆ เพื่อเน้นการไปใช้งานจริงกันครับ
โดย workshop ที่เราจะทำจะเป็นการเขียน graphql api เพื่อดึงข้อมูล todo และ user มาจาก jsonplaceholder service
json placeholder api : https://jsonplaceholder.typicode.com
สิ่งที่ต้องเตรียมพร้อม
- node.js version >= 10.13.0, แนะนำ v13 ขึ้นไป
- vscode หรือ editor อื่นๆที่ถนัด (แนะนำ vscode นะ intellisense(autocomplete) มันว้าวมาก)
- yarn ติดตั้งโดย (npm i -g yarn หรือใน linux mac จะเป็น sudo npm i -g yarn)
อันดับแรกติดตั้ง nest cli โดยใช้คำสั่ง
$ sudo yarn global add @nestjs/cli
ทดสอบใช้ nest cli ว่าเราลงสำเร็จ จะได้ผลลัพธ์ประมาณนี้
เริ่มโปรเจคใหม่ด้วยคำสั่ง
$ nest new project-name
เลือก yarn
เปิดโปรเจคขึ้นมา
อธิบาย structure
- app.module.ts คือ module หลัก หรือ main config ต่างๆใน module นั้นๆ
- app.service.ts ทำงานเป็น controller คือที่เอาไว้เก็บพวก logic ต่างๆใน module นั้นๆ
- app.controller.ts เป็นเหมือน route ที่ค่อยเรียกใช้ logic จาก app.service.ts อีกที (การทำงานต่างจากชื่อเรียก แต่ใน graphql เราจะไม่ใช้ไฟล์นี้)
ทดสอบรันโปรเจคโดยใช้คำสั่ง
$ yarn start:dev
เข้า browser ไปที่ http://localhost:3000 จะได้ผลลัพธ์ดังนี้
ถ้าทำมาถึงตรงนี้แล้วยัง มึนๆ งงๆ แนะนำให้ลองกลับขึ้นไปทำอีกรอบนะครับ จากนี้ไปของจริง (จริงๆก็ขู่ไปงั้นแหละ ฮ่าๆๆ)
โอเค ไปต่ออ
ทำการลง graphql package โดยใช้คำสั่ง
$ yarn add @nestjs/graphql graphql@^15 apollo-server-express
config graphql ไปที่ app module
/src/app.module.ts
โดยตอนแรกนั้น โค้ดจะ error ไม่ต้องตกใจ เพราะตัวมันเองยังไม่มี root resolver
เมื่อเสร็จแล้ว อันดับแรก สิ่งแรกที่เราจะทำคือการ เขียน schema
โดย schema แรก คือ schema ของ user มาดูกันว่า user มี schema เป็นแบบไหนก่อน
จะได้ว่า user หน้าตาเป็นแบบนี้
{
id: number,
name: string,
username: string,
email: string,
}
ในที่นี้จะใช้ field เท่าที่เราต้องการ จะไม่เอามาหมด
ทำการสร้าง module แรก คือ user module
/src/user/user.module.ts
ต่อไปทำการเขียน schema ของ user
/src/user/user.schema.ts
ทำการสร้าง user resolver
/src/user/user.resovler.ts
โดยทดสอบสร้าง query helloWorld ดังข้างต้น
ทำการ provide resolver ไปที่ user module
/src/user/user.module.ts
และทำการ import user module ไปที่ app.module.ts
ทำการทดสอบโดยไปที่ playground โดยเข้าได้ที่ http://localhost:3000/graphql
ทดสอบ query ได้ผลลัพธ์ดังนี้
ต่อไปเราจะย้าย logic ไปที่ controller แต่ในที่นี้เราจะเรียกว่า service
/src/user/user.service.ts
ทำการ provide ที่ user module
เรียกใช้ user.service ที่ user.resolver
/src/user/user.resolver.ts
ทำการทดสอบ query ที่ playground จะต้องได้ผลลัพธ์ตามเดิม ถ้ามีอะไรผิดพลาด
ลองย้อนกลับไปไหม่นะครับ T^T
โอเคครับ เหนื่อยกันรึยัง ฮ่าๆๆ
สู้ๆนะครับ อีกนิดเดียว api เราก็จะสมบูรณ์แล้ว
ต่อไปเราจะทำการยิงไปที่ jsonplaceholder เพื่อดึงข้อมูล user ออกมาจริงๆนะครับ
ทำการลง axios
$ yarn add axios
สร้าง service สำหรับ fetch ข้อมูลจาก service อื่นดังนี้
/src/services/jsonPlaceholderService.ts
provide ที่ user module
/src/user/user.module.ts
ทำการเขียน logic ใน user.service.ts
/src/user/user.service.ts
ทำการเขียน resolver
/src/user/user.resolver.ts
ทดสอบที่ playground จะได้ผลลัพธ์ดังนี้
ส่วนในฝั่งของ todo ก็ทำคล้ายๆของ user เลยครับ พาทำต่อกลัวจะยาวว ฮ่าๆๆๆ
สรุป ข้อดี-ข้อเสีย
ข้อดี
- ด้วย sturcture ที่แบ่งเป็น module ทำให้แบ่งเรื่องแต่ละเรื่องเป็นหมวดหมู่เข้าถึงง่าย
- มีรูปแบบการเขียนเป็นแบบ OOP (object-oriented programming) ทำให้ทำความเข้าใจโค้ดแต่ละส่วนได้ง่าย
- การเขียน graphql schema เขียนเป็น class object base ทำให้ validate schema type ได้ง่ายขึ้นในขณะเขียนโค้ด
- ใช้ typescript for safety ทำให้ลดบัคที่เกิดจากการเขียนได้มากขึ้น
ข้อเสีย
- nestjs นั้นมี size ที่หนักเกินไป เมื่อเทียบกับ express ที่ lightweight กว่ามาก
- มี learning curve ที่สูงพอสมควร เนื่องจากใช้หลักการเหมือน angular และใช้ typescript
- ต้องมีความเข้าใจใน structure ในระดับหนึ่ง
สำหรับ document ตัวเต็มที่เกี่ยวข้องนะครับ
ลิ้งเดียว ครบ จบ
สำหรับบทความนี้ก็หวังว่าจะเป็นประโยชน์กับหลายๆคนนะครับ (หรือปวดหัวแทน)
ก็ขอขอบคุณทุกคนมากๆนะครับที่เข้ามาอ่าน ไว้เจอกันใหม่บทความหน้านะครับ ขอบคุณครับ !