首页 > 其他分享 >RESTful API 设计最佳实践

RESTful API 设计最佳实践

时间:2024-03-27 15:48:17浏览次数:30  
标签:tickets 12 06 最佳 API ticket RESTful 资源

数据模型已经稳定,接下来你可能需要为web(网站)应用创建一个公开的API(应用程序编程接口)。需要认识到这样一个问题:一旦API发布后,就很难对它做很大的改动并且保持像先前一样的正确性。现在,网络上有很多关于API设计的思路。但是在全部案例中没有一种被广泛采纳的标准,有很多的选择:你接受什么样的格式?如何认证?API应该被版本化吗?

在为SupportFu(一个轻量级的Zendesk替换实现)设计API时,对于这些问题我尽量得出一些务实的答案。我的目标是设计这样一个API,它容易使用和采纳,足够灵活去为我们用户接口去埋单。

 

out_lier out_lier 翻译于 2013/06/06 20:04  顶 3      

API的关键要求

许多网上能找到的API设计观点都是些学术讨论,这些讨论是关于模糊标准的主观解释,而不是关于在现实世界中具有意义的事。本文中我的目标是,描述一下为当今的web应用而设计的实用的API的最佳实践。如果感觉不对,我不会去尝试满足某个标准。为了帮助进行决策,我已经写下了API必须力争满足的一些要求:

  • 它应当在需要的地方使用 web 标准
  • 它应当对开发者友好并且便于在浏览器地址栏中浏览和探索
  • 它应当是简单、直观和一致的,使它用起来方便和舒适
  • 它应当提供足够的灵活性来增强大多数的 SupportFu 用户界面
  • 它应当是高效的,同时要维持和其他需求之间的平衡

一个 API 是一个开发者的 UI - 就像其他任何 UI 一样, 确保用户体验被认真的考虑过是很重要的!

lwei lwei 翻译于 2013/06/06 18:29  顶 3      

使用 RESTful URLs and actions

如果有一样东西获得广泛认可的话,那就是 RESTful 原则。Roy Felding 在他论文 network based software architectures 的 第五章 中首次介绍了这些原则。

这些REST的关键原则与将你的 API 分割成逻辑资源紧密相关。使用HTTP请求控制这些资源,其中,这些方法(GET, POST, PUT, PATCH, DELETE)具有特殊含义。

可是我该整出什么样的资源呢?好吧,它们应该是有意义于 API 使用者的名词(不是动词)。虽然内部Model可以简单地映射到资源上,但那不一定是个一对一的映射。这里的关键是不要泄漏与API不相关的实现细节。一些相关的名词可以是 票,用户和小组

伪猫 伪猫 翻译于 2013/06/06 12:01  顶 2      

一旦定义好了资源, 需要确定什么样的 actions 应用它们,这些 actions 怎么映射到你的 API 上。RESTful 原则提供了 HTTP methods 映射作为策略来处理 CRUD actions,如下:

  • GET /tickets - 获取 tickets 列表
  • GET /tickets/12 - 获取一个单独的 ticket
  • POST /tickets - 创建一个新的 ticket
  • PUT /tickets/12 - 更新 ticket #12
  • PATCH /tickets/12 - 部分更新 ticket #12
  • DELETE /tickets/12 - 删除 ticket #12

REST 非常棒的是,利用现有的 HTTP 方法在单个的 /tickets 接入点上实现了显著的功能。没有什么方法命名约定需要去遵循,URL 结构是整洁干净的。 REST 太棒了!

伪猫 伪猫 翻译于 2013/06/06 12:21  顶 2      

接入点的名称应该选择单数还是复数呢?keep-it-simple原则可以在此应用。虽然你内在的语法知识会告诉你用复数形式描述单一资源实例是错误的,但实用主义的答案是保持URL格式一致并且始终使用复数形式。不用处理各种奇形怪状的复数形式(比如person/people,goose/geese)可以让API消费者的生活更加美好,也让API提供者更容易实现API(因为大多数现代框架天然地将/tickets和/tickets/12放在同一个控制器下处理)。

但是你该如何处理(资源的)关系呢?如果关系依托于另外一个资源,Restful原则提供了很好的指导原则。让我们来看一个例子。SupportFu的一个ticket包含许多消息(message)。这些消息逻辑上与/tickets接入点的映射关系如下:

  • GET /tickets/12/messages - 获取ticket #12下的消息列表
  • GET /tickets/12/messages/5 - 获取ticket #12下的编号为5的消息
  • POST /tickets/12/messages - 为ticket #12创建一个新消息
  • PUT /tickets/12/messages/5 - 更新ticket #12下的编号为5的消息
  • PATCH /tickets/12/messages/5 - 部分更新ticket #12下的编号为5的消息
  • DELETE /tickets/12/messages/5 - 删除ticket #12下的编号为5的消息
优雅先生 优雅先生 翻译于 2013/06/10 17:54  顶 5      

