【问题标题】:Building a custom API--needing a logic check构建自定义 API——需要逻辑检查
【发布时间】:2011-01-21 05:21:15
【问题描述】:

我正处于为大型应用程序编写我的第一个成熟 API 的规划和早期编码阶段。这些年来我使用了多个 API,但这是我第一次被要求构建允许在这个级别进行编程交互的东西。

我进行了大量研究以寻找最佳实践等,并确定了我认为将提供相当灵活的响应通信系统的内容。

我的问题是:

这是您期望看到的 API 交互吗?

我错过了什么重要的事情吗?

API 说明:

我将使用 HTTP Type 1 协议进行通信,并使用唯一的 API 密钥进行身份验证。

我希望这是通过 SSL 连接通过 CURL 请求实现的。

成功 (200 OK) XML 响应示例(速率限制请求):

<?xml version="1.0" encoding="UTF-8"?>
<node>
    <short_message>Request Complete</short_message>
    <long_message>Rate Limit Status Response</long_message>
    <response_data>
        <rate_limit>40</rate_limit>
        <rate_used>31</rate_used>
    </response_data>
</node>

失败的 XML 响应示例(将在适当的 400/500 标头下发送);

<?xml version="1.0" encoding="UTF-8"?>
<node>
    <error_code>1201</error_code>
    <short_message>API Error</short_message>
    <long_message>The requested API version (1.5) is invalid</long_message> 
</node>

此外,我正在设置要在可搜索文档中使用的错误代码,以缓解其他开发人员的偏头痛。请求的通过/失败将通过适当的 HTTP 代码给出——成功(200)、错误请求(400)、未找到方法(404)、身份验证失败(403)等......

我还使用基于版本的端点,因此任何代码更改都不需要外部代码更改。

最终,开发人员将能够请求 XML、JSON 或 PHP 序列化数组中的所有响应。

我的代码内部非常简单。所有数据都通过 POST(可能使用 CURL 或其他替代方法)传递,包括唯一的 API 密钥。该 API 密钥与系统中的用户相关联,然后允许内部方法执行为该特定用户启用的有限功能集。

我遵循 API 的“黄金法则”——“始终添加,永不删除”。

那么.. 我还应该考虑什么以及我错过了什么?

