如何设计一个优秀的API - 文章 - 伯乐在线 http://blog.jobbole.com/42317/

如何设计一个优秀的API - 标点符 https://www.biaodianfu.com/how-to-design-a-good-api.html

MediaWiki API help - Wikipedia https://en.wikipedia.org/w/api.php

如何设计一个优秀的API

2013年6月28日  21 sec read

到目前为止,已经负责API接近两年了,这两年中发现现有的API存在的问题越来越多,但很多API一旦发布后就不再能修改了,即时升级和维护是必须的。一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的。如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的打击就更大。如果API经常发生变化,用户就会失去对提供方失去信心,从而也会影响目前的业务。

但是我们为什么还要修改API呢?为了API看起来更加漂亮?为了提供更多功能?为了提供更好的性能?还是仅仅觉得到了改变了时候了?对于用户来说,他们更愿意使用一个稳定但是看起来不那么时髦的API,这并不意味着我们不再改进API了。当糟糕的API带来的维护成本越来越大时,我想就是我们去重构它的时候。

如果可以回头重新再做一遍,那么我心目中的优秀的API应该是怎么样的?

判断一个API是否优秀,并不是简单地根据第一个版本给出判断的,而是要看随着时间的推移,该API是否还能存在,是否仍旧保持得不错。槽糕的API接口各种各样,但是好的API接口对于用户来说必须满足以下几个点:

  • 易学习:有完善的文档及提供尽可能多的示例和可copy-paste的代码,像其他设计工作一样,你应该应用最小惊讶原则
  • 易使用:没有复杂的程序、复杂的细节,易于学习;灵活的API允许按字段排序、可自定义分页、 排序和筛选等。一个完整的API意味着被期望的功能都包含在内。
  • 难误用:对详细的错误提示,有些经验的用户可以直接使用API而不需要阅读文档。

而对于开发人员来说,要求又是不一样的:

  • 易阅读:代码的编写只需要一次一次,但是当调试或者修改的时候都需要对代码进行阅读。
  • 易开发:个最小化的接口是使用尽可能少的类以及尽可能少的类成员。这样使得理解、记忆、调试以及改变API更容易。

如何做到以上几点,以下是一些总结:

1、 面向用例设计

如果一个API被广泛使用了,那么就不可能了解所有使用该API的用户。如果设计者希望能够设计出被广泛使用的API,那么必须站在用户的角度来理解如何设计API库,以及如何才能设计出这样的API库。

2、 采用良好的设计思路

在设计过程中,如果能按照下面的方式来进行设计,会让这个API生命更长久

  • 面向用例的设计,收集用户建议,把自己模拟成用户,保证API设计的易用和合理
  • 保证后续的需求可以通过扩展的形式完成
  • 第一版做尽量少的内容,由于新需求可以通过扩展的形式完成,因此尽量少做事情是抑制API设计错误的一个有效方案
  • 对外提供清晰的API和文档规范,避免用户错误的使用API,尤其是避免API(见第一节)靠后级别的API被用户知晓与误用

除此之外,下面还列出了一些具体的设计方法:

  • 方法优于属性
  • 工厂方法优于构造函数
  • 避免过多继承
  • 避免由于优化或者复用代码影响API
  • 面向接口编程
  • 扩展参数应当是便利的
  • 对组件进行合理定位,确定暴露多少接口
  • 提供扩展点

3、 避免极端的意见

在设计API的时候,一定要避免任何极端的意见,尤其是以下几点:

  • 必须漂亮(API不一定需要漂亮)
  • API必须被正确地使用(用户很难理解如何正确的使用API,API的设计者要充分考虑API被误用的情况:如果一个API可能会被误用,那么它一定会被误用)
  • 必须简单(我们总会面临复杂的需求,能两者兼顾的API是更好的API)
  • 必须高性能(性能可以通过其他手段优化,不应该影响API的设计)
  • 必须绝对兼容(尽管本文一直提到如何保证兼容,但是我们仍然要意识到,一些极少情况下会遇到的不兼容是可以容忍的)

4、 有效的API评审

