各公司 API 接口设计观察

2022-04-13 18:21:34 +08:00
 rv54ntjwfm3ug8

测试过程

因为我的两个帖子 /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 ,结果都属于上面几种情况,因为过滤并检查是否有隐私信息麻烦就不贴了。

结论

5231 次点击
所在节点    程序员
28 条回复
rv54ntjwfm3ug8
2022-04-13 18:47:30 +08:00
奇怪 发出来格式乱了 结论也丢了

结论:
1. 所测国外大公司同一产品的 API 路由都没有统一格式,链接中包含大小写的居多
2. 所测公司 API 路由在成功状态下返回内容中都没有成功标识
3. 国外公司对能处理的非输入错误返回 200 和 40x 的各占一半,输入错误全部为 40x
4. 所以怎么用舒服怎么来就好
5. V 站的 Markdown 编辑器好难用(逃)
golangLover
2022-04-13 20:26:41 +08:00
google 的 api 设计是非常混乱的。。想学 api 设计不要学 google.
maichael
2022-04-13 20:42:23 +08:00
实际上大公司都是跨部门(甚至跨公司)、跨历史长流,API 混乱再正常不过了。
agagega
2022-04-13 20:44:00 +08:00
隔壁楼里支持用状态码已经是崇洋媚外了吗🐶
Soin
2022-04-13 20:44:59 +08:00
国内主流都是成功和失败返回的格式统一,这种不统一的不方便解析吧?
freefcw
2022-04-13 20:45:02 +08:00
不同的产品,团队人员都不一样,语言也不一样,最关键的是历史都不一样。YouTube 是 Python 开始的,Facebook 是 java 开始的,你这些都要考虑

一般要考虑就考虑某一个产品的统一输出,像 aws ,azure ,Facebook ,Dropbox ,Twitter ,GitHub 的开放 api 之类的就比较标准和规范

p.s. 成功状态下内容中没有 code 和 message 我觉得更合理一些,不知道国内怎么养成个啥都需要的习惯。。
Building
2022-04-13 20:53:36 +08:00
根据我的实际体验:
海外产品的 api 十分简洁甚至十分简单
大陆产品的 api 十分复杂甚至十分难用
其实就跟 App 一个德行
afewok
2022-04-13 21:09:43 +08:00
是不是又有舔狗鼓吹国外月亮比较圆了?
chendy
2022-04-13 21:27:53 +08:00
API 接多了,就觉得还是有 SDK 的香,不用自己接的才是最好的
liuidetmks
2022-04-13 22:14:24 +08:00
@afewok 刚看帖子,有人因为国内很多人把 code 放在 body 里面,解读成这个国家 xxxx
大受震撼
hu8245
2022-04-13 22:48:19 +08:00
我比较欣赏 GitHub 的 API ,也比较好套用到自己的理念上
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 设计吗?
binux
2022-04-13 23:03:25 +08:00
@Goooooos Error responses are served with a non-200-series HTTP code. 许愿帮你翻译吗?
chendy
2022-04-13 23:11:05 +08:00
@Goooooos 只能说接触多的都是国外比较好的东西,做的不好的也基本接触不到,幸存者偏差了
Goooooos
2022-04-13 23:13:57 +08:00
@chendy 做广告买量分析,对接过 facebook ,twitter ,google ,tiktok 的 ads api ,我觉得 Facebook 的 graph 是这里面做得最好的一个了
kakach
2022-04-13 23:24:46 +08:00
个人觉得 PayPal 的 API 很好,非常 restful ,返回里会有 HATEOAS link.例如 https://developer.paypal.com/docs/api/orders/v2/#orders_create
lower
2022-04-13 23:26:19 +08:00
@chendy 网上有好多聚合了好多个第三方支付平台的开源项目,用起来真的方便,统一的参数配置、初始化、调用接口;不同的参数字段名称、金额单位、加签算法等等都转换封装好了😂,设计模式用的很 6……有的把依赖安装方式都打好了,美滋滋,用完扫码支付几块钱再感谢作者
codeMore
2022-04-13 23:45:46 +08:00
@lower 劳烦推荐一个,借鉴学习一下
xuanbg
2022-04-14 06:47:05 +08:00
1 、越是大厂,其接口风格就越混乱。员工上万,妖魔鬼怪。
2 、国外的代码也未必就比国内香。不幸接触过诺基亚、爱立信、摩托罗拉的代码,绝对是屎山中的珠穆朗玛。所以在某种意义上,这 3 家的倒掉也不是没有底层原因的。为了能持续摸鱼,代码还是要好好写,不然鱼塘干掉就尴尬了。
3 、接口风格最重要的不是 http 状态码 200 还是非 200 ,而是统一。当然我站 200 。如果非 200 ,body 可以直接返回数据,无需封装成统一的数据格式。200 的话,就必须有一致的封装,不然让前端怎么解码?
4 、200 一把梭的,是把 http 当传输协议用了,话说 http 本来就是传输协议啊。这。。。没毛病啊。
Goooooos
2022-04-14 08:45:28 +08:00
我觉得用 http 状态码,还是 200 一把梭都不是问题
只要能保证一致就好了,不要这个接口这样定义,那个接口又那样定义

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/846785

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX