You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.1 KiB
6.1 KiB
更新比较慢的版本,先熟悉这个教程和这个框架
fastify/docs-chinese: Fastify 中文文档 (github.com)
开始
准备
npm init -y
# 运行处加入 "build": "tsc -p tsconfig.json",
npx tsc --init
pnpm i -S fastify
pnpm i -D typescript @types/node
// started.ts
import Fastify from 'fastify'
const fastify = Fastify({
logger: false
})
fastify.get('/', async (request, reply) => {
return "Hello World"
})
async function start(){
try{
await fastify.listen({
port:3000,
host:'0.0.0.0'
})
}catch (e){
fastify.log.error(e)
}
}
start()
运行
npm run build
node started.js
路由
完整格式
fastify.route({
method: 'GET',// 请求类型
url: '/',// 请求地址
schema: {// 请求参数验证
querystring: {
name: { type: 'string' },
excitement: { type: 'integer' }
},
response: {// 响应参数验证
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
},
handler: function (request, reply) {// 响应程序
reply.send({ hello: 'world' })
}
})
简写格式
- 也可以将处理函数卸载opts里面,但是如果简写中和opts里面都写了处理函数会报错
const opts = {
schema: {
response: {
200: {
type: 'object',
properties: {
hello: { type: 'string' }
}
}
}
}
}
fastify.get('/', opts, (request, reply) => {
reply.send({ hello: 'world' })
})
URL构建
- Fastify 同时支持静态与动态的 URL
- 要注册一个参数命名的路径,请在参数名前加上_冒号_。_星号_表示通配符。 注意,静态路由总是在参数路由和通配符之前进行匹配
// 参数路由
fastify.get('/example/:userId', (request, reply) => {})
fastify.get('/example/:userId/:secretToken', (request, reply) => {})
// 通配符
fastify.get('/example/*', (request, reply) => {})
// 多参数
fastify.get('/example/near/:lat-:lng/radius/:r', (request, reply) => {})
// 真实的冒号:
fastify.post('/name::verb') // 将被解释为 /name:verb
Async, Await
- 可以直接使用return返回值
- 假如在路由中,
reply.send()
脱离了 promise 链,在一个基于回调的 API 中被调用,你可以使用await reply
, 也可以是return reply
-
-
return value
与reply.send(value)
同时使用只会发送第一次,同时还会触发警告日志,因为你试图发送两次响应。
-
fastify.get('/', options, async function (request, reply) {
setImmediate(() => {
reply.send({ hello: 'world' })
})
await reply
// return reply
})
路由前缀
// server.js
const fastify = require('fastify')()
fastify.register(require('./routes/v1/users'), { prefix: '/v1' })
fastify.register(require('./routes/v2/users'), { prefix: '/v2' })
fastify.listen(3000)
// routes/v1/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', handler_v1)
done()
}
// routes/v2/users.js
module.exports = function (fastify, opts, done) {
fastify.get('/user', handler_v2)
done()
}
自定义日志级别
- 可以在统一路由加入打印固定字段的,但是非必要
// server.js
const fastify = require('fastify')({ logger: true })
fastify.register(require('./routes/user'), { logLevel: 'warn' })
fastify.register(require('./routes/events'), { logLevel: 'debug' })
fastify.listen(3000)
- 也可以直接在路由的opts中定义
fastify.get('/', { logLevel: 'warn' }, (request, reply) => {
reply.send({ hello: 'world' })
})
装饰器
fastify.decorate('utility', function () {
// 新功能的代码
})
fastify.decorate('conf', {
db: 'some.db',
port: 3000
})
// 通过装饰属性的名称便可访问值:
fastify.utility()
console.log(fastify.conf.db)
路由函数的 this
指向 Fastify server
fastify.decorate('db', new DbConnection())
fastify.get('/', async function (request, reply) {
reply({hello: await this.db.query('world')})
})
检查装饰器的存在
用于检查服务器实例上是否存在某个装饰器:
// 用于检查服务器实例上是否存在某个装饰器:
fastify.hasDecorator('utility')
// 用于检查 Request 实例上是否存在某个装饰器
fastify.hasRequestDecorator('utility')
// 用于检查 Reply 实例上是否存在某个装饰器
fastify.hasReplyDecorator('utility')
验证和序列化
验证器复用
myField: { $ref: '#foo'}
将在当前 schema 内搜索$id: '#foo'
字段。myField: { $ref: '#/definitions/foo'}
将在当前 schema 内搜索definitions.foo
字段。myField: { $ref: 'http://url.com/sh.json#'}
会搜索含$id: 'http://url.com/sh.json'
的共用 schema。myField: { $ref: 'http://url.com/sh.json#/definitions/foo'}
会搜索含$id: 'http://url.com/sh.json'
的共用 schema,并使用其definitions.foo
字段。myField: { $ref: 'http://url.com/sh.json#foo'}
会搜索含$id: 'http://url.com/sh.json'
的共用 schema,并使用其内部带$id: '#foo'
的对象。
fastify.addSchema({
$id: 'http://example.com/',
type: 'object',
properties: {
hello: { type: 'string' }
}
})
fastify.post('/', {
handler () {},
schema: {
body: {
type: 'array',
items: { $ref: 'http://example.com#/properties/hello' }
}
}
})
// 作为根引用
fastify.addSchema({
$id: 'commonSchema',
type: 'object',
properties: {
hello: { type: 'string' }
}
})
fastify.post('/', {
handler () {},
schema: {
body: { $ref: 'commonSchema#' },
headers: { $ref: 'commonSchema#' }
}
})
获取共用Schema
- 当自定义验证器或序列化器的时候,Fastify 不再能控制它们,此时
.addSchema
方法失去了作用
fastify.addSchema({
$id: 'schemaId',
type: 'object',
properties: {
hello: { type: 'string' }
}
})
const mySchemas = fastify.getSchemas()
const mySchema = fastify.getSchema('schemaId')