提出此问题的场景:
后端 API 返回 JSON 格式的数据,但字段通常都是 snake_case 的,即使是 camelCase ,有时候前端也需要对其重命名以符合前端的命名规范和一致性。
通常后端 API 返回 JSON 格式的数据都是序列化为 JavaScript 后就丢弃了,目前的做法需要 2 步:
第 2 步中存在这么一些问题:
一种解决此问题的想法
解决思路是允许后端对象和前端对象共享 1 个 interface ,并且除了静态检查,运行时也会校验数据合法性。
举个例子,后端返回如下数据:
{
"id": 1,
"usename": "testuser",
"avatar_url": "https://....",
"is_admin": false,
"type": "vip"
}
前端可以定义如下 interface:
/*
rename_all = "camelCase"
*/
interface User {
id: number;
username: string;
avatarUrl: string;
isAdmin: string;
/*
alias="type"
*/
userType: string;
}
注意到注释 rename_all = "camelCase",alias="type"(当然注释只是一种注解的形式,可行性暂不讨论),那么在根据这个 interface 序列化和反序列化是,库将根据注解将所有的 snake_case ,转为 camelCase ,userType 的值将从原数据对象的 type 字段提取。此外由于类型都是 string 或者 number ,如果原对象的值类型不符合,运行时将直接抛出异常。
以下是一个调用示例:
// 此调用内部会将后端返回的数据序根据 User interface 的信息列化为符合这个接口的对象,如果无法序列化,抛出异常。
api.get("testuser").json<User>()
1
zcf0508 2022-06-24 13:13:43 +08:00
浏览器运行的是 js 不是 ts
|
2
iulo 2022-06-24 13:33:11 +08:00
两个建议:
1. 不要犯教条主义的错误,snake_case 和 camelCase 并不是绝对不能混用,只要明确好边界(返回的数据全部是 snake_case ,自身代码逻辑变量 camelCase ),没什么弊端,自己内部的规范应该是根据社区共识和自身情况来综合考虑的。 2. 前后端使用通用协议描述数据结构,例如 pb ,你要做的是把协议文件"翻译"成一份类型描述放在项目内,而不是在运行时去下发类型描述。 |
3
NathanInMac 2022-06-24 13:38:43 +08:00
x y 问题吧,楼上说的挺好的了。grpc web 之类的工具可以完美解决
|
4
gfreezy 2022-06-24 13:55:04 +08:00 2
看看这个 https://deepkit.io/
|
5
iamgqb 2022-06-25 11:12:00 +08:00 via iPhone
json mapper
|