Rails快速JSON序列化历险记

在正在进行的系列文章中,我想称为“作为Turing学生做事”,我想讨论从API创建JSON输出的问题。 等等,让我从头开始…。

首先,让我们定义一些术语:API是应用程序编程接口。 API本质上是在Internet上运行的数据库接口。 另一种查看方式是其他计算机程序的网站。 计算机不在乎事物的“外观”。 屏幕是什么颜色,或者数据在屏幕上整洁的可单击框内对齐都没有关系。 计算机只是想要他们正在寻找的数据,因此无论用户告诉他们做什么,他们都可以做到。 API遍布Internet,使开发人员可以访问大量且不断增长的数据,以供操作。 API一词具有出色的Google功能-您可以通过简单的搜索学习所有想要的内容以及更多内容。

现在,我说计算机不在乎外观如何—从技术上讲是正确的,但存在相应的问题。 可以使用Internet上可访问的数据,但是如何格式化这些数据以供其他计算机程序使用对我们人类来说是一样重要的事情。 是否应将匹配的数据显示为键:=>:value,“键” —“值”或任何其他表示它的方式? 数据库使用ID来唯一标识记录-这些记录是否应随数据一起传输,如果应该,则应首先传输还是最后传输? 所有这些都是API开发人员必须做出的决定。

这导致了“骑自行车”的问题。 “循环淘汰”是一个开发人员术语,表示“浪费时间在琐碎的细节上,而重要事项没有得到充分处理。”呈现API数据的格式并不像数据本身那么重要。 不过,这很重要。 截至2017年,已有超过17,000个公共API(1)。 想象一下,如果所有人都以独特的格式显示数据! 将会浪费成千上万的工时,这可以通过提供可靠的API数据显示标准来避免。

标准化API的尝试进展缓慢。 实际上,在2000年之前,根本没有关于如何设计或使用API​​的真正标准(2)。 由于进行了各种努力,包括将JSON的实现作为API传输数据的标准格式。 直到2015年,才有一致的尝试来标准化JSON数据API send(3)。 从我作为新程序员的角度来看,结论是:现在是开始在“生产者”和“消费者”方面进行API编程的好时机。

在深入探讨之前,让我们定义另一个术语:序列化。 Rails编程中的序列化是对格式化API的JSON输出的引用,以便每个记录都是唯一的,并带有所需的数据。 已经进行了一些尝试来标准化Rails JSON输出,并使用相应的Ruby gem来完成这项工作。 最常见的称为“活动模型”串行器。 但是有趣的是,其中大多数已经失宠了(随后它们的发展枯竭了)。 主要原因是速度。 他们将原始数据转换为格式化JSON所花费的速度太高了。 因此,Netflix来了……

Netflix JSON序列化器简称为“快速JSON API”。它根据新的JSON 1.0标准显示数据。 但这也是FAST。 根据其自己的GitHub帖子,“在当前1000条记录的基准测试上,序列化时间比Active Model序列化程序至少快25倍。”(4)我们不确定这是否完全正确(我个人怀疑这有些痛苦)取得胜利-他们的测试很可能是为了看到他们的出色表现而进行的),但它可能比其他任何东西都要快。 图灵决定开始使用它,可能是因为他们可以看到它将要接管的“墙上的文字”。

使用串行器一点都不难。 它实际上只涉及三件事:安装/包括gem,创建序列化器,然后在适当的控制器操作中调用该序列化器。 您甚至可以通过“ rails generate”命令访问自动生成序列化程序的权限。 实际上,这一切都非常扎实! 要开始使用,请转到https://github.com/Netflix/fast_jsonapi并按照非常简单的说明进行操作。

一个谨慎的世界:Netflix序列化器是自以为是的。 假设您从事传输记录的工作并且记录具有关联的ID,则需要使用:id才能起作用。 如果您最终尝试显示原始数据(例如仅是日期或美元金额),则可能会遇到一些麻烦。 实际上,我们的任务之一是求和给定一天的总收入,而该总收入没有任何特定的ID相关联-数据是通过一系列交易和许多项目的成本汇总而成的。 将这些数据送入序列化器的“常规”途径是创建一个普通的旧Ruby对象(PO​​RO)并添加新数据,这需要创建一个新的模型类和相关的测试。 每次您只想吐出一些数据时,所有这些似乎都很麻烦。 为了避免所有这些,我发现了一个很酷的技巧:Ruby OpenStruct(5)的使用。

在Ruby中,OpenStruct本质上是使用所需属性随时随地创建的对象。 使用“ OpenStruct.new”并为其分配属性,就像使用哈希和中提琴一样,即拥有一个具有这些属性的对象。 使用Netflix序列化程序时,这非常方便,因为它需要ID。 策略是这样的:如果您要呈现相关对象所没有的自定义数据,或者实际上并没有真正与数据库对象相关联的数据,请使用OpenStruct创建一个临时对象以呈现给Netflix。序列化器。 您可以使用它传递所需的任何数据,并且它将自动格式化为JSON 1.0标准。

在这种情况下,我使用了一个新的数据点(收入),因此我需要创建一个自定义的序列化器,但是在其他情况下,您可以只使用已有的序列化器。 总的来说,我发现使用OpenStruct函数确实非常灵活和有用。 我可能会学习将对象数据呈现给序列化程序的其他(也许更好)的方法,但是我很高兴有此选项可用。 除此之外,创建一个伪造的对象也很有趣! (我今晚可能已经编码太长时间了。)

我很期待看到我还能用API做些什么,所以很快就会有更多帖子……。

(1)https://www.programmableweb.com/news/programmableweb-api-directory-eclipses-17000-api-economy-continues-surge/research/2017/03/13

(2)https://www.mobapi.com/history-of-rest-apis/

(3)https://jsonapi.org/about/

(4)https://github.com/Netflix/fast_jsonapi

(5)https://ruby-doc.org/stdlib-2.4.1/libdoc/ostruct/rdoc/OpenStruct.html