sosfiw
sosfiw
发布于 3个月前

API应该支持哪些数据格式?

在考虑API的设计,实现和维护时,最重要的考虑因素之一是数据格式 - API如何处理数据生成和数据请求之间的交互。生成和操作之间的这条路径,通常是在服务器和客户机之间,是API生态系统的关键。

因此,API生态系统中支持的数据格式类型非常重要,也许是区分API有效且功能强大与未充分利用之间的依据。采用正确的格式使API 具有功能性和实用性

今天,我们概述了API通常处理的数据格式(JSON,XML,YAML等)。我们将逐步介绍每种格式之间的差异,并概述为什么某种格式可能比API的特定情况更好。

为什么数据格式支持很重要

API是连接 一些用户,服务和资源到其他用户,服务和资源之间的桥梁。这是API最具包容性的定义 - 无论API做什么,它如何做,或者为什么这样做,API都是两点之间的桥梁。然而,手头的问题是这座桥梁如何贯穿。API中的资源连接必须既对请求方可用,又易识别相关数据。

共同的行业格式

现在我们将概述各种数据格式类型。我们将把当时最常见的行业语言分为四大类:

  • 直接数据格式
  • Feed数据格式
  • 操作数据格式
  • 数据库数据格式

与许多分类一样,这些区别之间存在一定程度的重叠。然而,为了使这种对话更容易,这些语言将按其专业而不是广泛的目的支持进行分组。

直接数据格式

直接数据格式旨在直接在机器之间处理数据。这些语言通常被称为机器可读,因为它们往往是密集和紧凑的。这意味着它们非常适合机器集成或与其他API的操作。

当其他API或服务需要来自API 的数据流才能运行时,最好使用直接数据格式。此类别中最常见的三种格式是JSON,XML和YAML。

JSON

在处理客户端脚本时,JSON(JavaScript Object Notation)是一种很棒的格式,并且通常可以更快地与其他选项(如XML)相对应。在许多方面,它可能没有其他选择那么强大或广泛使用,但它支持许多功能,使其采用是一个强大的选择。

例如,JSON支持XML缺少的数字,字符串和布尔值之间的区别(如下面“年龄门”示例中所示); 然而,作为一种反驳,XML处理混合内容远比JSON好,特别是在需要详细表达的混合节点数组的情况下。

{
    "title": "Age Gate",
    "type": "object",
    "properties": {
        "firstName": {
            "type": "string"
        },
        "knownValue": {
            "type": "boolean"
        },
        "age": {
            "description": "Age in years",
            "type": "integer",
            "minimum": 18
        }
    },
    "required": ["firstName", "lastName"]
}

XML

XML(可扩展标记语言)同样具有一些很大的优点。虽然它几乎无处不在,拥有庞大的基础,但其最大的优势可能是它最大的弱点。这是最大的力量?它尽可能地抛出一切。它的主要负面?它尽可能地抛出一切。

虽然拥有您可能需要的所有工具在概念上是一个很大的好处,但它使XML变得繁重而且速度慢,而且对某些计算的处理效率已经很低(特别是在XML转换领域),开发人员经常会遇到选择更多功能与更慢的速度(XML)或更少的功能与更高的效率(JSON)。

下面是混合模式age-gate镜像和扩展先前JSON示例的功能的示例。

<xs:complextype name="lettertype" mixed="true">
  <xs:sequence>
    <xs:element name="usertype" type="xs:string"></xs:element>
    <xs:element name="userage" type="xs:positiveInteger"></xs:element>
    <xs:element name="regdate" type="xs:date"></xs:element>
  </xs:sequence>
</xs:complextype>

YAML

YAML(YAML不是标记语言)是“适用于所有编程语言的人类友好数据序列化标准。”其中JSON是轻量级的,具有稍微宽松的功能集,并且XML冗长但通常有点麻烦,YAML易于阅读轻巧。虽然它由于用于解析配置设置和关系查询而被归类为直接数据格式,但许多系统将其用作基本平面数据库。

下面是一个简单的age-gate实现,它在某些条件下调用服务器上的文件。

# failover url
url_403: /
#url_403: http://example.org/underage

# snippet definition
snippet_enter: /templates/verified.html.twig
snippet_exit:  /templates/underageexit.html.twig
snippet_403: /templates/validate.html.twig

# minimium age config
min_age: 18

# container variable
width: 300
height: 300

# container bg
overlay: '#ffffff'

