摆脱 JSON:Web 开发中数据传输的新方法

摆脱 json:web 开发中数据传输的新方法

如果您一直在 web 开发行业进行编码,那么您很可能非常熟悉 json。这是包罗万象的事实上的标准,从未受到挑战。它无处不在,你已经习惯了。您的所有 rest 调用都通过 json 传输数据。您知道该格式的局限性,并且接受它们。

还是必须这么做?

(注意:所有包和代码的链接都在文章的链接部分)

简史

我的背景是 java 和 javascript/typescript 世界,所以我已经学会了如何处理他们自己的怪癖。许多年前,我开始了一个业余爱好 web 项目(typescript/node),它有一个 json 无法很好解决的问题。

我想摆脱 restful 思维模式,在浏览器和服务器之间实现更轻松、基于消息的传输。为此,我真的很想利用 javascript 类型系统来区分消息。你知道,我们会拥有诸如 adddocumentgetusersgivemeallyourmoney 等类。并且我不会拥有许多 http 端点,而是只有一个,并且消息将以更特别的方式从浏览器流向服务器并返回。

但是我并没有真正有一个优雅的解决方案来满足我的需求,因为 json 在序列化过程中会破坏所有类型信息。当然,我可以使用一些专用属性来传输类型,但这需要自定义处理,我只是觉得这不是我想要走的路线。我只是想要一个协议,它可以按原样获取我的对象,并以反序列化时完全相同的方式序列化它。它将保留所有类型信息,仅此而已。所以我需要一个替代方案。

有人可能会说 json 有很多替代品,例如 protocol buffers 或 messagepack。但这些替代方案的本质是它们都是二进制协议。即使当我搜索它们的使用信息时,web 开发也完全不存在。而且我个人觉得没有一个能满足我的要求。

因此,我开始了为自己创建更好的 json 的挑战。

cbot(基于字符的对象传输)协议简介

大约五年前,我通过创建协议的第一个版本开始了这段旅程。那时它还没有名字;我只是将其称为 ejs(增强型 json)。

通过逐步改进,我开发了第二次迭代。现在,有了第三次进化,我将其命名为 cbot,我终于觉得它已经足够成熟,可以介绍给其他可能感兴趣的人。

该协议的主要特点是什么?它们为何如此重要?

正如我之前提到的,该项目的最初火花是在序列化过程中保留类型的能力。但我很快意识到我还可以嵌入更多 json 无法嵌入的信息。

json 有一个坏习惯,就是不保证任何东西。您可以输入任何您喜欢的内容,并且通常必须相信您的 name 属性实际上包含一个字符串而不是布尔值数组。或者您在运行时检查所有内容以确保。当然,有库可以检查模型。但我再次问自己,为什么实际的协议实现不能做到这一点,以便我可以相信反序列化的就是我想要的东西?

此外,json 的原生类型非常有限。例如,json 有一个用于集合的数组。但 javascript 已经有了集合和映射。我也可以添加它们吗?那么日期呢?我曾多次在日期格式上遇到困难。也许您有一个带有时区的约会,也可能没有。它甚至打算拥有一个吗?你永远不会知道,因为 json 并没有真正告诉你任何事情。

所以本质上,我想以某种方式纠正这种缺点。

为什么不是二进制协议?

这是个好问题。第一个原因是,已经存在过多的二进制协议。那么为什么还要创建另一个呢?第二个问题是,如果有更好的替代方案,为什么他们没有在几年前接管 json?一定有充分的理由。

我的猜测很简单,使用 javascript 处理二进制数据并不那么容易。使用字符串更容易。而且 json 很容易被人类理解和查看。当然,浏览器有原生 json 支持。

由于 cbot 的目标是在浏览器环境中工作,因此创建字符协议会更清晰。

它看起来像什么?

