关于 API 的设计,是一个 API 包含三个结构体还是每个 API 一个结构体呢? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
beneo
V2EX    程序员

关于 API 的设计,是一个 API 包含三个结构体还是每个 API 一个结构体呢?

  •  
  •   beneo 2017-05-05 14:51:36 +08:00 5151 次点击
    这是一个创建于 3083 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我们的架构是前后端分离的,我是写 Java 的,要向 App、H5、PC 等提供接口;之前我们的业务比较简单,基本上一个页面一个 API,慢慢业务起来了,API 的返回结构体开始复杂,我们后端也开始做复用和抽象;

    今天和 App 开发争论一个问题。App 上有个页面,里面分成三大块,每块都是一个 Excel 的结构体,而且每个 Excel 的结构体,在其他好几个页面上面,都有复用。某一个页面需要一个,另外一个页面需要另一个,这样的情况;

    目前 App 那边一直坚持这个页面只要一个 API,一次返回三个结构体;原因是对用户体验友好。

    而我做后端的觉得,这个 Excel 结构体复用的地方比较多,想做到单一职责,应该分三个 API 来调用;

    我想问问大家怎么看这个问题,有没有比较正确的姿势来解
    28 条回复    2018-07-24 10:20:14 +08:00
    ytmsdy
        1
    ytmsdy  
       2017-05-05 14:56:28 +08:00
    key word: API Gateway
    beneo
        2
    beneo  
    OP
       2017-05-05 14:57:29 +08:00
    @ytmsdy 不明白兄台这个关键词说明了什么问题,请明示
    @ytmsdy
    beneo
        3
    beneo  
    OP
       2017-05-05 14:58:40 +08:00
    @ytmsdy 我们使用 zuul 来做 API Gatway,但是没有解决这个问题
    ytmsdy
        4
    ytmsdy  
       2017-05-05 15:07:09 +08:00
    从后端的角度来说,一个 API 的请求返回值如果过大的话,拆分成几个 API 是合理、正确、明智的。
    API 的返回体过大几个弊端:
    1:最直观的感受就是页面加载速度会下降,前端必须要等待所有的数据都返回以后才能显示。
    2:如果并发量大的话,很容易造成业务的堵塞。
    3:维护不方便
    所以拆分出来是很合理的解决方案。

    但是从前端的角度看
    1:一个 API 拆分成多个 API 以后,打开一个页面需要发送多次请求,增加前端的工作量这是肯定的。
    2:网络延时也是会增加,前端说对用户体验不好也是确实的。
    3:乱七八糟的 API 多了以后,前端也头疼。

    所以之前 amazon 有一篇专门的分享文章来说明他们是怎么来处理这些问题的,具体的你可以搜索一下。
    LZ 也可以去了解一下 API 网关,这应该可以解决 LZ 的问题。
    ytmsdy
        5
    ytmsdy  
       2017-05-05 15:09:20 +08:00
    @beneo 我找一下那篇文章。
    beneo
        6
    beneo  
    OP
       2017-05-05 15:10:31 +08:00
    @ytmsdy 感谢,api gateway amazon 真心不好找
    ytmsdy
        7
    ytmsdy  
       2017-05-05 15:11:38 +08:00
    @beneo 关键词被淹没了~~
    ytmsdy
        8
    ytmsdy  
       2017-05-05 15:15:25 +08:00   1
    @beneo 亚马逊的处理方法,大概是这样的。
    1:后端把 API 拆分
    2:通过 API 网关对 API 进行聚合形成一个新的 API 来返回多个 API 的聚合信息
    3:对外只发布 API 网关聚合后的 API
    as463419014
        9
    as463419014  
       2017-05-05 15:18:26 +08:00
    做一个组合查询的 api
    先做分开做查询 api:get1(),get2(),get3(),get4()....
    然后做一个组合查询 api:getx (args...),这个 api 就是根据参数中的值取查其他的 api 然后把查询结果组合起来一起返回

    需要查 123 组合的结果,就调用 getx(1,2,3),需要 2,4 组合的结果,就调用 getx(2,4)
    这样你可以愉快的按模块拆分 api,做 App 的也可以愉快的使用一个 api 获得查询结果了

    以上内容纯属临时瞎编,考虑不周请见谅
    kalman03
        10
    kalman03  
       2017-05-05 15:27:01 +08:00
    GraphQL
    artikle
        11
    artikle  
       2017-05-05 15:42:39 +08:00
    我们做法要是 API 返回信息过大过多,就考虑拆分为好几个接口,要么多次请求,要么只返回必须字段,另外的不是必须马上显示的信息可以延迟返回。
    你的那种要是一次返回三个结构体的信息量不多,速度可以,请求不是特别频繁,就可以考虑组装一个新 model 返回。反之就拆分
    hotdogwc
        12
    hotdogwc  
       2017-05-05 15:55:43 +08:00
    @kalman03 这个正解,但是有多少个公司可以做到全面使用呢?
    wc951
        13
    wc951  
       2017-05-05 16:12:44 +08:00 via Android
    微服务拆分肯定是每个 api 只负责自己那一摊,再通过 api gatway 之类的整合起来,有点像 esb 里的服务编排
    huijiewei
        14
    huijiewei  
       2017-05-05 16:54:12 +08:00 via iPhone
    restful 的指导意见是拆开
    Numbcoder
        15
    Numbcoder  
       2017-05-05 17:09:02 +08:00
    这个问题明显是 App 开发想偷懒,API 拆分后,可以三个请求同时发起,如果 UI 没有关联的话,那么请求先完成的可以先显示,就算 UI 有关联,三个请求并发发起,肯定也比三个请求串联所花的时间短吧,明显是用户体验更好啊
    beneo
        16
    beneo  
    OP
       2017-05-05 17:12:27 +08:00
    @huijiewei 有文章么?这方面我也看了好几本书,但是没有遇到我说的那种情况,都是该怎么写,header 怎么写什么的
    TypeErrorNone
        17
    TypeErrorNone  
       2017-05-05 17:22:51 +08:00
    我之前的做法是在用 openresty,做个组合接口的功能,后端提供的接口前端可以随意组合。

    ps:这个功能在我离职后被我们牛逼的架构师拆掉了,呵呵
    beneo
        18
    beneo  
    OP
       2017-05-05 17:50:54 +08:00
    @TypeErrorNone 具体怎么弄呢?一般 API 是服务端提供,然后通过 openresty,有生成新的 API,这样好维护么?
    TypeErrorNone
        19
    TypeErrorNone  
       2017-05-05 18:01:21 +08:00
    前端一次 post 多个接口地址,openresty 就是并发请求接口,组合接口内容,响应给前端。
    这是代码 https://github.com/kangkang66/dockerlnmp/blob/openresty/nginx/lua/kang.lua
    pioneer
        20
    pioneer  
       2017-05-05 19:17:50 +08:00 via iPhone
    哈哈哈
    xialdj
        21
    xialdj  
       2017-05-05 19:24:09 +08:00 via iPhone
    你需要 graphql 前端爱用什么结构就用什么结构
    Ouyangan
        22
    Ouyangan  
       2017-05-05 21:52:29 +08:00
    按照我的习惯 , 我会拆开 , 至于为什么... 一对比还真想不出什么理由.
    SmiteChow
        23
    SmiteChow  
       2017-05-05 22:35:32 +08:00
    graphql 就是个坑, 远离
    qs
        24
    qs  
       2017-05-06 08:52:42 +08:00
    之前想拆, 被前端拒绝了, 也就没做了。
    caixiexin
        25
    caixiexin  
       2017-05-06 17:24:37 +08:00 via Android
    不知道你们后端服务有没有拆分,有的话,就可以提供一个聚合接口,这个聚合接口的数据通过查询其他几个接口数据后组装而成。
    类似微服务的概念。
    TommyLemon
        26
    TommyLemon  
       2018-07-24 10:14:22 +08:00
    APIJSON 就是一个很好的解决方案啊,
    自动将前端传的 JSON 参数转为 SQL 语句执行并返回结果,
    期间自动校验权限、结构、内容,自动防 SQL 注入。

    通过自动化 API,前端可以定制任何数据、任何结构!
    大部分 HTTP 请求后端再也不用写接口了,更不用写文档了!
    前端再也不用和后端沟通接口或文档问题了!再也不会被文档各种错误坑了!
    后端再也不用为了兼容旧接口写新版接口和文档了!再也不会被前端随时随地没完没了地烦了!

    在线解析
    自动生成文档,清晰可读永远最新
    自动生成请求代码,支持 Android 和 iOS
    自动生成 JavaBean 文件,一键下载
    自动管理与测试接口用例,一键共享
    自动校验与格式化 JSON,支持高亮和收展

    对于前端
    不用再向后端催接口、求文档
    数据和结构完全定制,要啥有啥
    看请求知结果,所求即所得
    可一次获取任何数据、任何结构
    能去除重复数据,节省流量提高速度

    对于后端
    提供通用接口,大部分 API 不用再写
    自动生成文档,不用再编写和维护
    自动校验权限、自动管理版本、自动防 SQL 注入
    开放 API 无需划分版本,始终保持兼容
    支持增删改查、模糊搜索、正则匹配、远程函数等

    后端接口和文档自动化,前端(客户端) 定制返回 JSON 的数据和结构!
    github.com/TommyLemon/APIJSON
    创作不易,GitHub 右上角点 Star 支持下吧,谢谢^_^
    TommyLemon
        27
    TommyLemon  
       2018-07-24 10:17:43 +08:00
    @SmiteChow
    哈哈,看来你是用过了。
    字段、状态码、权限控制、表关联查询... 确实一堆的坑。

    提供自动化 API 的 APIJSON 才是简单高效的解决方案,看上面的回复。

    APIJSON 对比 GraphQL:
    完爆 Facebook/GraphQL,APIJSON 全方位对比解析
    https://juejin.im/post/5ae80edd51882567277433cf
    TommyLemon
        28
    TommyLemon  
       2018-07-24 10:20:14 +08:00
    @Numbcoder
    有关联能并发发起?第二个接口要用第一个接口返回的数据作为参数,并发怎么搞?哪个接口先回调都不清楚
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1332 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 38ms UTC 17:10 PVG 01:10 LAX 10:10 JFK 13:10
    Do have faith in what you're doing.
    ubao 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