DEV Community

Cover image for มาลองใช้ NestJS ทำ GraphQL Server กัน (ฉบับผู้เริ่มต้น)
NotAllow
NotAllow

Posted on • Edited on

มาลองใช้ NestJS ทำ GraphQL Server กัน (ฉบับผู้เริ่มต้น)

ทุกวันนี้ผมใช้ express + apollo ทำ GraphQL Server แต่ปีนี้ในทีมก็มีมติว่าจะเปลี่ยนไปเขียน TypeScript ซึ่งจะตอบโจทย์ในเรื่องของ NewBie Mistakes ตอนแรกว่าจะเขียนไว้อ่านเอง แต่ก็อยากมาแชร์ให้ทุก ๆ คนมาลองดูกันครับ

มาทำความรู้จักกันครับว่า NestJS คืออะไร

NestJS อย่างที่หลาย ๆ คนทราบกันดีอยู่แล้วว่ามันคือ Framework ตัวนึงที่เขียนด้วย TypeScript และออกแบบมาโดยใช้แนวคิด OOP กับ Fuctional Programming เข้าด้วยกัน ซึ่ง NestJS ก็อาศัยการทำงานของ HTTP Server ที่เราสามารถเลือกใช้ได้ก็จะเป็น Express หรือ Fastify ในบทความนี้ผมขอใช้ Express แล้วกันนะครับ

มาเริ่มกันเลยดีกว่า

ติดตั้ง Nest CLI กันก่อน ด้วย Command ตามนี้

$ npm i -g @nestjs/cli 
Enter fullscreen mode Exit fullscreen mode

เสร็จแล้วก็สร้างโปรเจค

$ nest new nestjs-graphql-starter 
Enter fullscreen mode Exit fullscreen mode

แล้วมันจะขึ้นให้เลือก package manager ว่าจะใช้ npm หรือ yarn ในทีนี้ผมก็เลือก yarn นะครับ

Which package manager would you ❤️ to use? npm or yarn 
Enter fullscreen mode Exit fullscreen mode

เท่านี้ก็จะได้ Nestjs project structer มาแล้วครับ ต่อมาเราจะมาเริ่มใช้ GrahpQL ร่วมกับ NestJS กัน

ก่อนอื่นก็มาติดตั้ง GraphQL กันด้วยคำสั่ง

$ yarn add @nestjs/graphql graphql-tools graphql // or npm i --save @nestjs/graphql graphql-tools graphql 
Enter fullscreen mode Exit fullscreen mode

ต่อมาติดติ้ง Http server จะเลือกใช้ตัวไหนก็ได้ระหว่าง express กับ fastify

กรณีเลือกใช้ express ใช้คำสั่ง

$ yarn add apollo-server-express // or npm i --save apollo-server-express 
Enter fullscreen mode Exit fullscreen mode

กรณีเลือกใช้ fastify ใช้คำสั่ง

$ yarn add apollo-server-fastify // or npm i --save apollo-server-fastify 
Enter fullscreen mode Exit fullscreen mode

เข้า Folder ที่สร้างเมื่อกี้ด้วย Editor Tool แล้วหาไฟล์ nest-cli.json ใส่ code ตามนี้

{ "compilerOptions": { "plugins": ["@nestjs/graphql/plugin"] } } 
Enter fullscreen mode Exit fullscreen mode

ต่อมาแก้ไขไฟล์ ./src/app.module.ts เพื่อเรียกใช้งาน graphql ตาม code ด้านล่างนี้ได้เลยครับ

import { Module } from '@nestjs/common' import { GraphQLModule } from '@nestjs/graphql' @Module({ imports: [ GraphQLModule.forRoot({ installSubscriptionHandlers: true, autoSchemaFile: 'schema.gql', debug: false, playground: true, }), ], }) export class AppModule {} 
Enter fullscreen mode Exit fullscreen mode

จาก code ด้านบน

installSubscriptionHandlers: true ไว้สำหรับเลือกเปิดใช้งาน Subscription หรือไม่
autoSchemaFile: 'schema.gql' ไว้ generate file typeDefs schema เพื่อนำไปไว้ Build เพื่อ Run Apollo Server
debug: false ไว้สำหรับจะเลือกใช้งาน debug หรือไม่
playground: true ไว้สำหรับเลือกเปิดใช้งาน playgroud client หรือไม่

ต่อมาพระเอกของเรากันดีกว่า Nest มี CLI ไว้สร้าง Module,Interface,Resolver,Service
มาสร้าง module กัน ด้วยคำสั่ง

$ nest g module {name} //or nest g mo {name} 
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างผมจะสร้าง module ชื่อ book ก็ใช้คำสั่ง

$ nest g mo book 
Enter fullscreen mode Exit fullscreen mode
$ nest g resolver {name} //or nest g r {name} 
Enter fullscreen mode Exit fullscreen mode

ตัวอย่างผมจะสร้าง Resolver ชื่อ book ก็ใช้คำสั่ง

$ nest g r book 
Enter fullscreen mode Exit fullscreen mode

