iT邦幫忙

2022 iThome 鐵人賽

DAY 8
0
Modern Web

Fastify 101系列 第 8

[Fastify] Day08 - Fastify Server Methods

  • 分享至 

  • xImage
  •  

大家好,我是 Yubin

這篇文章要講的是 FastifyInstance 中定義的幾個重要 method。

大部分是用來設定伺服器的行為,以及註冊 plugins, routes, hooks 用。

Fastify Server Methods

  • listen

可以設定 fastify server 要聽在哪個 host、哪個 port 上,以及成功或失敗的處理。

import fastify, { FastifyInstance, FastifyListenOptions } from 'fastify'

const server: FastifyInstance = fastify()

const fastifyConfig: FastifyListenOptions = {
  port: 8888,
  host: '0.0.0.0'
}

server.listen(fastifyConfig, (error, address) => {
  if (error) {
    console.error(error)
  }
})

.listen() 方法第一個參數為 FastifyListenOptions 物件,常常用來設定這個 server 聽的 address 及 port。
如果沒有給定 host,則會聽在 localhost 上 (也就是只能接收本機來的 request)。
如果沒有給定 port,則會在系統中找第一個可以用的 port 來開。

值得注意的是,'0.0.0.0' 表示會聽所有 IPv4 的 request。
如果環境中可能會有 IPv6 的 request 進來,可以將 host 設定為 '::'

const fastifyConfig: FastifyListenOptions = {
  port: 8888,
  host: '::'
}

所以如果自己在 local 測試都沒問題,部屬出去發現怎麼打不到,可能就是這個 host 的值沒有給定。

  • .ready()

若所有 plugins 都被載入完成會呼叫這個 function,若 plugins 載入過程有錯誤,會拋出錯誤。

可以用 callback 的寫法,如

server.ready(err => {
  if (err) throw err
})

.ready() 本身也是一個 Promise 物件,可以用這個方法來處理成功或失敗的情況。

server.ready().then(() => {
  console.log('successfully booted!')
}, (err) => {
  console.log('an error happened', err)
})

自己常用的寫法是 await server.ready() 來確保程式流程往下後,每個 plugins 都被載入成功。(因為有許多 plugin 的註冊都是 async function)

  • .after()

註冊完一個或多個 plugins 後呼叫,會在 .ready() 之前被呼叫。

可以用來對每個 plugin 的載入狀況做個別的處理。

server
  .register((instance, opts, done) => {
    console.log('Current plugin')
    done()
  })
  .after(err => {
    console.log('After current plugin')
  })
  .register((instance, opts, done) => {
    console.log('Next plugin')
    done()
  })
  .ready(err => {
    console.log('Everything has been loaded')
  })
  • .route()

註冊 route 用的,裡面傳入 RouteOptions 物件。更多資訊可以參考 Fastify101: route

  • .hasRoute()

用來檢查某個 route 是否存在,回傳值為 boolean。

const routeExists = server.hasRoute({
  url: '/',
  method: 'GET'
})

if (routeExists === false) {
  // add route
}
  • .close()

將 FastifyInstance 關閉用。

server 關閉的途中,如果有新的 request 進來,會回應 503 (Service Unavailable) 的狀態碼,並將該 request 銷毀。
如果需要,可以控制 FastifyServerOptions 中的 return503OnClosing 來改變預設行為。

.close() 本身也是一個 Promise 物件,可以處理正常關閉或錯誤關閉的情況。

fastify.close().then(() => {
  console.log('successfully closed!')
}, (err) => {
  console.log('an error happened', err)
})
  • .addHook()

註冊 hook 使用。

  • .register()

註冊 plugin 使用。

  • .log

這個不是 function,.log 可以拿到 logger 的 instance,預設為 Pino instance,用來寫 log 非常方便。

server.log.info('Hello Pino')
  • .inject()

製造一個假的 request 傳入 server 中,寫 server 的 testing 的時候必備。

  • .setNotFoundHandler()

設定 404 Not Found 時候的處理行為。

  • .setErrorHandler()

Fastify 預設會將 error 的處理以狀態碼 500 (Internal Server Error) 的形式回應出去,這個 handler 可以控制這個預設行為。
例如,收到 error 的時候寫 log,或改變預設的 Status Code。

server.setErrorHandler((error, request, reply) => {
  // Log error
  request.log.error(error)
  // Send error response
  reply.status(409).send({ ok: false })
})
  • .printRoutes()

印出 route 的樹狀圖,debug 很好用。

記得要在 .reader() 之後 (或 callback) 中使用。

server.get('/test', () => {})
server.get('/test/hello', () => {})
server.get('/hello/world', () => {})
server.get('/helicopter', () => {})

server.ready(() => {
  console.log(server.printRoutes())
})

印出

└── /
    ├── test (GET)
    │   test (HEAD)
    │   └── /hello (GET)
    │       /hello (HEAD)
    └── hel
        ├── lo
        │   └── /world (GET)
        │       /world (HEAD)
        └── icopter (GET)
            icopter (HEAD)

可以加上 commonPrefix: false 的參數。

console.log(server.printRoutes({ commonPrefix: false }))

└── / (-)
    ├── helicopter (GET, HEAD)
    ├── hello/world (GET, HEAD)
    └── test (GET, HEAD)
        └── /hello (GET, HEAD)
  • .printPlugins()

可以把所有註冊的 plugins 印出來,一樣 debug 用。


以上是常用/實用的 Fastify Server Methods。
如果想要了解更多資訊,可以參考 Fastify: Server Method


上一篇
[Fastify] Day07 - FastifyInstance and FastifyServerOptions
下一篇
[Fastify] Day09 - Hook
系列文
Fastify 10130
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言