API设计完成以后,需要经过周密的设计评审,评审的重点如下:

  • 用例驱动,评审前必须提供完善的使用用例,确保用例的合理性和完备性。
  • 一致性,是否与系统中其他模块的接口风格一致,是否与对称接口的设计一致。
  • 简单明了,API应该简单好理解,容易学习和使用的API才不容易被误用,给我们带来更多的麻烦。
  • API尽可能少,如果一个API可以暴露也可以不暴露,那么就不要暴露他,等到用户真正有需求的时候再将它成为一个公开接口也不迟。
  • 支持持续改进,API是否能够方便地通过扩展的方式增加功能和优化。

5、 提高API的可测试性

API需要是可测试的,测试不应依赖实现,测试充分的API,尤其是经过了严格的“兼容性整合测试”的API,更能保证在升级的过程中不出现兼容性问题。兼容性整合测试,是指一组测试用例集合,这组测试用例会站在使用者的立场上使用API。在API升级以后,再检测这组测试用例是否能完全符合预期的通过测试,尽可能的发现兼容性问题。

6、 保证API的向后兼容

对于每一个API的设计者来说,都渴望做到“向后兼容”,因为不管是现在的API用户,还是潜在的API用户,都只信任那些可兼容的API。但向后兼容有多个层次上的意义,而且不同层次的向后兼容,也意味着不同的重要性和复杂度。

7、 保持逐步改善

过去我们总希望能将现有的“不合理”的设计完全推翻,然后按照现在“美好”的思路,重新设计这个API,但是在一段时间以后,又会碰到一样的状况,需要再推翻一次。 如果我们没有有效的逐步改善的办法,依靠推翻现有设计,重新设计API只能让我们回到起点,然后重现之前的过程。 要有一套行之有效的持续改善的办法来在API兼容的同时,改善API使之更好。

8、 把握API的生命周期

每一个API都是有生命周期的,我们需要让API的生命周期更长,并且在API的生命周期结束时能让其平滑的消亡。

  • 告诉用户我们是如何设计的,避免误用,提供指导,错误的使用往往是缩短API寿命的一大杀手
  • 提供试用期,API不可能一开始就是稳定,经过试用的API才能有更强的生命力
  • 为API分级:内部使用;二次开发使用;开发或试用中;稳定;弃用API。避免API被滥用的同时,我们可以通过调整API的级别,来扩大其影响力,也能更优雅的结束一个API的生命周期。

开发API的过程其实就是一个沟通交流的过程。沟通的双方就是API用户和API设计者。

9、 一些具体的实施方案

在一个API不可避免要消亡或者改变的时候,我们应该接受并且面对这个事实,下面列举了几种保证兼容性的前提下,对API进行调整的办法:

  • 将API标记为弃用,重新建立一个新的API。如果一个API不可避免要被消亡,这是唯一的办法。
  • 为其添加额外的参数或者参数选项来实现功能添加
  • 将现有API拆成两部分,提供一个精简的核心API,过去的API通过封装核心API上实现。这通常用于解决用户需要一个代码精简的版本时。
  • 在现有的API基础上进行封装,提供一个功能更丰富的包或者类

一些好的API示例:

  1. Flickr API,这里是文档的示例,同时提供了一个非常方便的API测试工具
  2. Mediawiki API
  3. Ebay API,这里有一个非常详尽的文档示例

