ก้าวสู่อีกขั้นของการเขียน api gateway ด้วย Nest.js + GraphQL

ก้าวสู่อีกขั้นของการเขียน api gateway ด้วย Nest.js + GraphQL
21/01/22   |   1.9k   |  

สวัสดีครับ ผมชื่อจ๊อบนะครับ เป็นเด็กจบไหม่ไฟแรง จบจากคณะวิศวกรรมศาสตร์ สาขาวิศวกรรมคอมพิวเตอร์ ที่มหาวิทยาลัยสีม่วงแห่งหนึ่งในเชียงใหม่

ปัจจุบันทำงานตำแหน่ง 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 ตัวเต็มที่เกี่ยวข้องนะครับ

ลิ้งเดียว ครบ จบ

 

สำหรับบทความนี้ก็หวังว่าจะเป็นประโยชน์กับหลายๆคนนะครับ (หรือปวดหัวแทน)

ก็ขอขอบคุณทุกคนมากๆนะครับที่เข้ามาอ่าน ไว้เจอกันใหม่บทความหน้านะครับ ขอบคุณครับ !

 

 



ติดตามข่าวสารและเรื่องราวดีๆ ทาง Email