V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
beneo
V2EX  ›  程序员

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

  •  
  •   beneo · 2017-05-05 14:51:36 +08:00 · 4771 次点击
    这是一个创建于 2763 天前的主题,其中的信息可能已经有所发展或是发生改变。
    我们的架构是前后端分离的,我是写 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   ·   实用小工具   ·   5078 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 29ms · UTC 09:46 · PVG 17:46 · LAX 01:46 · JFK 04:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.