在Ruby和Rails开发人员中,面向服务的架构作为缓解程序大小增长的强大方法享有当之无愧的声誉。在广泛的应用程序中提取关注点。这些新生的小服务通常继续使用Rails或Sinatra,并使用JSON通过HTTP进行通信。尽管JSON作为一种数据交换格式有很多优点:它是人类可读的、可理解的,并且通常表现良好。浏览器和JS不直接处理数据——尤其是涉及到内部服务时。我的观点是,就编码而言,结构化格式(例如Google的ProtocolBuffers)是比JSON更好的选择。如果您从未使用过ProtocolBuffers,可以参考这里。别担心,在解释为什么应该选择ProtocolBuffers而不是JSON之前,本文将介绍如何将它与Ruby一起使用。ProtocolBuffers简介首先,什么是ProtocolBuffers?该文件称:“ProtocolBuffers是一种以高效且可扩展的格式对结构化数据进行编码的方法。”Google为内部服务开发了ProtocolBuffers。它是一种二进制格式,允许您使用规范语言定义模式,例如:messagePerson{requiredint32id=1;要求的字符串名称=2;可选字符串电子邮件=3;您可以将它们封装在命名空间中或像上面那样在顶层声明它们。此代码段定义了Person数据类型的架构,包含三个字段:id、name和email。除了命名字段之外,您还可以提供一种类型来确定数据的编码方式和在线发送方式。上面我们看到有int32和string类型。还提供了用于验证和结构化的关键字(必需和可选)。字段已编号,这有助于向后兼容,稍后我将对此进行更详细的介绍。ProtocolBuffers规范已经用多种语言实现:Java、C、Go等。如果你四处寻找,大多数现代语言都有办法做到这一点。Ruby也不例外,有几种不同的gem使用ProtocolBuffers编码和解码数据。这意味着该规范可以在以不同语言实现的系统之间传输数据。例如,RubyGem安装了一个名为ruby??-protoc的二进制文件,它可以与主要的ProtocolBuffers库(OSX上的brewinstallprotobuf)结合使用,自动生成用于编码和解码数据的存根文件。运行的二进制原型文件生成以下Ruby类:#!/usr/bin/envruby#Generatedbytheprotocolbuffercompiler.DONOTEDIT!require'protocol_buffers'#forwarddeclarationsclassPerson<::ProtocolBuffers::Message;endclassPerson<::ProtocolBuffers::Messageset_fully_qualified_name“Person”需要:int32,:id,1需要:string,:name,2可选:string,:email,3end可以看到,通过支持这种模式(ProtocolBuffer格式),它是用来对信息进行编码和解码的,我们可以自动得到一个类(详见Gem中ProtocolBuffers::Message的基类)。我们已经看到了一些信息,所以让我们仔细看看这些特性,让我试着说服你考虑ProtocolBuffers——这里有5个原因。原因#1:模式本身很好。有一个痛苦的讽刺指向我们小心翼翼地在我们的数据库中编写数据模型,维护代码层,并在我们要发送数据到另一个服务时将这些数据模型置于控制之下当数据连接到另一个服务时,所有的疑问都需要被经过考虑的。但是,我们经常依赖于边界处系统之间不一致的代码。我们的系统无法强制执行数据组件的结构。这非常重要。编码的语义是你曾经拥有的业务对象。在proto格式中,它足以帮助并确保应用程序之间的信号不丢失,边界是您创建和执行的业务规则。原因#2:无偿的向后兼容性编号字段排除了原型定义中所需的版本检查,这是规定的动机之一(为什么协议缓冲区以这种方式设计和实现)。正如开发者文档中所述,该协议旨在一定程度上避免像下面这样的“丑陋代码”。以下代码用于检测协议的版本:if(version==3){...}elseif(version>4){if(version==5){...}...}同上数字字段,你必须改变你的编码习惯,使其可维护并向后兼容旧版本。如文档中所述,一旦ProtocolBuffers被引入是这样的:“可以轻松引入和解析新字段,而无需中间服务来检查数据,无需了解所有字段即可传递数据。”部署各种JSON的服务器已经遇到了与开发模式和向后兼容性相关的各种问题。我现在相信数字字段可以防止错误并简化新功能和服务的推出。原因#3:更少的样板代码除了明确的版本检查和缺乏后续兼容性之外,基于HTTP的JSON端点的底层服务通常依赖于专门的手写样板代码来处理编码和解码Ruby对象。解析类和反解析类通常包含隐藏的业务逻辑,这暴露了手动解析每种新数据类型的缺陷。当一个类通过ProtocolBuffers生成时(你一般不会再去碰它),它可以提供很多类似的方法,也避免了很多令人头疼的事情。随着模式的发展,您将使用proto生成类(诚然,一旦您更新它们),您可以为您关注的挑战留出更多空间(保持您的应用程序运行并继续构建产品)。理由#4:验证和可扩展性ProtocolBuffers中定义的required、optional和repeated关键字非常强大。它们允许您在模式级别进行编码以可视化您的数据结构并实现类工作方式的细节(每种编程语言都处理)。Ruby的protocol_buffers库会引发异常,例如如果对象实例没有填写必填字段,而您尝试对这样的对象实例进行编码,则会引发异常。您可以通过简单地编辑新编号字段的值来将字段从必填更改为可选,反之亦然。有了这种灵活的编码语义序列化格式,它的能力得到了极大的增强。因为还可以嵌入proto,定义其他内部成员,也可以有一个通用的Request和Response结构,同样允许其他数据结构的传输,并保证传输是连通的,实现了真正的服务器间的灵活性和安全性通信数据传输提供了机会。像Riak这样的数据库系统使用ProtocolBuffers产生了很大的效果——因为一些启示,我建议重新访问这些接口。理由#5:提议的语言互操作性因为ProtocolBuffers已经以多种语言实现,所以在您的架构中混合多种语言的应用程序之间的互操作性变得更加容易。如果你用Java或Go引入一个新的服务,甚至与一个用Node或Clojure或Scala实现的后端通信,你只需将proto文件传递??给用目标语言编写的代码生成器,你将获得更好的安全性和架构间的互操作性.特定于平台的数据类型的细节由目标语言处理,与JSON编码和解码方案中的匹配字段和数据类型相比,您将更多地关注问题的难点部分。什么时候JSON更好?有时JSON优于ProtocolBuffers,包括以下场景:您需要或希望数据是人类可读的来自服务的数据直接发送到Web浏览器您的服务器端应用程序该程序是用javaScript编写的您'您不会将数据模型绑定到模式您没有带宽来向您的武器库添加另一个工具运行不同类型的Web服务的操作负担太多,而且可能更多。***总之,重要的是权衡利弊,不要盲目选择技术。ProtocolBuffers并没有完全取代JSON,尤其是在服务直接与Web浏览器通信的情况下,它不仅在上述方法中提供了真正的优势,而且在编码和解码速度以及数据大小方面也具有真正的优势。您可以从您的应用程序中提取哪些服务?如果今天让你选择,你会选择JSON还是ProtocolBuffers?让我们来讨论一下——我们很乐意在下面的评论中听到更多关于您使用JSON和ProtocolBuffers的经验。英文原文:5ReasonstoUseProtocolBuffersInsteadofJSONForYourNextService翻译链接:http://www.oschina.net/translate/choose-protocol-buffers
