大家好,我是 Yubin
這篇文章要講的是 FastifyInstance 中定義的幾個重要 method。
大部分是用來設定伺服器的行為,以及註冊 plugins, routes, hooks 用。
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。