从技术上讲,它是JSON的超集,YAML因其可读性,轻松揭示层次结构的能力以及极少量的内容而被许多人所接受。它还具有广泛的众所周知和理解的工具 - 例如,RAML是一种基于YAML的语言,用于描述API。YAML也广泛用于游戏服务器。

Feed数据格式

Feed数据格式是一个完全独立的野兽。虽然仍被视为以机器为中心,但Feed格式更多地与用户实用程序相关,而非机器可用性。这些格式旨在提醒用户注意代码库中的更改,对网页更改的警报以及对域和服务的各种修改的管理。此类别中的格式包括RSS,Atom和SUP。

Feed数据格式通常用于序列化来自各种服务器,站点或前端接口的更新,并提醒用户注意这些更改。这些更改可以自动导入和集成,标记为更新,也可以根据使用情况进行修改。

RSS

RSS 是最广泛的Feed数据格式。RSS已经成为WordPress和其他博客平台的“官方”提要方法。这是一种非常简单的格式,但尽管它很简单,但它仍然存在重大问题。RSS排除了格式良好的XML标记,仅支持纯文本和转义HTML,并且缺乏对许多字段的支持,这些字段可以使其成为比目前更强大的系统。

Atom

另一方面,Atom旨在纠正这些问题。Atom是从头开始构建的,支持自动发现和识别以及更复杂的标记和媒体,是RSS的升级。不幸的是,这种集成带来了成本。虽然更多的媒体和标记是一件好事,但它会使系统更容易通过恶意代码入侵,并且系统总体上更重,导致性能下降。

RSS和Atom的实现只是将这些URL及其相关资源绑定到API中的特定行为。此外,还有许多第三方API可以非常轻松地添加这些Feed。例如:Google Feed

<script src="https://www.google.com/jsapi" type="text/javascript"></script><script type="text/javascript">// <![CDATA[
    google.load("feeds", "1");

    function initialize() {
      var feed = new google.feeds.Feed("http://fastpshb.appspot.com/feed/1/fastpshb");
      feed.load(function(result) {
        if (!result.error) {
          var container = document.getElementById("feed");
          for (var i = 0; i < result.feed.entries.length; i++) {
            var entry = result.feed.entries[i];
            var div = document.createElement("div");
            div.appendChild(document.createTextNode(entry.title));
            container.appendChild(div);
          }
        }
      });
    }
    google.setOnLoadCallback(initialize);

// ]]>
</script>

SUP

SUP(简单更新协议)。虽然RSS和Atom都是最好的,但它比Atom更快,而且比RSS更冗长,它带有两种格式的负面效果。它比Atom更快,但支持更少的媒体格式。它比RSS更冗长,但不像Atom那样可扩展。这是一个很好的“中间道路”方法,但实际上是一个中等选择平均速度和实用性。

{ "updated_time": "2009-04-28T21:29:20Z",
  "since_time": "2009-04-28T21:24:19Z",
  "period": 300,
  "available_periods": {
    "300": "http://gdata/youtube.com/sup?seconds=300",
    "600": "http://gdata/youtube.com/sup?seconds=600",
    "900": "http://gdata/youtube.com/sup?seconds=900"
  },
  "updates": [
    ["159aa827", "6e19"],
    ["9559d1d", "6e19"],
    ["159aa827", "6f22"],
    ....
  ]
}

操作数据格式

操纵数据格式应该被视为“包装”而不是“格式”。这些格式旨在由客户端计算机上的应用程序消化,而不是由服务器或服务消化。在这种情况下,包装器只是一个传递服务,而不是解析或转换服务。此类别中的格式包括PDFKML

包装器和格式之间的这种差异对于理解这种类型至关重要。操纵数据格式本质上是变革性的。发送PDF的人不会发送代码只是被机器消化,而是发送PDF由客户打开,签名,操作或通过扩展程序在浏览器中显示。

当然,这使得格式非常小众。如果API处理位置,尤其是地图服务上的地理位置,则必须支持KML。如果API处理文档的签名验证服务,则需要PDF支持。如果API从不处理这种数据,那么格式根本就没有用例。

数据库数据格式

最后,数据库数据格式是那些通常用于处理数据库与其他数据库或用户之间通信的格式,这是一种越来越常见的功能。直接数据格式根据请求形成数据并处理从服务到服务的数据,而数据库数据格式则生成数据并将其存档以供以后使用。此类别中的格式包括CSV和SQL。这个领域的支持与数据如何在本地存储以及您打算将哪些服务联系起来有关。

CSV

CSV(逗号分隔值)是一种非常常见的格式,尽管XML在很大程度上已经过时了。然而,它仍然有用,尤其是在MediaWiki平台的数据抓取环境中考虑时,处理从一种形式到另一种形式的数据转换。然而,它与SQL形成鲜明对比,因为它更常用于转换,而不是存储。

