DEV Community

NotAllow
NotAllow

Posted on • Updated on

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

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

Install Deno กัน

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

brew install deno
Enter fullscreen mode Exit fullscreen mode

หลังจากที่เราได้ 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
Enter fullscreen mode Exit fullscreen mode

หลังจากติดตั้งมาแล้วให้ 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
Enter fullscreen mode Exit fullscreen mode

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

denon init
Enter fullscreen mode Exit fullscreen mode

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

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

Enter fullscreen mode Exit fullscreen mode

เสร็จแล้วก็ไขไฟล์ ./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 })

Enter fullscreen mode Exit fullscreen mode

เสร็จแล้วมาเขียน 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!
  }
`

Enter fullscreen mode Exit fullscreen mode

เสร็จแล้วมา 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],
})

Enter fullscreen mode Exit fullscreen mode

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

Top comments (0)