或者如果某种关系不依赖于资源,那么在资源的输出表示中只包含一个标识符是有意义的。API消费者然后除了请求资源所在的接入点外,还得再请求一次关系所在的接入点。但是如果一般情况关系和资源一起被请求,API可以提供自动嵌套关系表示到资源表示中,这样可以防止两次请求API。

如果Action不符合CRUD操作那该怎么办?

这是一个可能让人感到模糊不解的地方。有几种处理方法:

  1. 重新构造这个Action,使得它像一个资源的field(我理解为部分域或者部分字段)。这种方法在Action不包含参数的情况下可以奏效。例如一个有效的action可以映射成布尔类型field,并且可以通过PATCH更新资源。
  2. 利用RESTful原则像处理子资源一样处理它。例如,Github的API让你通过PUT /gists/:id/star 来 star a gist ,而通过DELETE /gists/:id/star来进行 unstar 。
  3. 有时候你实在是没有办法将Action映射到任何有意义的RESTful结构。例如,多资源搜索没办法真正地映射到任何一个资源接入点。这种情况,/search 将非常有意义,虽然它不是一个名词。这样做没有问题 - 你只需要从API消费者的角度做正确的事,并确保所做的一切都用文档清晰记录下来了以避免(API消费者的)困惑。
优雅先生 优雅先生 翻译于 2013/06/11 12:03  顶 4      

总是使用 SSH

总是使用SSL,没有例外。今天,您的web api可以从任何地方访问互联网(如图书馆、咖啡店、机场等)。不是所有这些都是安全的,许多不加密通信,便于窃听或伪造,如果身份验证凭证被劫持。

另一个优点是,保证总是使用SSL加密通信简化了认证效果——你可以摆脱简单的访问令牌,而不是让每个API请求签署。

要注意的一点是非SSL访问API URLs。不要重定向这些到对应的SSL。相反,抛出一个系统错误!最后一件你想要的是配置不佳的客户发送请求到一个未加密的端点,只是默默地重定向到实际加密的端点。

多多de棉花糖 多多de棉花糖 翻译于 2013/06/08 14:31  顶 2      

文档

API的好坏关键看其文档的好坏. 好的API的说明文档应该很容易就被找到,并能公开访问。在尝试任何整合工作前大部分开发者会先查看其文档。当文档被藏于一个PDF之中或要求必须登记信息时,将很难被找到也很难搜索到。

好的文档须提供从请求到响应整个循环的示例。最好的是,请求应该是可粘贴的例子,要么是可以贴到浏览器的链接,要么是可以贴到终端里的curl示例 。 GitHub 和 Stripe 在这方面做的非常出色。

一旦你发布一个公开的API,你必须承诺"在没有通告的前提下,不会更改APIDe功能" .对于外部可见API的更新,文档必须包含任何将废弃的API的时间表和详情。应该通过博客(更新日志)或者邮件列表送达更新说明(最好两者都通知)。 

qingfeng哥 qingfeng哥 翻译于 2013/06/06 20:22  顶 2      

版本控制

必须对API进行版本控制。版本控制可以快速迭代并避免无效的请求访问已更新的接入点。它也有助于帮助平滑过渡任何大范围的API版本变迁,这样就可以继续支持旧版本API。

关于API的版本是否应该包含在URL或者请求头中 莫衷一是。从学术派的角度来讲,它应该出现在请求头中。然而版本信息出现在URL中必须保证不同版本资源的浏览器可浏览性(browser explorability),还记得文章开始提到的API要求吗?

