关于javascript:使用-fstjson-自动生成更快的-json-序列化方法

53次阅读

共计 2946 个字符,预计需要花费 8 分钟才能阅读完成。

fst-json 的全称是 “fast-safe-typescript json”,它的实质就是间接应用你定义好的 Typescript 文件,来生成更加高效的序列化办法。
其目标是利用现有的资源(开发过程编写的 Typescript 文件),在编译和开发阶段尽可能进步运行时性能,同时这个过程并没有额定的开发累赘。

github: https://github.com/aircloud/f…

背景

因为 JSON schema 这个概念是由 fastify 引入,咱们先对此进行介绍。

fastify 是一个高性能 Node.JS 服务端框架,其特点就是高性能,而之所以高性能次要的起因就是它引入了 JSON schema,通过对参数减少束缚,来取得更快的序列化速度。

同时,fastify 也开源了一个独立的 json 序列化库 fast-json-stringify,能够在 非 fastify 的我的项目中应用

在 fastify 中,JSON schema 的大抵写法如下:

const schema = {
  schema: {
    response: {
      200: {
        type: 'object',
        properties: {
          hello: {type: 'string'}
        }
      }
    }
  }
}
fastify
  .get('/', schema, function (req, reply) {
    reply
      .send({hello: 'world'})
  })

咱们能够看出,这一套写法不仅会带来额定的学习老本,而且因为目前大多数我的项目开发都是采纳 Typescript,这套定义也会和咱们的 Typescript 定义有所反复。

事实上,尽管下面的示例代码比拟短小,然而在理论的我的项目中,接口比拟多的状况下,这些代码的开发量和额定的学习 / 保护老本还是不容小视的。

那么有没有可能间接应用 Typescript,而不必从新定义 JSON schema 呢?

答案是有的。

fst-json 就是这样一个工具,它能够通过复用咱们在 Typescript 中定义的 schema,通过工具主动生成 fastify 须要的 schema,这样咱们就无需额定保护 schema 定义了。

应用形式

接下来,咱们简略介绍 fst-json 的应用形式,首先装置(全局或者装置到我的项目中):

npm i fst-json -g

假如咱们我的项目采纳了 Typescript,当时曾经有了 schema 文件:

export interface HellWorld {
  attr1: string;
  attr2: string;
  attr3?: string;
}

咱们在我的项目目录下新建 .fstconfig.js,用于申明配置,配置如下:

module.exports = {
  sourceFiles: ['./src/schema/*.ts'],
  distFile: "./src/schema-dist.ts",
  format: 'fastify'
}

之后咱们运行:

fst-json gen

而后此时会生成一个 src/schema-dist.ts,这里会有主动生成的 JSON schema 定义,接下来咱们在我的项目中能够同时应用 JSON schema 定义和咱们之前定义好的 Typescript 类型:

import * as schemas from './schema-dist';
import type {HellWorld} from "./schema";

const schema = {
  schema: {
    response: {200: schemas.HellWorldSchema}
  }
}

server
  .get('/', schema, function (req, reply) {
    let res: HellWorld = {
      attr1: 'hello', 
      attr2: 'world', 
      attr3: 'optional'
    }

    reply
      .send(res);
  })

当然,fst-json 不仅仅能够在 fastify 中应用,也能够在任何其余须要 JSON 减速的中央应用,用法也都很简略,能够参考这个 HelloWorld

原理和劣势

fst-json,实际上是通过对 Typescript 进行语法树解析,针对 export 导出的各种类型生成对应的 fast-json-stringify 的 JSON schema,所以运行速度和手写是没有区别的。因而,它不仅仅能齐全应用 fast-json-stringify 的效率劣势,除了缩小反复开发量以外还有如下长处:

  • 依据 schema 进行字段校验: 首先会进行 Tyepscript 语法校验,另外当缺失必须的属性(例如,当定义 interface 时没有被 ? 修饰符润饰的属性缺失)的时候也会间接报错。
  • 过滤不须要的 schema 字段: 例如当把 Node.JS 当作 BFF 层的时候,能够严格依照 Typescript 的定义来返回字段,防止返回不须要的字段,从而防止上游服务的敏感字段被间接透传出去,也意味着从接口层面开始,真正做到 Fully Typed。
  • 更快的序列化速度: 依据 fast-json-stringify 的测试,能达到靠近 2 倍的 JSON 序列化速度。

目前,fst-json 对罕用的各类 interface、class、type 等类型定义都进行了反对,并且减少了各类 examples 和 90% 的覆盖率测试。

当然,因为 Typescript 的写法比拟灵便。出于 JSON schema 自身的局限性,咱们无奈笼罩所有场景,所以也能够参考这里的注意事项,有针对性的对比拟容易出问题的写法进行躲避。

局限性

fst-json 只是语法解析和生成工具,具体的运行时,实际上就是在应用 fast-json-stringify,也因而我的项目中须要装置 fast-json-stringify 依赖。

另外,针对 fast-json-stringify 的测试,在比拟小的 payload 的状况下,它的速度是有劣势的,当 payload 过大的时候,它的劣势不再显著,甚至还不如 JSON.stringify。官网的形容是:

fast-json-stringify is significantly faster than JSON.stringify() for small payloads.
Its performance advantage shrinks as your payload grows.

不过事实上,这个时候你依然能够应用 fst-json 做一些事件,例如笔者应用 fst-json 来做 bff 层对上游服务接口的继续集成兼容测试,在 Typescript 曾经提前定义好了的状况下,每次测试的时候只须要申请依赖服务并且把响应字段序列化,如果没有报错并且字段序列化之后也没有变成 null(在比较复杂的接口定义中,如果个别属性定义类型和返回类型不统一,fast-json-stringify 是会间接转换成 null),就阐明接口是没有变动的。能够无效防止依赖服务接口变动,却又没有及时同步到位造成暗坑的状况。

另外,其实目前 fast-json-stringify 生成序列化代码还是在运行时做的,这里的问题可能在于代码不通明,以及运行时开销和危险,笔者是心愿将它的生成代码变成编译时去做,不过这样的话实际上有一点反复造轮子的错觉,所以目前还没有做这个事件。


最初 fst-json 作为一个开源不久的小我的项目,必定还有些须要优化和欠缺的中央,欢送 star 反对和提出倡议。

正文完
 0