本文并不是 cbot 的教程,因为这样的教程已经存在。然而,因为您很可能是一名开发人员/工程师,所以您至少需要对正在发生的事情有某种程度的了解。所以我为此目的制定了一个例子。在示例中,我使用 cbot 作为简单的 json 替代品。使用更高级的功能需要使用元模型,这在实际教程中也有讨论。

但无论如何,这是物体:

{  name: "john smith",  age: 41,  address: {    street: "second avenue",    postalcode: "1356-a",    city: "yorkistan"  },  isniceguy: true,  hobbies: [    "playing cards",    "shopping",    "asking odd questions"  ],  favouritepoem: {    title: "digital dreams",    created: new date("2024-09-16t12:13:00"),    content: "in the code, we drift and weave,n"      + "a dance of data we perceive.n"      + "with each keypress, a world unfolds,n"      + "infinite stories, yet untold."  }}

当该对象转换为 cbot 消息时,它看起来像这样:

112345abbea  nameb  jkjohn smitha !ageb !id41a "addressb "ea #streetb #jksecond avenuea $postalcodeb $jk1356-aa %cityb %jkyorkistanfa &isniceguyb &ieta 'hobbiesb 'cjkplaying cardsjkshoppingjkasking odd questionsda (favouritepoemb (ea )titleb )jkdigital dreamsa *createdb *ih2024-09-16t12:13:00.000+03:00a +contentb +jloin the code, we drift and weave,oa dance of data we perceive.owith each keypress, a world unfolds,ninfinite stories, yet untold.mff

cbot 格式主要是为了机器可读而设计的。它具有可预测且简单的语法,可以被视为一种小型汇编语言。每个命令都由换行符分隔,每行都以一个操作码开头,解释如何构造对象。

因为这种格式是要以编程方式读取的,所以按原样读取并没有任何意义。但是,它可以以反汇编格式可视化,这可以更好地解释内容:

MCSM 12345abbOBJB (plain)  DEFN 0 name  ASGV 0 (name) STRN SSTR John Smith  DEFN 1 age  ASGV 1 (age) NATV FLOAT64 41  DEFN 2 address  ASGV 2 (address) OBJB (plain)    DEFN 3 street    ASGV 3 (street) STRN SSTR Second Avenue    DEFN 4 postalCode    ASGV 4 (postalCode) STRN SSTR 1356-A    DEFN 5 city    ASGV 5 (city) STRN SSTR Yorkistan  OBJE  DEFN 6 isNiceGuy  ASGV 6 (isNiceGuy) NATV BOOLEAN TRUE  DEFN 7 hobbies  ASGV 7 (hobbies) ARRB    STRN SSTR Playing cards    STRN SSTR Shopping    STRN SSTR Asking odd questions  ARRE  DEFN 8 favouritePoem  ASGV 8 (favouritePoem) OBJB (plain)    DEFN 9 title    ASGV 9 (title) STRN SSTR Digital Dreams    DEFN 10 created    ASGV 10 (created) NATV ZONED_DATETIME 2024-09-16T12:13:00.000+03:00    DEFN 11 content    ASGV 11 (content) STRN STBG      STNL In the code, we drift and weave,      STNL A dance of data we perceive.      STNL With each keypress, a world unfolds,      STPA Infinite stories, yet untold.    STEN  OBJEOBJE

在反汇编中,可以看到一些命令、一些解释和数据。以下是操作码的简要摘要:

mcsm 是一个模型校验和,用于验证消息是否被双方理解。objb / obje 表示对象的开始和结束defn / asgv 对意味着首先将索引分配给属性名称,然后 asgv 使用该索引将值分配给对象。因此,如果消息中再次遇到相同的属性名称,则不必重复。sstr sstr 表示一个简单的普通字符串natv float64 表示 64 位浮点数的本机值natv boolean true,你已经猜到了arrb / arre – 对表示数组的开头和结尾natv zoned_datetime 表示分区日期时间,这是 javascript date 的默认值strn、stbg、stnl、stpa 和 sten 是一组定义字符串生成器的指令。由于字符串可能包含换行符并且它们可以无限长,因此使用字符串构建器模式将字符串拆分为更易于管理的部分。