【问题讨论】:

    标签: php xml api


    【解决方案1】:

    关于“单一 URL/端点”的想法 - 请记住,使用 Apache,您可以通过 URL 重写规则从单个脚本提供无限数量的 URL。这意味着通过在“端点”脚本目录中正确定义的 .htaccess 文件,您可以让 Web 服务器自动“映射”传入请求,例如:

    /foo/slice/1234 => /foo/?action=slice&oid=1234 /foo/dice/3456 => /foo/?action=dice&oid=3456 /foo/chop/4567 => /foo/?action=chop&oid=4567

    如果您最终决定要提供“RESTful” URL(并且可以使用 HTTP 请求模式 GET、POST、PUT、DELETE、HEAD),这将非常有用。

    【讨论】:

      【解决方案2】:

      如果您真的在构建 REST 服务,请考虑以下几点:

      • request_status,应该放弃使用 html 响应代码(至少 200:OK,400:Bad Request,401:Unauthorized,403:Forbidden 和 500:Internal Error),response_code 可能需要在您的文档中找到问题的解释。
      • 您想提供不同的格式,响应的格式不应该依赖于 url 而应该依赖于Accept header

      【讨论】:

      • @mathroc - (+1) 很好,我见过几个类似的 cmets,所以我将放弃 response_status 来代替 HTTP 响应代码
      【解决方案3】:

      肖恩,

      我假设您的目标是构建一个 RESTful API - 这是真的吗?

      我的回答只有在这个假设成立时才适用——我并不是要批评你的设计,只是批评它的 RESTful。

      REST 定义了 4 个接口约束,您的设计必须遵守这些约束才能成为 RESTful。您的设计至少违反了其中三个,因此不是 RESTful。这本身不一定是坏事,但重要的是您要了解您的系统可能不具备您期望的属性。

      我将尝试从下面的简短答案开始,但请查看http://nordsc.com/ext/classification_of_http_based_apis.html,我会在其中进一步讨论此问题。然后,您可以将所有这些分解为更小的问题,然后返回这里或访问 Yahoo 群组上的 rest-discuss:http://tech.groups.yahoo.com/group/rest-discuss/

      现在缩短您的设计:

      1. 您不应使用自己的响应代码,而只能使用 HTTP 提供的响应代码。您可以自己制作,但这些必须普遍适用,而不是特定于您的应用程序或交互。

      2. 您应该使用特定的媒体类型,而不仅仅是应用程序/xml。如果现有类型都不符合您的需求(或可以扩展为这样做),您可以开发自己的。事实上,主要的设计活动应该花在媒体类型上。这是您的域语义所在。

      3. 您必须遵守超媒体约束才能真正实现 RESTful。这意味着应向客户提供链接和/或表单,以了解其下一步可以做什么。

      使用上面引用的分类,您的 API 看起来像 基于 HTTP 的 I 型 (http://nordsc.com/ext/classification_of_http_based_apis.html#http-type-one),假设您没有在 URI 中放置操作,这将使其成为 RPC URI -隧道http://nordsc.com/ext/classification_of_http_based_apis.html#uri-rpc

      我希望这可以帮助您实现总体目标。

      一月

      【讨论】:

      • @Jan Algermissen- (+1) 哇,很好的答案——今晚我将完成所有这些链接。你是正确的,我倾向于你提到的基于 HTTP 的类型 I。我试图让开发人员尽可能地访问它,并认为这是最好的方法——将我的标签从 Restful 更改为其他东西。你觉得这比 REST 有什么缺点吗?我仍然会使用 POST over GET 来安全地获取数据。
      • 很高兴它有帮助。我显然是彻头彻尾地支持 REST,但我也明白学习曲线很高。我认为只要你知道系统的特性是什么,你就可以安全地做最符合要求的事情。因此,如果长期维护成本不是您的主要问题,您可能能够忍受紧密耦合。意识到这一点很重要。因此我的“表”是因为我觉得人们真的开始对这一切感到困惑 :-) 你的最后一句话我没听懂,你能重新措辞吗?
      • 我应该扩展一下!我计划对所有 API 调用使用 SINGLE url,而不是为每个方法/函数调用不同的 URL。因此,您可以为所有内容调用domain.com/api/execute,然后将所有必需的信息发布到该脚本。所需参数之一是要执行的方法。我希望这更有意义!另外,我希望这不是太不标准,它似乎会使开发更容易,而不是必须跟上多个脚本调用。
      • 对所有 API 调用使用单个 URL 会将您的架构简化为纯消息传递。这样做的一个影响是您失去了 HTTP 内置缓存。您也失去了所有可见性,因为您无法再正确使用 HTP 方法。基本上,您将 HTTP 视为传输协议,而不是应用程序协议(实际上是)。为了帮助理解:TCP 已经是一种传输协议——为什么还要在它之上再一层一层呢?无意侮辱你:如果你使用 HTTP,你真的不会做得更糟。我会做一些重新设计。
      • 另外:你打算做的是一个自制的 SOAP-over-HTP。 IOW,虽然您将受到该方法的所有负面影响,但您也将承担设计自己的(小)SOAP 的负担。建议:多挖掘一点,选择基于 HTTP 的 Type I (nordsc.com/ext/…)。学习曲线是合理的,但收益将是巨大的。 HTH。
      【解决方案4】:

      您是否考虑过使用版本化端点?他们可能需要您进行更多的规划和维护,但您的用户会喜欢在您每次决定更改参数/返回值时不必重写他们的代码。

      如果您想出一个弃用然后删除旧版本的计划,这应该不会太痛苦。

      【讨论】:

      • @jasonbar - 实际上,我忘了在我原来的帖子中提到这一点,但出于这个原因,我也在做基于版本的端点。谢谢!
      【解决方案5】:

      一些事情:

      1) 将响应头放在不同的地方——HTTP 头和 response_code——肯定会引起混淆。一些开发人员会在一个地方检查它,一些在另一个地方。如果您想使用该路由,请绝对确保 HTTP 标头和返回的 XML 之间的响应代码相同。

      2) 您的服务器不必在每次响应时都返回 API 版本。你在浪费电线上的比特。如果客户想要特定版本的 API,让他们在请求中发送它。您不必将其寄回给他们。

      3) 结合 response_code 和 request_status。看看 HTTP 是怎么做的:200-299 表示成功。 400-499 表示客户端是哑巴。 500-599 表示服务器搞砸了。

      【讨论】:

      • @Alex - 对版本号的好调用——我相信我不久前在另一个 API 中看到了这个并认为这是一个好主意,但认为这是多余的。此外,我将使用 HTTP 代码而不是 SUCCESS/FAILURE,但我会保留错误代码以帮助编写 API 文档。
      【解决方案6】:

      您可以用作示例的最佳 API 是您编码的 API。使用相同的命名约定和大小写。

      另外,尝试使用您的 API 构建示例应用程序,您会很快发现它的缺点。

      【讨论】:

        【解决方案7】:

        XML 看起来不错。 但是要说更多关于内部逻辑的信息,我们需要更多的细节,而不仅仅是 XML。

        【讨论】:

        • @streetparade - 我现在要进行一些调整并稍微扩展问题。谢谢!
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2014-07-08
        • 1970-01-01
        • 2011-04-21
        • 2021-05-15
        • 1970-01-01
        • 1970-01-01
        • 2021-06-28
        相关资源
        最近更新 更多