我非常赞成 approach that Stripe has taken to API versioning - URL包含一个主版本号(比如http://shonzilla/api/v1/customers/1234)
),但是API还包含基于日期的子版本(比如http://shonzilla/api/v1.2/customers/1234),可以通过配置HTTP请求头来进行选择。这种情况下,主版本确保API结构总体稳定性,而子版本会考虑细微的变化(field deprecation、接入点变化等)。

API不可能完全稳定。变更不可避免,重要的是变更是如何被控制的。维护良好的文档、公布未来数月的deprecation计划,这些对于很多API来说都是一些可行的举措。它归根结底是看对于业界和API的潜在消费者是否合理。

优雅先生 优雅先生 翻译于 2013/06/11 12:26  顶 2      

结果过滤,排序和搜索

最好是尽量保持基本资源URL的简洁性。 复杂结果过滤器、排序需求和高级搜索 (当限定在单一类型的资源时) ,都能够作为在基本URL之上的查询参数来轻松实现。下面让我们更详细的看一下:

过滤: 对每一个字段使用一个唯一查询参数,就可以实现过滤。 例如,当通过“/tickets”终端来请求一个票据列表时,你可能想要限定只要那些在售的票。这可以通过一个像 GET /tickets?state=open 这样的请求来实现。这里“state”是一个实现了过滤功能的查询参数。

排序: 跟过滤类似, 一个泛型参数排序可以被用来描述排序的规则. 为适应复杂排序需求,让排序参数采取逗号分隔的字段列表的形式,每一个字段前都可能有一个负号来表示按降序排序。我们看几个例子:

  • GET /tickets?sort=-priority - 获取票据列表,按优先级字段降序排序
  • GET /tickets?sort=-priority,created_at - 获取票据列表,按“priority”字段降序排序。在一个特定的优先级内,较早的票排在前面。

参考:https://www.oschina.net/translate/best-practices-for-a-pragmatic-restful-api

参考:https://www.infoq.cn/article/understanding-restful-style/

 

标签:tickets,12,06,最佳,API,ticket,RESTful,资源
From: https://www.cnblogs.com/gaoyanbing/p/18099425

相关文章

  • Zookeeper客户端java API
    ZooKeeper是一个开源的分布式协调服务,它为分布式应用提供了简单的原语来管理分布式系统中的协调问题,如命名、配置管理、同步和组服务等。ZooKeeper的API为客户端提供了与ZooKeeper服务交互的方式。下面我们将介绍ZooKeeper的主要API及其功能。主要API功能列表:create创建......
  • blog-engine-07-gatsby 建极速网站和应用程序 基于React的最佳框架,具备性能、可扩展
    拓展阅读blog-engine-01-常见博客引擎jekyll/hugo/Hexo/Pelican/Gatsby/VuePress/Nuxt.js/Middleman对比blog-engine-02-通过博客引擎jekyll构建githubpages博客实战笔记blog-engine-02-博客引擎jekyll-jekyll博客引擎介绍blog-engine-02-博客引擎jekyll-jekyll如何......
  • 云原生最佳实践系列 3:基于 SpringCloud 应用玩转 MSE
    概述随着业务不断创新,大型的单个应用和服务会被拆分为数个甚至数十个微服务,微服务架构已经被广泛应用。微服务的好处在于快速迭代,迭代过程保障线上流量不受损。依赖开源产品缺少专业运维工具,常常需要投入较大的运维人力和成本。本实践基于云原生应用产品提供微服务注册配置中心......
  • 轻松掌握:使用 API 接口自动缩短网址的秘诀
    在互联网的世界里,网址缩短已经成为了一种时尚和必要。长而复杂的网址不仅难以记忆,还可能让人望而却步。但是,现在有了API接口,我们可以轻松地将网址自动缩短,让分享变得更加简单和高效!本文将以具体例子详细介绍如何使用API接口实现网址缩短。首先,让我们来了解一下什么是API......
  • 淘宝/天猫获得淘宝app商品详情原数据 API接口数据item_get_app,官方授权接口
     淘宝/天猫的API接口,特别是那些用于获取淘宝app商品详情原数据的接口,提供了强大的功能,使得开发者能够轻松地获取和处理淘宝平台上的商品信息。以下是这些API接口的主要功能:公共参数请求地址:item_get名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretSt......
  • 京东获得JD商品详情 API接口数据item_get(内含详细步骤)
    onebound.jd.item_get公共参数注册账号获取测试key 名称类型必须描述keyString是调用key(必须以GET方式拼接在URL中)secretString是调用密钥api_nameString是API接口名称(包括在请求地址中)[item_search,item_get,item_search_shop等]cacheString否[yes,no]默认yes,将调用缓存......
  • 阿里巴巴中国站获得1688商品详情 API接口数据item_get(内含详细步骤)
     阿里巴巴中国站(1688)提供的商品详情API为开发者提供了丰富的功能,使他们能够通过编程的方式访问和获取1688平台上的商品详细信息。以下是关于这个API功能的一些主要介绍:获取商品详情信息:通过API,开发者可以查询指定商品的详细信息,包括商品标题、描述、价格、库存等。这些信息......
  • 淘宝/天猫获得淘宝app商品详情原数据 API接口数据,有哪些常见的错误
    淘宝API在使用过程中可能会遇到多种错误,这些错误可能由不同的原因引起。以下是一些常见的淘宝API错误及其可能的原因:签名错误:这通常是由于签名生成过程中出现问题导致的。例如,签名参数错误、签名方法不正确或签名顺序不一致等都可能导致签名错误。API接口权限不足:如果调用A......
  • 市场数据和金融数据API的获取步骤,支持Python、Java、Go等接入方式,轻松实现量化数据交
    今天我想分享一个非常实用的技术内容,即如何通过接口API来实现订阅并接入实时行情数据源的报价信息。这个技术可以帮助你获取最新的市场数据,为你的应用程序或交易策略提供及时的信息支持。接入实时行情数据源可以让你了解市场动态并快速作出决策,非常有助于优化你的交易策略和投资决......
  • 【python】服务端和客户端 RESTful 接口上传 E
    哈喽,大家好,我是木头左,物联网搬砖工一名,致力于为大家淘出更多好用的AI工具!服务端代码1.安装Flask和Flask-RESTful需要安装Flask和Flask-RESTful这两个库。Flask是一个轻量级的Web框架,而Flask-RESTful则是一个为Flask添加了RESTfulAPI支持的扩展。pipinstall......