这是 typescript 独有的东西吗?

不,不是。

由于我的背景和用例,实现自然是从 javascript 端开始的。但由于 cbot 与语言无关,因此它也可以扩展到其他语言。事实上,已经有一个有效的 java 实现,基本上支持该协议能够执行的所有操作。

某处有规范吗?

有点。我发现创建一个合适的规范实际上很难做到。我确实尝试使用某种 ebnf 格式来创建一个,但我的第一个问题是这种格式没有单一的规范(讽刺)。只是对它的一堆解释。另外,即使我使用了其中一个版本,我也没有任何方法来实际验证规范的正确性。

因此,我决定创建一个 typescript 文件,其中包含作为类型和类的验证逻辑。我使用该规范文件来验证我的测试。因此,它成为验证规范。该规范文件是其他实现必须用作事实来源的主规范。

该项目目前的状况如何?

正如我现在所写的,我觉得对于大多数用例来说它的功能基本上是完整的。有一些功能需要更多的研究,例如元模型中的枚举、二进制类型支持和不可空属性支持。

然而,我真正需要的是反馈。我知道对于某些人来说,进行 json 替换完全是无稽之谈,而 typescript 闻起来就像放屁。但是那些真正认为 cbot 可以解决用例的人,我想知道它的表现如何,哪些支持被认为是重要的。

本质上,下一步只是获得一些建设性的反馈,以确保协议能够稳定到第一个实际版本。

链接

联系方式:sisujs@sisujs.figit:https://gitlab.com/sisujs/sisujs/

存储库

npm:https://www.npmjs.com/package/@sisujs/meta-cbotmvn:https://mvnrepository.com/artifact/fi.sisujs/cbot

文档

typescript 教程:https://gitlab.com/sisujs/sisujs/-/blob/main/docs/cbot/tutorial_ts.mdjava 教程:https://gitlab.com/sisujs/sisujs/-/blob/main/docs/cbot/tutorial_java.md类型文档:https://gitlab.com/sisujs/sisujs/-/blob/main/js/meta-cbot/typedoc/readme.mdjavadoc:https://www.javadoc.io/doc/fi.sisujs/cbot/latest/index.html

以上就是摆脱 JSON:Web 开发中数据传输的新方法的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1493186.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
使用 Github 页面部署 React Nextjs 应用程序的步骤
上一篇 2025年12月19日 15:28:32
优化代码性能最佳实践
下一篇 2025年12月19日 15:28:41