ทีนี้ NestJS ก็ได้ออก Decorator ของตัวเองเพื่อทำ DTO (Data Transfer Object) ไว้แล้ว โดยที่เมื่อก่อนยืมของ TypeGraphQL มาใช้ก่อน งั้นเรามาเริ่มสร้าง Model กัน
สร้างโดยการ Create Folder ให้อยู่ใน Directory Book ที่ ./src/book/models/book.model.ts

import { Field, ID, ObjectType } from '@nestjs/graphql' @ObjectType() export class Book { @Field(type => ID) id: string @Field(type => String, { nullable: true }) name?: string @Field(type => String, { nullable: true }) description?: string @Field(type => Number, { nullable: true }) price?: number @Field(type => [String], { nullable: true }) writer?: string[] } 
Enter fullscreen mode Exit fullscreen mode

ถ้าต้องการให้ Field มีค่าเป็น null ได้ ให้ใส่ options เพิ่มคือ { nullable: true } และใส่ ? หลังตัวแปรเพื่อละเว้นให้เป็น optional ได้

เสร็จแล้วสร้าง DTO ไว้หรับ Type Input กันเถอะเพื่อไปใช้เป็น Variable ตอนเรียกใช้งานกัน

create folder dto ให้อยู่ใน Directory Book ที่ ./src/book/dto
แล้ว create file book.input.ts อยู่ใน folder dto
เมื่อสร้างแล้วเขียน code ตามนี้เลยครับ

import { Field, InputType } from '@nestjs/graphql' @InputType() export class InputBook { @Field(type => String) name: string @Field(type => Number, { nullable: true }) price?: number @Field(type => String, { nullable: true }) description?: string @Field(type => [String]) writer: string[] } 
Enter fullscreen mode Exit fullscreen mode

ถ้าต้องการให้ Field ไหนเป็น Array ให้ใส่ [] คอบ Type นั้นได้เลยครับ

มาจัดการกับ Resolver กัน ในบทความที่ผมเขียนนี้จะยกการทำ Mutation กับ Query ไว้เท่านี้ก่อนนะครับเพื่อไม่ให้บทความมีความยาวมากเกินไป

กลับมาที่ File : book.resolver.ts แล้วเขียน Code สร้าง Mutation กับ Query กันตามนี้เลยครับ ขออนุญตาติฟิกค่า return เลยนะครับ

import { Resolver, Query, Mutation, Args } from '@nestjs/graphql' import { Book } from './models/book.model' import { InputBook } from './dto/book.input' @Resolver('Book') export class BookResolver { @Query(returns => Book) getBook(): Book { const result: Book = { id: '1', name: 'BeforeSecond', price: 199, } return result } @Mutation(returns => Book) createBook(@Args('input') input: InputBook): Book { const result: Book = { id: '2', ...input, } return result } } 
Enter fullscreen mode Exit fullscreen mode

เสร็จแล้วลองรันกันครับ

$ yarn start:dev 
Enter fullscreen mode Exit fullscreen mode

เข้า Web Browser เปิด URL: http://localhost:3000/graphql

ทดสอบ Query กัน

ใส่ Code Query ดังนี้

query { getBook{ id name price description writer } } 
Enter fullscreen mode Exit fullscreen mode

ปรากฏว่าได้ผลลัพทธ์

{ "data": { "getFirst": { "id": "1", "name": "first" } } } 
Enter fullscreen mode Exit fullscreen mode

ทดสอบ Mutation กัน

mutation { createBook(input:{ name:"test", description:"ทดสอบ", price:299, writer:["First","BeforeSecond"] }){ id name price description writer } } 
Enter fullscreen mode Exit fullscreen mode

ผลลัพท์

{ "data": { "createBook": { "id": "2", "name": "test", "price": 299, "description": "ทดสอบ", "writer": [ "First", "BeforeSecond" ] } } } 
Enter fullscreen mode Exit fullscreen mode

Very Good 👍👍👍👍👍

สรุปได้ว่า NestJS ก็เป็นอีกทางเลือกนึงที่สามารถทำ GraphQL Server ได้ด้วยการเขียน TypeScript ที่ผมคิดว่าตอบโจทย์ได้ดีเลยทีเดียวครับ โดยปกติถ้าเขียน Express+Apollo เราจะต้องมานั่งทำ typeDefs เอง หรือบ้างก็ไปใช้ CLI codegen:generate แต่ NestJS ทำให้เราสะดวกมากขึ้นไปเยอะเลย ยิ่งถ้าใช้ TypeORM หรือ Sequelize นี่ยิ่งสบายเลยกับการเขียน GraphQL มาก ๆ เลยครับ

สุดท้ายนี้ ถ้าผิดพลาดต้องขอภัยด้วยนะครับ ขอบคุณที่อ่านมาจนจบครับผม 😀
สามารถศึกษาเพิ่มเติมได้ที่
Referense: https://docs.nestjs.com/graphql/quick-start

Top comments (1)

Collapse
 
adrinalin4ik profile image
Alex Panfilkin

You can also try to use this one npmjs.com/package/nestjs-graphql-t...