以下是CSV解析器的简单实现:

<?php
use League\Csv\Reader;

$csv = Reader::createFromPath('/path/to/your/csv/file.csv');

//get the first row, usually the CSV header
$headers = $csv->fetchOne();

//get 25 rows starting from the 11th row
$res = $csv->setOffset(10)->setLimit(25)->fetchAll();

SQL

存储数据通常由SQL格式处理,主要是由于文件和关系结构,以及SQL的广泛采用和相关的MySQL实现。

[code.google.com php-sql-parser implementation page](http://code.google.com/p/php-sql-parser/) 中的这段代码精彩的展示了SQL如何轻松地集成到PHP系统中:

Array
(
    [OPTIONS] => Array
        (
            [0] => STRAIGHT_JOIN
        )      

    [SELECT] => Array
        (
            [0] => Array
                (
                    [expr_type] => colref
                    [base_expr] => a
                    [sub_tree] =>
                    [alias] => `a`
                )

            [1] => Array
                (
                    [expr_type] => colref
                    [base_expr] => b
                    [sub_tree] =>
                    [alias] => `b`
                )

            [2] => Array
                (
                    [expr_type] => colref
                    [base_expr] => c
                    [sub_tree] =>
                    [alias] => `c`
                )

        )

    [FROM] => Array
        (
            [0] => Array
                (
                    [table] => some_table
                    [alias] => an_alias
                    [join_type] => JOIN
                    [ref_type] =>
                    [ref_clause] =>
                    [base_expr] =>
                    [sub_tree] =>
                )

        )

    [WHERE] => Array
        (
            [0] => Array
                (
                    [expr_type] => colref
                    [base_expr] => d
                    [sub_tree] =>
                )

            [1] => Array
                (
                    [expr_type] => operator
                    [base_expr] => >
                    [sub_tree] =>
                )

            [2] => Array
                (
                    [expr_type] => const
                    [base_expr] => 5
                    [sub_tree] =>
                )

        )
)

当处理多个彼此说话的数据库时,SQL是首选格式,因为SQL用于组织数据和处理该数据之间的调用。当使用需要翻译成另一种格式的YAML之类的处理单个数据库或平面数据库文件时,CSV是首选格式。

超媒体如何影响API?

自从万维网广泛采用以来,数据已经越来越远离静态的描述性内容,转向操纵的交互式数据,称为超媒体。“超文本”的扩展,超媒体将对象,视频,音乐和其他媒体链接到其他此类来源。

“媒体”和“超媒体”之间存在着严格的界限。媒体只是文本,图形,音频或视频的集合,而超媒体则是与这些其他媒体格式相互作用的结合。因此,格式必须改变以支持这场革命。因此,编解码器处理,文件格式,标记,面向对象,数据库处理等等变得非常重要。

在我们讨论数据格式时,请记住这一点 - 虽然数据格式非常重要,但它们的使用方式与您打算处理的媒体类型有很大关系,以及它是否属于超媒体。您的API可能会像梦一样处理视频数据,但如果没有RSS提要来通知用户新内容,您可能也没有受众。

结论

数据格式支持与其独特的特定用例有关。虽然理论上您可以花费整个开发预算来扩展API的格式支持和转换,以便支持任何事情以及所引发的所有内容,但最终会得到一个膨胀的API,需要更多的支持以及更大的失败机会。但是,如果你画得太难,并且只支持一种或两种格式,以及那种罕见的格式,你就有可能变得敏捷和精益但最终无用。

因此,必须提出的问题归结为这样 - “任何人都可以合理地期望这种格式在使用API​​吗?”如果您要使用自己的API,您是否期望支持您正在考虑的格式?如果是这样,实施它!如果没有,请考虑是否有更好的选择,并支持!

简单地理解每种格式的作用对于您是否想要支持它有很大帮助。综上所述:

  • 直接数据格式(JSON,XML,YAML):支持直接共享数据以供在其他系统中使用的格式,最适用于B2B或面向公众的API实现
  • Feed数据格式(RSS,Atom,SUP):序列化更改并将用户更新为这些更改的格式最适用于订阅行业,如博客,视频共享和社交媒体
  • 操作数据格式(KML,PDF):数据被包装以便以文档形式共享的格式,最适用于设计和通信行业
  • 数据库数据格式(CSV,SQL):数据被分类并以数据库格式存储以供解释的格式,最好用于分析依赖或长期数据。
API