@JunQiu
2018-09-18T09:31:18.000000Z
字数 6090
阅读 2248
summary_2018/06 designIdea language_node fastify
1、日常工作
2、技术学习
Incoming Request│└─▶ Routing(路由匹配)│└─▶ Instance Logger(实例化log)│404 ◀─┴─▶ onRequest Hook(执行onRequest Hook)│4**/5** ◀─┴─▶ run Middlewares(执行中间件函数)│4**/5** ◀─┴─▶ Parsing(解析请求对象req->request)│415 ◀─┴─▶ Validation(验证)│400 ◀─┴─▶ preHandler Hook│4**/5** ◀─┴─▶ beforeHandler(在handler执行前执行)│4**/5** ◀─┴─▶ User Handler(执行请求处理函数)│└─▶ Reply(响应)│└─▶ onSend Hook│4**/5** ◀─┴─▶ Outgoing Response(output响应)│└─▶ onResponse Hook
###1、如果在执行钩子过程中出现错误,只需将它传递给next()并且Fastify将自动关闭请求并将适当的错误代码发送给用户。(自定义错误代码传递给用户,使用reply.code())2、可以在到达路由处理程序之前响应请求。比如认证钩子。如果您正在使用onRequest或中间件,请使用res.end。如果您正在使用preHandler挂钩,请使用reply.send。3、当fastify.close()被调用来停止服务器时触发。第一个参数是Fastify实例,第二个参数是done回调函数(结束回调)。4、beforeHandler不是标准钩子preHandler,在路由中注册,只会在指定的路由中执行。5、Application Hooks('onClose','onRoute')fastify.addHook('onRequest', (req, res, next) => {// some codenext()})//注意钩子的参数,不同的阶段的参数代表的值不一样fastify.addHook('onRequest', async (req, res) => {// some codeawait asyncMethod()// error occurredif (err) {throw new Error('some errors occurred.')}return})fastify.addHook('preHandler', async (request, reply) => {// some codeawait asyncMethod()// error occurredif (err) {throw new Error('some errors occurred.')}return})fastify.addHook('onSend', async (request, reply, payload) => {// some codeawait asyncMethod()// error occurredif (err) {throw new Error('some errors occurred.')}return})fastify.addHook('onResponse', async (res) => {// some codeawait asyncMethod()// error occurredif (err) {throw new Error('some errors occurred.')}return})
## 应用级别module.exports = function (req, res, next) {next('test')}fastify.use(methodname)##若需限制中间件到特殊路径//只需将路径作为第一个参数传递use// Single pathfastify.use('/css', serveStatic(path.join(__dirname, '/assets')))// Wildcard pathfastify.use('/css/*', serveStatic(path.join(__dirname, '/assets')))// Multiple pathsfastify.use(['/css', '/js'], serveStatic(path.join(__dirname, '/assets')))Tips: not support routes with parameters, (eg: /user/:id/comments) and wildcard is not supported in multiple paths.## 如果需要传入参数(参考express)const mid=require('./test1')fastify.use(mid(222))// midmodule.exports = options=>function (req, res, next) {next(options)}Tips:中间件的请求和响应参数是原生 Nodejs Http 的 req 和 res,而路由中的 request 和 reply 是经过 Fastify 封装的,两者并不一样## 以插件的形式注入,register会创造新的上下文,可以使用fastify-plugin解决// plconst fp = require('fastify-plugin')module.exports = fp(function (fastify, opts, next) {const mid = function (req, res, next) {next(11111)}fastify.use(mid)next()})fastify.register(pl)
### decorateReply(you want to add new methods to the Reply core object. )fastify.decorateReply('utility', function () {// something very useful})//decorateRequest### 依赖(添加一个字符串数组(表示您所依赖的装饰器的名称)作为第三个参数)fastify.decorate('utility', fn, ['greet', 'log'])
##使用fastify.register(plugin, [options])options:logLevel、prefix//创建一个插件非常简单,只需要创建一个带有三个参数的fastify实例,一个选项对象和下一个回调函数。Example:fastify.register(require('./routes/v1/users'), { prefix: '/v1' })// routes/v1/users.jsmodule.exports = function (fastify, opts, next) {fastify.get('/user', handler_v1)next()}Tips:fastify, opts, next## register产生新的上下文,然后传递给下一代fastify.register((instance, opts, next) => {instance.decorate('util', (a, b) => a + b)console.log(instance.util('that is ', ' awesome'))next()})fastify.register((instance, opts, next) => {console.log(instance.util('that is ', ' awesome')) // 抛出异常next()})
node_module.export_export
##作为属性module.exports = {};//exports被赋值,导出失败##方式二module.exports.xx=xx;exports.xx=xx;
### exportexport var firstName = 'Michael';export var lastName = 'Jackson';#orvar firstName = 'Michael';var lastName = 'Jackson';var year = 1958;export {firstName, lastName, year};##别名function v1() { ... }function v2() { ... }export {v1 as streamV1,v2 as streamV2,v2 as streamLatestVersion};##export命令规定的是对外的接口,必须与模块内部的变量建立一一对应关系// 报错export 1;// 报错var m = 1;export m;// 写法一export var m = 1;// 写法二var m = 1;export {m};// 写法三var n = 1;export {n as m};###export default命令,为模块指定默认输出//export default命令只能使用一次//可以指定任意名字,import不要大括号//export default命令其实只是输出一个叫做default的变量// 正确export var a = 1;// 正确var a = 1;export default a;(赋值给default)// 错误export default var a = 1;### import//import语句是 Singleton 模式(加载多个只会加载一个)import {firstName, lastName, year} from './profile.js';import * as circle from './circle';##别名import { lastName as surname } from './profile.js';##import命令输入的变量都是只读的,因为它的本质是输入接口。import {a} from './xxx.js'a = {}; // Syntax Error : 'a' is read-only;#禁止这种操作,本意用于提供只读,难排查错误import {a} from './xxx.js'a.foo = 'hello'; // 合法操作##export、import复合写法export { foo, bar } from 'my_module';// 可以简单理解为import { foo, bar } from 'my_module';export { foo, bar };
回调函数和钩子函数(hook)