如何设计一个优秀的API的更多相关文章

  1. 如何设计一个优秀的API(转载)

    最近在整理框架的一些 API,觉得很有必要总结一下 API 兼容性的设计.下图是我自己当下的一些总结,慢慢维护: 网上搜索了一下,一个多月前,“标点符”已经发布了下面这篇文章,觉得写得非常不错,转载于 ...

  2. 如何设计一个优秀的API(转)

    到目前为止,已经负责API接近两年了,这两年中发现现有的API存在的问题越来越多,但很多API一旦发布后就不再能修改了,即时升级和维护是必须的.一旦API发生变化,就可能对相关的调用者带来巨大的代价, ...

  3. 如何设计一个良好的API接口?

    沟通创造价值,分享带来快乐.这里是程序员阅读时间,每天和你分享读书心得,欢迎您每天和我一起精进.今天和大家一起讨论的话题是如何设计一个良好的API接口? 作者:梁桂钊 解读:张飞洪 挑战 API是软件 ...

  4. ASP.NET Web API实践系列11,如何设计出优秀的API

    本篇摘自:InfoQ的微信公众号 在设计API的时候考虑的问题包括:API所使用的传输协议.支持的消息格式.接口的控制.名称.关联.次序,等等.我们很难始终作出正确的决策,很可能是在多次犯错之后,并从 ...

  5. 前端资讯周报 2.27 - 3.5: 如何设计一个优秀的HTML接口,深入理解line-height

    从本周起,每周一我都会分享上一周我订阅的技术站点中,和解决问题的过程中阅读到的值得分享的文章,或者视频教程,又或者图书. 个人认为国外的技术文章质量较高,而且发布的技术资讯也走在行业前沿,所以比较关注 ...

  6. 如何设计一个牛逼的API接口

    在日常开发中,总会接触到各种接口.前后端数据传输接口,第三方业务平台接口.一个平台的前后端数据传输接口一般都会在内网环境下通信,而且会使用安全框架,所以安全性可以得到很好的保护.这篇文章重点讨论一下提 ...

  7. 优秀的API接口设计原则及方法(转)

    一旦API发生变化,就可能对相关的调用者带来巨大的代价,用户需要排查所有调用的代码,需要调整所有与之相关的部分,这些工作对他们来说都是额外的.如果辛辛苦苦完成这些以后,还发现了相关的bug,那对用户的 ...

  8. 如何设计优秀的API(转)

    到目前为止,已经负责API接近两年了,这两年中发现现有的API存在的问题越来越多,但很多API一旦发布后就不再能修改了,即时升级和维护是必须的.一旦API发生变化,就可能对相关的调用者带来巨大的代价, ...

  9. Google首席软件工程师Joshua Bloch谈如何设计一款优秀的API【附PPT】

    编者按]随着近来软件规模的日益庞大,API编程接口的设计变的越来越重要.良好的接口设计可以降低系统各部分之间的相互依赖,提高组成单元的内聚性,降低组成单元间的耦合度,从而提高系统的维护性和稳定性. J ...

随机推荐

  1. offset家族

  2. 2.ruby基本语法,类的定义

    1.在ruby中的定义class,ruby中定义类也是以关键字class开头 后面带着类名,类名以大写开头.一个类的结束以关键字end 结束.如: class Customer end 2.ruby类 ...

  3. 【bzoj3689】异或之 可持久化Trie树+堆

    题目描述 给定n个非负整数A[1], A[2], ……, A[n].对于每对(i, j)满足1 <= i < j <= n,得到一个新的数A[i] xor A[j],这样共有n*(n ...

  4. 常州模拟赛d3t1 神在夏至祭降下了神谕

    题目描述 我们村子在过去的400年中,断绝与下界的接触,过着自给自足的生活. 夏至祭是一场迎接祖灵于夏季归来,同时祈求丰收的庆典. 村里的男人会在广场上演出夏之军和冬之军的战争.夏之军会打倒冬之军的大 ...

  5. P1140 相似基因 (动态规划)

    题目背景 大家都知道,基因可以看作一个碱基对序列.它包含了4种核苷酸,简记作A,C,G,T.生物学家正致力于寻找人类基因的功能,以利用于诊断疾病和发明药物. 在一个人类基因工作组的任务中,生物学家研究 ...

  6. spring mvc 单元测试示例

    import java.awt.print.Printable; import java.io.IOException; import javax.servlet.http.HttpServletRe ...

  7. ES6的一些说明

    一 ES6 即 ECMAScript6 ECMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,已经在2015年6月正式发布了.它的目标,是使得JavaScript语言可 ...

  8. ElasticSearch API 之 GET

    GET API是Elasticsearch中常用的操作,一般用于验证文档是否存在:或者执行CURD中的文档查询.与检索不同的是,GET查询是实时查询,可以实时查询到索引结果.而检索则是需要经过处理才能 ...

  9. Codeforces891C. Envy

    $n \leq 5e5$,$m \leq 5e5$的无向边权图,$q \leq 5e5$个询问,每次问一系列边是否能同时存在于某棵最小生成树上. 一条边在最小生成树上,当比他小的边都加入后,加入他会使 ...

  10. 标准C程序设计七---27

    Linux应用             编程深入            语言编程 标准C程序设计七---经典C11程序设计    以下内容为阅读:    <标准C程序设计>(第7版) 作者 ...