相关推荐

  • 开源免费PHP工具 PHP开发效率提升利器

    推荐开源免费PHP开发工具以提升效率:VS Code、Sublime Text轻量高效,PhpStorm专业强大;调试用Xdebug、Kint、Ray;依赖管理选Composer;代码质量工具包括PHPStan、Psalm、PHP_CodeSniffer;数据库管理可用%ignore_a_1%MyA…

    2026年5月10日
    000
  • 谷歌浏览器如何截图 谷歌浏览器页面截图技巧

    谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧谷歌浏览器如何截图 谷歌浏览器页面截图技巧

    使用谷歌浏览器的开发者工具截图步骤:1. 按ctrl+shift+i(windows/linux)或cmd+option+i(mac)打开开发者工具。2. 点击右上角三个点,选择”更多工具”,再选择”截图”。3. 选择截取整个页面。推荐的谷歌浏览器扩展…

    2026年5月10日 用户投稿
    100
  • JavaScript计算器开发:解决数值显示与初始化问题

    本教程深入探讨了使用JavaScript构建计算器时常见的数值显示异常问题,特别是由于类属性未初始化导致的`Cannot read properties of undefined`错误。我们将详细分析问题根源,并通过在构造函数中调用初始化方法来解决该问题,同时优化显示逻辑,确保计算器功能稳定且界面显…

    2026年5月10日
    000
  • NextAuth getToken 在服务端返回 null 的问题排查与解决

    问题描述 在使用 Next.js 和 NextAuth 构建应用程序时,有时需要在服务端获取用户的身份验证信息。getToken 函数是 NextAuth 提供的一个便捷方法,用于从请求中提取 JWT (JSON Web Token)。然而,在某些情况下,尤其是在使用 getServerSidePr…

    2026年5月10日
    000
  • HTML文档如何工作?如何编辑HTML格式文件?

    HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?HTML文档如何工作?如何编辑HTML格式文件?

    浏览器解析和渲染html的过程包括:1. 解析html构建dom树;2. 结合css构建渲染树;3. 布局计算元素位置;4. 绘制像素到屏幕。编辑html可使用记事本、vs code、sublime text等文本或代码编辑器,其中vs code因语法高亮、自动补全和插件生态成为主流选择。标准htm…

    2026年5月10日 用户投稿
    100
  • GolangWeb项目异常捕获与日志记录

    答案:通过中间件使用defer和recover捕获panic,结合zap等结构化日志库记录请求链路信息,为每个请求生成trace ID,实现异常捕获与可追踪日志,提升系统稳定性与可观测性。 在Go语言Web项目中,异常捕获与日志记录是保障系统稳定性和可维护性的关键环节。Go本身没有像其他语言那样的t…

    2026年5月10日
    100
  • Python官网用户调查的参与方式_Python官网反馈提交详细教程

    答案是通过访问Python官网新闻页面、邮件邀请链接或GitHub仓库提交反馈。具体为:访问官网查找用户调查公告,或点击邮件中的专属链接参与,在GitHub的cpython仓库提交技术建议,并注意如实填写问卷与保护隐私。 如果您希望参与Python官网的用户调查并提交反馈,可以通过官方指定的渠道完成…

    2026年5月10日
    300
  • Go语言连接外部MySQL数据库:DSN配置与常见错误解析

    本文详细阐述了go语言使用`go-sql-driver/mysql`驱动连接外部mysql数据库的正确方法。重点介绍了数据源名称(dsn)的规范格式,特别是主机地址部分的配置,以避免常见的“getaddrinfow: the specified class was not found.”等网络解析错…

    2026年5月10日
    000
  • Tensorflow 音乐预测

    在本文中,我展示了如何使用张量流来预测音乐风格。在我的示例中,我比较了电子音乐和古典音乐。 你可以在我的github上找到代码:https://github.com/victordalet/sound_to_partition i – 数据集 第一步,您需要创建一个数据集文件夹,并在里面…

    2026年5月10日
    000
  • JS注解怎么和TypeScript结合_ JS注解在TypeScript环境下的应用

    TypeScript 支持通过配置 allowJs 和 checkJs 在 JavaScript 文件中识别 JSDoc 注解并进行类型检查,可在混合项目中提升类型安全;常见用法包括 @type、@param、@returns 和 @typedef,能为变量、函数参数等提供类型信息,支持与 .ts …

    2026年5月10日
    000
  • 学习了Python的Flask后,Go语言的Web框架该选Gin还是Beego?

    学习编程时,选择合适的框架至关重要。许多开发者在掌握Python Flask后,转向Go语言Web开发时,常常在Gin和Beego之间难以抉择。本文将深入分析,助您做出明智选择。 虽然网上搜索结果多建议使用Go原生标准库http,但实际上所有框架都是对http的封装。虽然使用http开发灵活,但工作…

    2026年5月10日
    000
  • JavaScript动态下拉菜单:实现日期选项与价格计算关联

    在现代web应用中,动态生成表单元素并使其具备交互逻辑是常见的需求。特别是在需要根据用户选择调整价格或服务参数的场景下,下拉菜单()常被用来展示一系列选项。本教程将指导您如何利用javascript动态生成一个包含日期选项的下拉菜单,并为每个选项关联一个具体的数值(如剩余天数),进而实现一个基于用户…

    2026年5月10日
    000
  • 如何在不暴露密钥的情况下,在客户端创建 Stripe Payment Link

    本文介绍了在纯静态网站环境下,如何利用 Stripe Payment Link 实现商品售卖,并着重讨论了在不暴露 Stripe 密钥的前提下,客户端创建 Payment Link 的可行性。分析了直接在客户端使用密钥的风险,并提出了预先生成 Payment Link 或使用后端服务动态生成 Pay…

    2026年5月10日
    000
  • 解决Go语言中GOPATH未设置错误及工作区配置指南

    本文旨在解决go语言开发中常见的“gopath not set”错误,并提供详细的go工作区配置指南。内容涵盖`gopath`环境变量的设置、go项目目录结构、`path`变量的扩展,以及一些高级配置技巧,旨在帮助开发者建立一个高效、规范的go开发环境,确保包的下载、编译和运行顺利进行。 Go语言在…

    2026年5月10日
    000
  • 掌握 JavaScript 中的高阶函数

    现代 javascript 开发严重依赖函数式编程,掌握其基本思想将极大提高你的编码能力。 高阶函数是这个范式最有力的武器之一。为了帮助您掌握它们,本文将介绍它们的定义、应用程序和独特的实现。 1. 函数式编程 函数式编程是一种编程范式,强调: 纯函数:没有副作用的函数,对于相同的输入返回相同的输出…

    2026年5月10日
    000
  • TypeScript函数体中如何高效判断参数类型?

    typescript 函数体中判断参数类型的技巧 typescript 中,我们可以定义接口来表示不同的数据类型。在本文中,我们将探讨如何在函数体中判断参数的类型,从而实现类型收窄,进行更精细的类型检查。 使用谓词函数 一种方法是编写谓词函数来手动检查类型。谓词函数返回的是 value is som…

    2026年5月10日
    000
  • Golang使用assert库简化测试断言

    使用testify/assert库可提升Go测试代码的可读性和效率,通过go get github.com/stretchr/testify/assert安装后导入包,用assert.Equal等函数替代冗长的手动判断,支持丰富断言方法如Equal、True、Nil、Contains等,并可添加自定…

    2026年5月10日
    100
  • 如何处理在线编辑HTML时外部链接验证的处理方法

    在线编辑HTML时需验证外部链接以保障安全与可用性,可通过自动检测标记外链并添加rel属性提升安全性;2. 实时验证链接有效性,利用HEAD请求检查状态码并在编辑界面提示结果;3. 配置可信域名白名单控制高风险链接输入,适用于合规要求高的场景;4. 提供友好反馈机制,对无效或可疑链接弹出提示并支持新…

    2026年5月10日
    000
  • 怎样为C++配置嵌入式AI开发环境 TensorFlow Lite Micro移植指南

    怎样为C++配置嵌入式AI开发环境 TensorFlow Lite Micro移植指南怎样为C++配置嵌入式AI开发环境 TensorFlow Lite Micro移植指南怎样为C++配置嵌入式AI开发环境 TensorFlow Lite Micro移植指南怎样为C++配置嵌入式AI开发环境 TensorFlow Lite Micro移植指南

    要在c++++项目中使用tensorflow lite micro进行嵌入式ai开发,关键步骤包括:1. 确定mcu平台并安装对应的交叉编译工具链;2. 配置python环境并安装必要的依赖包;3. 获取并裁剪tflm源码,保留核心模块;4. 将tflm静态库集成到c++工程中;5. 按照模型加载、…

    2026年5月10日 用户投稿
    000
  • JS如何实现策略模式

    策略模式通过封装算法使其可互换,JavaScript中利用函数作为一等公民实现,适用于表单验证等场景,结合工厂模式提升灵活性,但应避免过度设计。 策略模式的核心在于定义一系列算法,并将每一个算法封装起来,使它们可以相互替换。这使得算法可以在不影响客户端的情况下发生变化。在JS中,这可以通过函数作为一…

    2026年5月10日
    000

发表回复

登录后才能评论
关注微信