各公司 API 接口设计观察 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
rv54ntjwfm3ug8
V2EX    程序员

各公司 API 接口设计观察

  •  3
     
  •   rv54ntjwfm3ug8 2022-04-13 18:21:34 +08:00 5919 次点击
    这是一个创建于 1285 天前的主题,其中的信息可能已经有所发展或是发生改变。

    测试过程

    因为我的两个帖子 /t/838609 /t/846741 V 友们的意见都不太统一,刚好看到今天有人又在争论这个问题,于是我打算看看各公司 API 的接口设计

    • YouTube

    首页随便找了个接口:

    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" } } ] } } 
    • Gmail

    大部分 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 官方模板风格的请求(路由大驼峰,参数小驼峰)

    • Twitter:

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

    结论

    28 条回复    2022-04-15 09:21:23 +08:00
    rv54ntjwfm3ug8
        1
    rv54ntjwfm3ug8  
    OP
       2022-04-13 18:47:30 +08:00
    奇怪 发出来格式乱了 结论也丢了

    结论:
    1. 所测国外大公司同一产品的 API 路由都没有统一格式,链接中包含大小写的居多
    2. 所测公司 API 路由在成功状态下返回内容中都没有成功标识
    3. 国外公司对能处理的非输入错误返回 200 和 40x 的各占一半,输入错误全部为 40x
    4. 所以怎么用舒服怎么来就好
    5. V 站的 Markdown 编辑器好难用(逃)
    golangLover
        2
    golangLover  
       2022-04-13 20:26:41 +08:00 via Android
    google 的 api 设计是非常混乱的。。想学 api 设计不要学 google.
    maichael
        3
    a href="/member/maichael" class="dark">maichael  
       2022-04-13 20:42:23 +08:00
    实际上大公司都是跨部门(甚至跨公司)、跨历史长流,API 混乱再正常不过了。
    agagega
        4
    agagega  
       2022-04-13 20:44:00 +08:00 via iPhone
    隔壁楼里支持用状态码已经是崇洋媚外了吗
    Soin
        5
    Soin  
       2022-04-13 20:44:59 +08:00
    国内主流都是成功和失败返回的格式统一,这种不统一的不方便解析吧?
    freefcw
        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 我觉得更合理一些,不知道国内怎么养成个啥都需要的习惯。。
    Building
        7
    Building  
       2022-04-13 20:53:36 +08:00 via iPhone
    根据我的实际体验:
    海外产品的 api 十分简洁甚至十分简单
    大陆产品的 api 十分复杂甚至十分难用
    其实就跟 App 一个德行
    afewok
        8
    afewok  
       2022-04-13 21:09:43 +08:00   2
    是不是又有舔狗鼓吹国外月亮比较圆了?
    chendy
        9
    chendy  
       2022-04-13 21:27:53 +08:00   2
    API 接多了,就觉得还是有 SDK 的香,不用自己接的才是最好的
    liuidetmks
        10
    liuidetmks  
       2022-04-13 22:14:24 +08:00 via iPhon
    @afewok 刚看帖子,有人因为国内很多人把 code 放在 body 里面,解读成这个国家 xxxx
    大受震撼
    hu8245
        11
    hu8245  
       2022-04-13 22:48:19 +08:00
    我比较欣赏 GitHub 的 API ,也比较好套用到自己的理念上
    Goooooos
        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 设计吗?
    binux
        13
    binux  
       2022-04-13 23:03:25 +08:00
    @Goooooos Error responses are served with a non-200-series HTTP code. 许愿帮你翻译吗?
    chendy
        14
    chendy  
       2022-04-13 23:11:05 +08:00
    @Goooooos 只能说接触多的都是国外比较好的东西,做的不好的也基本接触不到,幸存者偏差了
    Goooooos
        15
    Goooooos  
       2022-04-13 23:13:57 +08:00
    @chendy 做广告买量分析,对接过 facebook ,twitter ,google ,tiktok 的 ads api ,我觉得 Facebook 的 graph 是这里面做得最好的一个了
    kakach
        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
    lower
        17
    lower  
       2022-04-13 23:26:19 +08:00
    @chendy 网上有好多聚合了好多个第三方支付平台的开源项目,用起来真的方便,统一的参数配置、初始化、调用接口;不同的参数字段名称、金额单位、加签算法等等都转换封装好了,设计模式用的很 6……有的把依赖安装方式都打好了,美滋滋,用完扫码支付几块钱再感谢作者
    codeMore
        18
    codeMore  
       2022-04-13 23:45:46 +08:00
    @lower 劳烦推荐一个,借鉴学习一下
    xuanbg
        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 本来就是传输协议啊。这。。。没毛病啊。
    Goooooos
        20
    Goooooos  
       2022-04-14 08:45:28 +08:00
    我觉得用 http 状态码,还是 200 一把梭都不是问题
    只要能保证一致就好了,不要这个接口这样定义,那个接口又那样定义
    yuxiu
        21
    yuxiu  
       2022-04-14 09:38:47 +08:00
    google 返回长度为 0 的内容,这么反人类吗,直接设 204 不就好了
    dayeye2006199
        22
    dayeye2006199  
       2022-04-14 11:54:09 +08:00
    推荐 shopify 的 API ,文档清晰,风格一致: https://shopify.dev/api/admin-rest
    looplj
        23
    looplj  
       2022-04-14 13:19:26 +08:00
    Shopify API 设计还行,但是有些 API 很难用。
    可以参考 stripe 。

    API 设计也是要看场景的,Open API ,比如 Shopify ,Stripe 这种,国外一定是 RESTful 的,状态码也是按规范的。
    但是用户 API ,就并不一定了,因为 RESTful 表达能力有限。
    freeup
        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 我也会有这段逻辑

    以上仅是我们系统是这样做的,不代表任何群体,任何观点,我只是陈述我们系统是怎么做的而已。。。

    存在即合理,没有绝对的正确与绝对的错误,没有最好的设计,只有最合适的设计。。。。。

    如果看完你不认同这个 一定淡定 淡定 不要喷我。。。。。
    2kCS5c0b0ITXE5k2
        25
    2kCS5c0b0ITXE5k2  
       2022-04-14 15:05:47 +08:00
    用啥都可以. 把文档写好就行.
    jjwjiang
        26
    jjwjiang  
       2022-04-14 15:14:27 +08:00
    建议看看 github 的
    gmywq0392
        27
    gmywq0392  
       2022-04-14 18:01:18 +08:00
    看 Stripe 和 Deutsche Bank
    pigspy
        28
    pigspy  
       2022-04-15 09:21:23 +08:00
    这跟崇洋媚外太大关系,就纯粹是有些(脏话)原教旨主义者扯着外国人的大旗来规训国内码农了
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     852 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 22:20 PVG 06:20 LAX 15:20 JFK 18:20
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86