为什么要在 JSON 响应中使用类型

Why to use types in JSON responses

提问人:Marian Ban 提问时间:3/2/2016 最后编辑:S MMarian Ban 更新时间:3/2/2016 访问量:161

问:

我正在开发一个应用程序的前端,该应用程序与后端思想 REST API 进行通信。后端是某种独立的设备,而不是标准的 Web 服务器,因此它没有那么强大(但可以运行 php)。该 API 非常通用,并返回类似键值对的值,例如

[{ key: "key1", value: "some value" }, { key: "key2", value: "1234" }]

我面临的问题是它不考虑类型,它返回所有内容,例如带引号的字符串(数字:“123”,布尔值:“1”)。最近我要求进行更改(我的论点是手动类型转换是不必要的工作,必须由每个客户端应用程序完成,如果服务器可以做到,则可以避免),但我需要一些更有说服力的论据。对我的要求的一些反驳是:

  1. RESTful 通信本身是一个字符串(所以无论如何,如果 传输 1 或“1”——客户端类型转换必须 完成)
  2. GUI 设计人员有责任了解每个参数的上下文
  3. 后端遵循 KISS 原则,将所有内容都保留为字符串,不需要在后端进行额外的处理,并且可以在 GUI 上完成,这通常是在功能更强大的 PC 上

那么,有什么好的论据可以说服我的同事,JSON响应中的类型对我和他们来说都是一件好事呢?

谢谢

JavaScript JSON REST 客户端

评论

0赞 deceze 3/2/2016
井。。。他们已经在区分数组、对象和字符串了......有人在某个地方关心类型。您可以将所有内容都作为逗号分隔的字符串发送,但你猜怎么着......如果你使用正确的类型,那就更容易了......

答:

3赞 Walfrat 3/2/2016 #1

RESTful 通信和 JSON 是两个不同的东西。JSON只是数据的格式,它可以是XML,甚至是CSV或自定义格式,这不会删除RESTful方面。

JSON几乎由所有处理服务器通信的javascript库原生处理,无需解析,几乎没有转换(可能是时间戳中的日期对象和其他类型的东西)。

在服务器端,也有很多库可以为您处理 JSON,以及它们如何生成键值?具有内省功能的通用代码,还是它们为所有类编写了大量序列化程序?这可能会导致编写和测试大量技术和不必要的代码。

KISS并不是要让它完全愚蠢,什么都不去想。让布尔值在字符串中有一个数字,而数字作为字符串作为开发者并不简单,它只是处理所有对象转换的地狱。如果您需要检查数据约束,这将导致您必须验证每个字段(测试数字是否为数字,...)时重复

更简单的事情是不要编写自己的库,将所有库都转换为字符串,其性能可能不如专用库。这是为您完成这项工作的二手库。

如果你把所有的东西都写成类型化对象,你在后端的json反序列化器会为你做一部分验证,布尔值就是布尔值,数字就是数字,如果你有很多验证要做,这会导致更少的代码来执行所有的检查。

客户端我想有很多代码来处理所有这些键/值的东西并转换值。这会减慢开发速度,如果您执行单元测试,则会增加大量测试工作。

GUI 设计人员有责任了解每个参数的上下文

嗯,这是真的,但我觉得提供格式良好的数据是服务器的责任。强制执行格式将导致快速失败,这是一件好事。由于这种通用格式,他们从未遇到过任何生产问题吗?他们不会使用适当的 JSON。

我个人在服务器上的 JSON 代码是 Java 注释和一个自定义序列化程序,仅此而已。我想知道他们写了多少代码来序列化/反序列化和转换类型。

1赞 MarengoHue 3/2/2016 #2

First of all, the idea of using the following data format is kinda stupid and is basically the same as . [{ key: "key1", value: "some value" }, { key: "key2", value: "1234" }]{ "key1": "some value", "key2": "1234" }

In regards to the points, your colleagues made: 1. While this is indeed text-based transfer and conversion between the string representation of your object and an actual object has to be done, there would be no need to recursively walk the tree of key/value pairs if you were to transfer objects or other complex types as values.

Let's pretend that you have to transfer following piece of data:

{ "key1": { "x": 10, "y": 20 } }

if you were to encode inner object as string you would get something like this:

"{ \"key1\": \"{ \"x\": \"10\", \"y\": \"20\" }\" }"

If your value was converted to string, you'd have to call JSON.parse on the entire object first as well as on the object that was possibly stored as text inside that object, which requires recursive walking of the tree. On the other hand, when using native types (such as objects, numbers and arrays) as values you would achieve the same effect with just one call to JSON.parse (which would internally be recursive, but still better that managing it yourself).

Second point is valid but I feel like any service should return the data in ready-to-use form or at least as ready as it can be. Wouldn't it be stupid if your service gave you some piece of raw XML instead of parsed and prepared data? Same principle applies here.

I feel like your friends are just being lazy trying to cover their butts with KISS principle here. It is very likely that their server code has all the info it needs to encode the values in their proper types, which would be much harder to do on the client side. So their third point seems like a blatant 'we are too lazy so you have to do it' thing.

评论

0赞 Walfrat 3/2/2016
My guess is they're using only flattened object, meaning they are writing some code for this when no code would be necessary for native JSON
0赞 MarengoHue 3/2/2016
Still there is no need in reinventing the collection of key-value pairs when we already have a data type for it. And it's not like you have to do anything extra to support those data types.
0赞 Walfrat 3/2/2016
I know i'm just adding an argument for what you said : not handling deep object make them write more code, so more risks of having problems :)