因为我的两个帖子 /t/838609 /t/846741 V 友们的意见都不太统一,刚好看到今天有人又在争论这个问题,于是我打算看看各公司 API 的接口设计
首页随便找了个接口:
POST https://www.youtube.com/youtubei/v1/att/get?key=<input>&prettyPrint=true
Request:
key=?
prettyPrint=?
Success Case (HTTP 200):
{
"responseContext": {
"serviceTrackingParams": [
{
"service": "**",
"params": [
{
"key": "**",
"value": "WEB"
},
{
"key": "**",
"value": "**"
},
]
},
**
],
"mainAppWebResponseContext": {
"datasyncId": "**",
"loggedOut": false
},
"webResponseContextExtensionData": {
"hasDecorated": true
}
},
"challenge": "**",
"botguardData": {
"program": "**",
"interpreterSafeUrl": {
"privateDoNotAccessOrElseTrustedResourceUrlWrappedValue": "//www.google.com/js/**.js"
}
}
}
Fail Case (不传 Key 字段 HTTP 403 ):
{
"error": {
"code": 403,
"message": "The request is missing a valid API key.",
"errors": [
{
"message": "The request is missing a valid API key.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
Fail Case 2 ( Key 随便传了个 0 HTTP 400 ):
{
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"errors": [
{
"message": "API key not valid. Please pass a valid API key.",
"domain": "global",
"reason": "badRequest"
}
],
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "API_KEY_INVALID",
"domain": "googleapis.com",
"metadata": {
"service": "**.googleapis.com"
}
}
]
}
}
大部分 API 都有混淆,选一个列登录 Google 账号列表的
POST https://accounts.google.com/ListAccounts
Requests:
listPages=?
authuser=?
pid=?
Success Case (HTTP 200):
["**",[["**",1,"**","**@gmail.com","https://**.googleusercontent.com/**.jpg",0,0,1,null,1,"**",null,**]]]
Success Case 2 (清空 Cookies 后测试 HTTP 200):
返回长度 0 的内容。
Fail Case (listPages 传负数 HTTP 400 ):
返回长度 0 的内容。
另外这里看到了 3 个 ASP.NET Core 官方模板风格的请求(路由大驼峰,参数小驼峰)
推特详情 API ,懒得截图了
GET https://twitter.com/i/api/graphql/**/TweetDetail
Request:
variables=%7B%22focalTweetId%**
URL 解码后:
{"focalTweetId":"**","referrer":"home",**
Success Case (HTTP 200):
{
"data": {
"threaded_conversation_with_injections_v2": {
"instructions": [
{
"type": "TimelineAddEntries",
"entries": [
{
"entryId": "**"
**
Fail Case (随便破坏 JSON 结构几个字符 HTTP 400 )
{"errors":[{"message":"Cannot parse variables: \"focalTweetId\\\"**
Fail Case 2 (传不存在的推特 ID HTTP 200 )
{"errors":[{"message":"_Missing: No status found with that ID.","locations":[{"line":5,"column":3}],
后续我又测试了 Amazon ,Azure ,AT&T 的 API ,结果都属于上面几种情况,因为过滤并检查是否有隐私信息麻烦就不贴了。
1
rv54ntjwfm3ug8 OP 奇怪 发出来格式乱了 结论也丢了
结论: 1. 所测国外大公司同一产品的 API 路由都没有统一格式,链接中包含大小写的居多 2. 所测公司 API 路由在成功状态下返回内容中都没有成功标识 3. 国外公司对能处理的非输入错误返回 200 和 40x 的各占一半,输入错误全部为 40x 4. 所以怎么用舒服怎么来就好 5. V 站的 Markdown 编辑器好难用(逃) |
2
golangLover 2022-04-13 20:26:41 +08:00 via Android
google 的 api 设计是非常混乱的。。想学 api 设计不要学 google.
|
3
maichael 2022-04-13 20:42:23 +08:00
实际上大公司都是跨部门(甚至跨公司)、跨历史长流,API 混乱再正常不过了。
|
4
agagega 2022-04-13 20:44:00 +08:00 via iPhone
隔壁楼里支持用状态码已经是崇洋媚外了吗🐶
|
5
Soin 2022-04-13 20:44:59 +08:00
国内主流都是成功和失败返回的格式统一,这种不统一的不方便解析吧?
|
6
freefcw 2022-04-13 20:45:02 +08:00 2
不同的产品,团队人员都不一样,语言也不一样,最关键的是历史都不一样。YouTube 是 Python 开始的,Facebook 是 java 开始的,你这些都要考虑
一般要考虑就考虑某一个产品的统一输出,像 aws ,azure ,Facebook ,Dropbox ,Twitter ,GitHub 的开放 api 之类的就比较标准和规范 p.s. 成功状态下内容中没有 code 和 message 我觉得更合理一些,不知道国内怎么养成个啥都需要的习惯。。 |
7
Building 2022-04-13 20:53:36 +08:00 via iPhone
根据我的实际体验:
海外产品的 api 十分简洁甚至十分简单 大陆产品的 api 十分复杂甚至十分难用 其实就跟 App 一个德行 |
8
afewok 2022-04-13 21:09:43 +08:00 2
是不是又有舔狗鼓吹国外月亮比较圆了?
|
9
chendy 2022-04-13 21:27:53 +08:00 2
API 接多了,就觉得还是有 SDK 的香,不用自己接的才是最好的
|
10
liuidetmks 2022-04-13 22:14:24 +08:00 via iPhone
@afewok 刚看帖子,有人因为国内很多人把 code 放在 body 里面,解读成这个国家 xxxx
大受震撼 |
11
hu8245 2022-04-13 22:48:19 +08:00
我比较欣赏 GitHub 的 API ,也比较好套用到自己的理念上
|
12
Goooooos 2022-04-13 22:53:21 +08:00
就拿 facebook 的 Graph Api ,也是定义了自己的业务错误码的
https://developers.facebook.com/docs/graph-api/guides/error-handling 然后的是 twitter ads api https://developer.twitter.com/en/docs/twitter-ads-api/response-codes 那些说只有国内才这样做,国内风气不好的,真的有去了解过国外的 api 设计吗? |
13
binux 2022-04-13 23:03:25 +08:00
@Goooooos Error responses are served with a non-200-series HTTP code. 许愿帮你翻译吗?
|
15
Goooooos 2022-04-13 23:13:57 +08:00
@chendy 做广告买量分析,对接过 facebook ,twitter ,google ,tiktok 的 ads api ,我觉得 Facebook 的 graph 是这里面做得最好的一个了
|
16
kakach 2022-04-13 23:24:46 +08:00 via Android
个人觉得 PayPal 的 API 很好,非常 restful ,返回里会有 HATEOAS link.例如 https://developer.paypal.com/docs/api/orders/v2/#orders_create
|
17
lower 2022-04-13 23:26:19 +08:00
@chendy 网上有好多聚合了好多个第三方支付平台的开源项目,用起来真的方便,统一的参数配置、初始化、调用接口;不同的参数字段名称、金额单位、加签算法等等都转换封装好了😂,设计模式用的很 6……有的把依赖安装方式都打好了,美滋滋,用完扫码支付几块钱再感谢作者
|
19
xuanbg 2022-04-14 06:47:05 +08:00 1
1 、越是大厂,其接口风格就越混乱。员工上万,妖魔鬼怪。
2 、国外的代码也未必就比国内香。不幸接触过诺基亚、爱立信、摩托罗拉的代码,绝对是屎山中的珠穆朗玛。所以在某种意义上,这 3 家的倒掉也不是没有底层原因的。为了能持续摸鱼,代码还是要好好写,不然鱼塘干掉就尴尬了。 3 、接口风格最重要的不是 http 状态码 200 还是非 200 ,而是统一。当然我站 200 。如果非 200 ,body 可以直接返回数据,无需封装成统一的数据格式。200 的话,就必须有一致的封装,不然让前端怎么解码? 4 、200 一把梭的,是把 http 当传输协议用了,话说 http 本来就是传输协议啊。这。。。没毛病啊。 |
20
Goooooos 2022-04-14 08:45:28 +08:00
我觉得用 http 状态码,还是 200 一把梭都不是问题
只要能保证一致就好了,不要这个接口这样定义,那个接口又那样定义 |
21
yuxiu 2022-04-14 09:38:47 +08:00
google 返回长度为 0 的内容,这么反人类吗,直接设 204 不就好了
|
22
dayeye2006199 2022-04-14 11:54:09 +08:00
推荐 shopify 的 API ,文档清晰,风格一致: https://shopify.dev/api/admin-rest
|
23
ZSeptember 2022-04-14 13:19:26 +08:00
Shopify API 设计还行,但是有些 API 很难用。
可以参考 stripe 。 API 设计也是要看场景的,Open API ,比如 Shopify ,Stripe 这种,国外一定是 RESTful 的,状态码也是按规范的。 但是用户 API ,就并不一定了,因为 RESTful 表达能力有限。 |
24
freeup 2022-04-14 14:27:58 +08:00 2
其实昨天那个帖子我也看了 都没敢说话 怕被喷,。。我们系统就是 get post ,只要进行了业务代码一定返回的 200,返回固定的格式
{"code","","msg":"","data":""} 我也是个实在派,感觉 api 是给开发人员用的,在都能满足功能且扩展性都差不多的情况下,我会优先选择简洁的方案。 1.我们只是把 http 当做一个传输协议,不参与任何业务逻辑,所有业务信息都已接口返回的内容为准,统一口径,这点就和 tcp/ip 一样,返回的包里才是具体的业务数据,就和虽然 tcp/ip 预留了可自定义的数据位置,但实际情况几乎不会有人去使用这个(不要杠 http 协议和 tcp 协议不再一层。。。我只是举个例子,非完全严谨,,瑟瑟发抖。。) 2.比如我们系统是前后端分离,外部传入的数据都要做防御性校验,比如参数必填,有错误,逻辑校验不过的情况,在我看来都是参数验证不过,返回一个固定的业务码,再返回一个实际具体的错误 3.我也对接过很多大厂的 api 某度 某宝 某信 尤其支付这块,业务情况实在是太多,如果不使用自定义的业务码,只返回错误 msg 不论是提工单还是检索问题,或者系统内部进行错误判定都不是太合适,假设是 http 状态码+错误 msg 那么在 http 码非 200 的情况下 就只能通过字符串消息进行错误判定,这样总感觉给人一种不严谨的感觉,因为错误码不会变,但是具体的错误文案可是会变得 4.200 一把梭 前端拦截也比较简单,只需要拦截非 200 且错误码不是成功的就行,也就是先 http 状态拦截,再 code 的拦截,只要返回 200 就能保证这个请求一定是到了业务里,其他情况一定就是出在了 http 协议上 5.而且返回具体的业务码可以前端可以根据不同的错误码 进行业务处理,例如:登录时账号密码错误 返回 1 那超过 5 次返回 2 那前端就会给出个提示 60 秒后在尝试,这种业务控制。当然这个功能不依赖后端也能完成,但是当这个逻辑作为业务的硬性逻辑时 那必须就得由后端控制,即使你直接访问 api 我也会有这段逻辑 以上仅是我们系统是这样做的,不代表任何群体,任何观点,我只是陈述我们系统是怎么做的而已。。。 存在即合理,没有绝对的正确与绝对的错误,没有最好的设计,只有最合适的设计。。。。。 如果看完你不认同这个 一定淡定 淡定 不要喷我。。。。。 |
25
2kCS5c0b0ITXE5k2 2022-04-14 15:05:47 +08:00
用啥都可以. 把文档写好就行.
|
26
jjwjiang 2022-04-14 15:14:27 +08:00
建议看看 github 的
|
27
gmywq0392 2022-04-14 18:01:18 +08:00
看 Stripe 和 Deutsche Bank
|
28
pigspy 2022-04-15 09:21:23 +08:00
这跟崇洋媚外太大关系,就纯粹是有些(脏话)原教旨主义者扯着外国人的大旗来规训国内码农了
|