标签:
这个附件的幻灯片是我最近给团队分享关于设计 HTTP API 的时候,结合 这篇 和我们团队历史上的一些错误,总结出来一些适合内部的经验。
这次分享主要关注以下几部分:
同时还会举出一些 badcase,这些 badcase 一般是我负责的或者开发的服务中遇到的问题。
在 HTTP API 实践中,涉及到了以下背景知识,可能需要了解
这个幻灯片,会从以下三个方面,沟通和讨论,在实现一个合理、易用的 API 需要关注的事项。
在规划一个 API 的时候,应该将不同的“资源”,分布到不同的 URI 下,不要将不同的资源放置到同一个 URI 下面进行操作。
下面是一个好的例子:
/v1.0/gossip/mine
/v1.0/gossip/user/uid
/v1.0/gossip/detail/gossip_id
/v1.0/user/invite
我也在工作中,遇到过一些做的不好的 API:
host:prot/?qt=cd2
host:port/?qt=s
这个不好的例子在于,将所有对资源的操作,都放到了 GET 参数中,这样最直接的坏处就是,会对线上查找日志造成影响(因为你不能确保 qt 会出现在?后面,然后如果有多个字段需要 grep,那就需要 bash 达人出手才行了; 去线上 grep 日志简直就是``pain-in-the-ass‘‘)。
除此之外,在代码上,后一种方式也会造成不小的混乱。比如在这个例子中, 前者的入口是这样写的:
1 app = Flask(__name__) 2 app.register_blueprint(user_api, 3 url_prefix=‘/v1.0/user‘) 4 app.register_blueprint(gossip_api, 5 url_prefix=‘/v1.0/gossip‘) 6 app.register_blueprint(bigbro_api, 7 url_prefix=‘/v1.0/dd‘) 8 app.register_blueprint(util_api, 9 url_prefix=‘/‘) 10 app.run(host=‘0.0.0.0‘, port=port, debug=True)
而后者呢,一般是这样写的:
1 $qt = $_REQUEST[‘qt‘]; 2 if ($qt == ‘cd2‘) { 3 // xxx 4 } else if ($qt == ‘s‘) { 5 // xxx 6 }
一个 API,在安全方面,应该做到以下几点:
同样,尽量避免使用``重定向‘‘,因为客户端使用的库可能无法正常处理重定向、RD 可能会忽略重定向,多次重定向会增加服务都拿压力。
服务、客户端升级前后的兼容,一直是服务开发的人力黑洞。所以从服务的第一个版本开始,需要将版本更迭这件事考虑在内。
解决办法是在每一个请求中,增加当前使用协议的版本号。一个简单地方法是在 Header 中增加版本号,可以减少版本信息对 API 接口的干扰。
比如这样:
Accept: application/vnd.heroku+json; version=3
如果你不这样做,那么在你的服务运维一段时间之后,尤其是客户端已经发布出去但是后面发现了 bug,你的代码很可能是这样的:
1 if (isset($_REQUEST[‘cduss‘]) && 2 ($result[‘cdstat‘] == 0) && 3 (substr($param[‘os‘], 0, 6) == ‘iphone‘) && 4 ($param[‘sv‘] == ‘2.1.0‘)) 5 { 6 $rst[‘errorno‘] = -1; 7 }
合理地使用 ETags,配合 Cache,可以同时减轻服务端、客户端的压力。这件事需要客户端和服务端的配合:
关于里面提到的 ETags、If-None-Match, 你自己放狗搜一下吧。
对服务涉及到很多上下游,还需要跨团队的API 来说, Request ID 是你在追查问题的法宝: 它通过一个统一的规则,将为请求分配的唯一 ID 增加在 HTTP 头中并向下游服务传递,像一条线一样,把整个服务流程上线串联起来,日后可以通过这个 ID 来分析请求执行的情况。
同时 Server 端也应该把 Request ID 增加在返回的结果中,这样客户端可以拿到它,会对调试提供极大的帮助。
再也不要用 pg=x&num=y&order=uid 来进行分页、排序了,将这些字段统统放到Range 里面去:
你看到了,全部使用 Range 的话,客户端根本不需要自己拼凑请求,只需要把上一次 Server 返回的 ``Next-Range‘‘ 再放回到请求头中,就可以完成“下一页”的操作了。
像这样:
curl -i -n -X GET https://api.heroku.com/apps \
-H ``Accept: application/vnd.heroku+json; version=3‘‘ \
-H ``Range: name ..; order=desc,max=10;‘‘
Accept: application/vnd.heroku+json; version=3
HTTP-API-DESIGN 怎样设计一个合理的 HTTP API (一)
标签:
原文地址:http://www.cnblogs.com/llhf/p/4541364.html