loading...

มาลองเล่น Deno GraphQL พร้อมกับทำ Deno Hot Reload กันเถอะ

beforesecond profile image beforesecond ・2 min read

มาวันนี้หลาย ๆ คนก็น่าจะรู้จัก Deno มาสักพักแล้ว Deno เป็น Runtime ตัวใหม่ของ
Javascript ที่จะมาแทน Node ในอนาคตสำหรับใครยังไม่ได้ติดตั้ง Deno ไปติดตั้งกันเลยดีกว่า

Install Deno กัน

สำหรับ MacOS ใช้ Homebrew ไปเลย แต่ถ้าใช้ OS อื่น ๆ สามารถดูการติดตั้งได้ที่นี่เลย https://deno.land/#installation

brew install deno

หลังจากที่เราได้ Deno มาแล้วก็มาเข้าเรื่องกันผมจะขอทำ Hot Reload และมาพูดต่อถึงการเขียน GraphQL นะครับ

มาเริ่มติดตั้ง Hot Reload ดีกว่า

สำหรับสาย NodeJS คงไม่พ้น Nodemon พอมา Deno ก็มีให้ใช้เหมือนกันนั่นคือ Denon
ขั้นตอนการติดตั้งก็ง่าย ๆ
สิ่งที่ต้องมีคือ Deno Version 1.0.1 ขึ้นไป ก่อนจะติดตั้งมาอัพเกรด Deno เป็น Version ล่าสุดกันก่อนโดยใช้คำสั่ง deno upgrade อัพเกรดเสร็จแล้ว ก็ติดตั้ง Denon กันได้เลย

deno install --allow-read --allow-run --allow-write -f --unstable https://deno.land/x/denon/denon.ts

หลังจากติดตั้งมาแล้วให้ export PATH="$HOME/.deno/bin:$PATH" เพื่อใช้ในการ Execute Deno ที่ได้ติดตั้งมา
เพียงเท่านี้คุณก็จะมี Denon ไว้ทำ Hot Reload แล้วต่อมา เริ่มสร้าง Project Deno GraphQL กัน

GraphQL

บทความนี้ขออนุญาติไม่พูดถึง GraphQL นะครับ เพราะคิดว่าน่าจะพอทราบ ๆ กันบ้างแล้วเนอะ
สิ่งที่ผมใช้คือ OAK ซึ่งเป็น middleware framework ไว้ทำ http server มาเริ่มกันเลยยย

├── denon.json
├── src
│   ├── index.ts
│   └── resolvers
│       ├── index.ts
│       └── user.ts
└── tsconfig.json

ผมจะวางโครงสร้างไว้คร่าว ๆ ตามนี้ครับ
มาสร้าง Denon ให้กับ project นี้กันก่อนโดยใช้คำสั่ง

denon init

เสร็จแล้วจะมีไฟล์ denon.json ให้เราทำการแก้ไขดังนี้

{
  "$schema": "https://deno.land/x/denon/schema.json",
  "scripts": {
    "start": "deno run --allow-net ./src/index.ts"
  }
}

เสร็จแล้วก็ไขไฟล์ ./src/index.ts ใส่ code ตามข้างล่างนี้ได้เลยครับ

import { Application } from 'https://deno.land/x/oak/mod.ts'
import { GraphQLService } from './resolvers/index.ts'

const app = new Application()

app.use(async (ctx, next) => {
  await next()
  const rt = ctx.response.headers.get('X-Response-Time')
  console.log(`${ctx.request.method} ${ctx.request.url} - ${rt}`)
})

app.use(async (ctx, next) => {
  const start = Date.now()
  await next()
  const ms = Date.now() - start
  ctx.response.headers.set('X-Response-Time', `${ms}ms`)
})

await app.use(
  await GraphQLService.routes(),
  await GraphQLService.allowedMethods()
)

console.log('Server start at http://localhost:8080')
console.log('Playgroud at http://localhost:8080/graphql')
await app.listen({ port: 8080 })

เสร็จแล้วมาเขียน resolvers กัน
ให้แก้ไข code ไฟล์ ./src/resolvers/user.ts ส่วนตัวผมชอบ TypeDefs ไว้ที่เดียวกับ Resolvers นะครับ เพราะเวลาจะหา TypeDefs หรือจะแก้ไข Resolvers จะได้แก้ที่ไฟล์เดียวกันไปเลย

import { gql } from 'https://deno.land/x/oak_graphql/mod.ts'

export const resolvers = {
  Query: {
    getUser: (parent: any, { id }: any, context: any, info: any) => {
      console.log('id', id, context)
      return {
        firstName: 'wooseok',
        lastName: 'lee',
      }
    },
  },
  Mutation: {
    setUser: (
      parent: any,
      { firstName, lastName }: any,
      context: any,
      info: any
    ) => {
      console.log('input:', firstName, lastName)
      return {
        done: true,
      }
    },
  },
}

export default gql`
  type User {
    firstName: String
    lastName: String
  }

  input UserInput {
    firstName: String
    lastName: String
  }

  type ResolveType {
    done: Boolean
  }

  type Query {
    getUser(id: String): User
  }

  type Mutation {
    setUser(input: UserInput!): ResolveType!
  }
`

เสร็จแล้วมา import ใช้ Resolvers และ TypeDefs จากไฟล์ ./src/resolvers/user.ts ใน ./src/reolvers/index.ts กันครับ ก็จะได้ตาม code ตัวอย่างด้านล่างนี้

import { applyGraphQL } from 'https://deno.land/x/oak_graphql@0.1/mod.ts'
import user, { resolvers as UserResolvers } from './user.ts'

export const GraphQLService = await applyGraphQL({
  typeDefs: [await user],
  resolvers: [await UserResolvers],
})

เสร็จแล้วสั่ง denon start แล้วลองเล่น Playgroud ดูครับถ้าไม่ผิดพลาดอะไรน่าจะได้ตามรูปด้านล่างนี้ครับ
Login
เสร็จแล้วครับ ขอบคุณที่มาอ่านกันอย่างไรก็ตามขอให้บทความนี้พอจะมีประโยชน์กับผู้อ่านไม่มากก็น้อยนะครับ ผิดพลาดประการใด ขออภัยมา ณ ที่นี้ด้วยครับ
ป.ล. ขอให้สนุกกับไดโนเสาร์นะครับ 😀
Repo : https://github.com/beforesecond/deno_graphql_poc

Discussion

markdown guide