有人可以帮助我在 FASTIFY 中创建一个 HOOK 来自动序列化所有 app.ts 端点中的这些类型的值吗?

问题描述 投票:0回答:1

有人可以帮我在 FASTIFY 中创建一个 HOOK 来自动序列化所有 app.ts 端点中的这些类型的值

我设法使用 .toString 解决了问题,但我想要一种在所有请求中自动执行此操作的方法

node.js serialization biginteger fastify
1个回答
0
投票

首先,JS标准函数不支持bigint:

const big = { n: :1231231231231231213n }
console.log(typeof big.n) // bigint
JSON.stringify(big) // TypeError: Do not know how to serialize a BigInt

JSON.parse('{"n":1231231231231231213}') // { n: 1231231231231231200 }

这里有3种解决方案:

  1. 设置 json 模式响应,fastify 会通过将它们转换为数字来为您完成此操作!
  2. 使用
    preSerialization
    钩子获取序列化的所有权。请注意,
    toString
    返回字符串而不是数字
  3. 通过
    setReplySerializer
    获得序列化的所有权。方法不同,但结果与以前相同。

我会使用完全控制序列化的东西,因为

JSON.*
实用程序不支持序列化bigint,并且解析json的客户端必须意识到这一点,否则将会失败! 请参阅上面的代码片段,
JSON.parse()
修剪数字。

const app = require('fastify')({ logger: true })

app.get('/solution-1', {
  schema: {
    response: {
      200: {
        type: 'object',
        properties: {
          n: { type: 'number' }
        }
      }
    }
  }
}, async (request, reply) => {
  return { n: 1231231231231231213n } // prints {"n":1231231231231231200} (not a string 🚀)
})

app.register(function plugin (app, opts, next) {
  app.addHook('preSerialization', async (request, reply, payload) => {
    payload.n = payload.n.toString()
    return payload
  })

  app.get('/solution-2', async (request, reply) => {
    return { n: 1231231231231231213n } // prints {"n":"1231231231231231213"}
  })

  next()
})

app.register(function plugin (app, opts, next) {
  app.setReplySerializer(function (payload, statusCode) {
    return JSON.stringify(payload, (key, value) =>
      typeof value === 'bigint'
        ? value.toString()
        : value
    )
  })
  app.get('/solution-3', async (request, reply) => {
    return { n: 1231231231231231213n } // prints {"n":"1231231231231231213"}
  })

  next()
})

app.listen({ port: 8080 })
curl http://localhost:8080/solution-1
curl http://localhost:8080/solution-2
curl http://localhost:8080/solution-3
© www.soinside.com 2019 - 2024. All rights reserved.