มาลองเล่น Deno GraphQL พร้อมกับทำ Deno Hot Reload กันเถอะ
NotAllow
Posted on May 29, 2020
มาวันนี้หลาย ๆ คนก็น่าจะรู้จัก 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 ดูครับถ้าไม่ผิดพลาดอะไรน่าจะได้ตามรูปด้านล่างนี้ครับ
เสร็จแล้วครับ ขอบคุณที่มาอ่านกันอย่างไรก็ตามขอให้บทความนี้พอจะมีประโยชน์กับผู้อ่านไม่มากก็น้อยนะครับ ผิดพลาดประการใด ขออภัยมา ณ ที่นี้ด้วยครับ
ป.ล. ขอให้สนุกกับไดโนเสาร์นะครับ 😀
Posted on May 29, 2020
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.