
首先我大量查阅了 V2EX 、知乎的讨论,发现前后端主流做的合作方法都是:
但是,在实践中,我发现了一些问题:
起草文档阶段往往是非常暂的。在这个过程中,开发者无法了解系统全貌,自然无法确定完接口列表。随着前端和后端的开发工作的推进,这些忘记的接口、需要修改的接口才逐渐暴露,这会增加前后端合作、沟通的时间成本。
那么,在起草文档阶段,是否有一个系统的方法,来确保最小化这种需要增加、修改的接口数量?
1 pmyile 2020-06-16 11:16:06 +08:00 交互评审的时候 走一遍 接口交互 |
2 gz911122 2020-06-16 11:17:00 +08:00 在起草文档阶段,是否有一个系统的方法,来确保最小化这种需要增加、修改的接口数量 : 后端先定好技术方案, 再商议接口文档,变更会小很多. |
3 pushback 2020-06-16 11:23:31 +08:00 不改需求不就没修改了么。 |
4 hantsy 2020-06-16 11:24:30 +08:00 对于开发阶段变化太快了,又臭又长的文档根本不可能用来做约束。 CDC 模式( Consumer Driven Contract )是一种很好的用于 API 协议开发 Pattern,API Producer 和 Consumer 之间先定好协议 Contract,生成 Stub 之类的,再分开开发实现,最终两边都是要通过相关的 Contract 测试。 自己查看 Pact 使用,支持各种语言。 另外 Spring 下的 Spring Cloud Contract 也一样,对 Spring 生态支持一流,还可以定义 Message Broker 之间的协议,只是对前端语言框架支持不如 Pact 好。 |
5 yidinghe 2020-06-16 11:27:14 +08:00 via Android 前端只关注布局、风格、交互效果和响应性,内容通过后端发来的元数据渲染出实际的界面元素,比如表单有哪些字段等等。 |
6 Kilerd 2020-06-16 11:38:00 +08:00 果然会出现 spring cloud contract,那玩意写起来简直是灾难,然后团队无一例外的转向了 moco |
7 rapiz 2020-06-16 11:52:34 +08:00 突然想,有没有这样的工具,在开发初期可以用图形界面之类快速设定接口格式,可以生成 openapi 文档,然后向前端提供后端的 mock 代码,向后端提供对应框架自动生成的接口代码。 |
8 carbrokers 2020-06-16 12:00:46 +08:00 歪个楼,做过一个项目,后端把数据库所有能取到的字段全部给前端了,后期完全不需要接口变更,所以后续的开发任务后端完全没有参加过。。。 |
9 skypyb 2020-06-16 12:03:41 +08:00 via Android 产品:新加一个小需求 /小改动 |
10 xiangyuecn 2020-06-16 12:07:15 +08:00 前后端靠背坐: 前端要数据转身拍拍后面那家伙:兄 di 给数据 后端改了接口转身揉揉后面那妹纸:接口字段又改了哈 有争论?互殴解决 |
11 faceRollingKB 2020-06-16 12:12:38 +08:00 个人经验:这种问题几乎无法避免,所以技术上我选择用 typescript 开发,方便日后改接口定义,另外如果接口定义问题比较大(概率小),通常涉及到组件、模块的重构,所以我选择用 ng 框架,重构代价小 |
12 Jackeriss 2020-06-16 12:14:10 +08:00 via iPhone graphql |
14 lenqu 2020-06-16 12:26:00 +08:00 可以参考我之前未做完的一个的东西,API 接口的一个中间件,在后端接口之上进行统一规范化,后端只完成最小单元接口实现,中间件进行整合提供服务 有需要的联系我哦!!!一起做 |
16 Foxkeh 2020-06-16 12:32:17 +08:00 @carbrokers 你说的"所有", 包括用户的密码字段吗 |
19 Justin13 2020-06-16 12:41:26 +08:00 via Android 上 GpaphQL |
20 hantsy 2020-06-16 12:51:39 +08:00 @chendy 这两个东西只要你的团队一直坚持写测试,一般不会有什么太大的问题。restdocs 我之前一个项目下来一直在用,用于 API 开发文档生成。 Spring Cloud Contract 有一定局限性,对于全部后端 Microservice 中 service 2 service 互操作的测试,优势很明显。但前后端调用,虽然官方也一直在加强其它实语言支持,也提供了 Nodejs 与 Java 项目结合的例子,但是与前端结合的时候远不如 Pact 舒服。 |
21 slyang5 2020-06-16 12:52:58 +08:00 用 protobuf ? |
23 ChanKc 2020-06-16 13:05:01 +08:00 via Android 理论上,restful 和 hateoas 就是为了解决这个问题的。 当然实际上,restful 已经变成了“有比较好看的 URL 的 API”的意思了 |
24 ty89 2020-06-16 13:17:09 +08:00 @carbrokers 这样别人爬你数据就太方便了,简直就是直接复制你的数据库 |
25 hantsy 2020-06-16 13:18:07 +08:00 @chendy 以前我觉得比较难受是用 Json Schema 定义( jsonschema.org ,这个也是标准 draft)把交互格式都是定好。 有在线工具 https://jsonschema.net/home 然后前后全部写测试验证符合就行了,这个比较直接。 后端 Java 可以用 RestAssured (包括 Jsonschema vilidator)验证. 前端按 JsonSchema 定义生成 json data 文件测试中 mock 就可以了。 |
26 ty89 2020-06-16 13:19:24 +08:00 从根本上的解决方案应该是 TDD, 测试驱动开发。 尤其是后端。 |
27 hantsy 2020-06-16 13:33:57 +08:00 |
28 zzzmh 2020-06-16 13:45:08 +08:00 1. 生成文档,我们用 swagger,另外还有一个 apidoc 生成放到静态服 2. 我要是能帮前端写掉一部分的代码尤其是逻辑类的,我会实现一版 demo 3. 再有分歧就互掐 |
29 houfeibin 2020-06-16 13:46:08 +08:00 @carbrokers 感觉你这样数据会很不安全 |
30 hantsy 2020-06-16 14:04:28 +08:00 @zzzmh Swagger 结合其它的一些工具,也可以生成不错的静态文档,https://github.com/hantsy/building-restful-apis-with-springmvc-gitbook/blob/master/swagger.md#documents-rest-apis |
31 noobsheldon 2020-06-16 14:07:01 +08:00 |
32 noobsheldon 2020-06-16 14:07:45 +08:00 |
33 ISSSSSSS 2020-06-16 15:03:20 +08:00 所以必然要有联调试过程。 |
34 index90 2020-06-16 15:15:08 +08:00 如果一个软甲只加代码不修改,是几乎不会出错的。接口也一样,不存在修改接口,只有加接口,用 /v1/xxx /v2/xxx 去区分。 |
35 la2la 2020-06-16 15:33:27 +08:00 后端开发搬着笔记本做到前端小姐姐旁边调 |
36 Seneca 2020-06-16 15:35:23 +08:00 我们是后端写接口,前端等着接口来了,直接调用就行。给你啥你用啥 |
37 xff1874 2020-06-16 15:45:40 +08:00 我们目前正在做这个事情,原理就是读取定义的接口和真实的请求,然后做比对 |
38 stevenkang 2020-06-16 16:38:14 +08:00 需求来了,基本上过一遍就能把接口定下来。 要改接口一般都是由于需求不明确(或自己没理解到位)、需求变更等原因。 这种情况下改一下接口就行了,毕竟改需求前端后端不都得过一遍嘛。 |
39 lplk 2020-06-16 16:59:43 +08:00 @carbrokers #8 我就这样搞过,虽然很省事,但是如果后期表格字段不断增加,这样会增加网络传输数据的时间,甚至有的字段会很大,最好还是严格规范 |
40 msg7086 2020-06-16 17:02:41 +08:00 改接口 = 改文档,然后前段照着文档来不就行了。 BDD/TDD 很多框架都可以根据测试数据来生成文档的。 |
41 jinwyp 2020-06-16 17:04:38 +08:00 很简单啊 找个资深前端定接口, 前端把界面开发完成 50%后 定的接口基本差不多了。 |
42 Aprilming 2020-06-16 17:05:22 +08:00 前端就给我画样式,接口啥的都是自己来写,自己对接,前端逻辑也是自己写。我的前端伙伴就是一个无情的 UI 机器人 |
43 Airon 2020-06-16 17:08:35 +08:00 交互能明确确认,确认完交互后端就能先出 mock,这样前后端开发就没啥影响。但是问题在于,需求是否真的明确这么细,产品是否完全不变动交互流程 (ps:很多傻逼产品明明自己确认的交互,开发出来还逼逼赖赖 技术们开发不考虑用户体验。。。然后又是改流程改接口) |
44 xuanbg 2020-06-16 17:09:49 +08:00 起草文档阶段往往是非常短暂的,这个是有问题的。设计的必要时间还是要留的,好的设计能够有效减少写代码和测试的时间。所谓磨刀不误砍柴工。 |
46 Sapp 2020-06-16 20:02:51 +08:00 你想要一次性拿全接口,如果是小项目开发有可能,只需要找个经验丰富的后端,他基本能 cover 你所有的需求,提供的接口一点不会少,妥妥的够你用,你想到的问题他都提前想到了,但是大项目基本不可能,一是你没办法招到那么多好后端,二是大项目本身就面临着需求变更,如果一开始就商量好所有的变更,我不说现实不现实,你们坐着开会都要开多久?开会的时间都可能比开发的时间长, 更何况真的能坐在会议桌就考虑到所有的问题? 所以这方面就不要指望能完全搞定了。但是有另一个方法,可以减少接口变更带来的前后端成本,就是 typescript + 动态生成接口,前端不需要手写 ajax 请求,直接调用 node 根据后端文档生成好的请求方法, 例如: const [getUsername, loading] = useRequest(getUsernameRequest) useeffect(() => { getUsername({userID: xxx}) }, []) getUsernameRequest 直接生成的,同时生成了 interface 文件。 同时因为 typescript 的类型要求,前端也根本不需要看文档就能知道需要输入那些参数,并且你提到的后端改了接口,把 userID 改为了 userId,那么前端会直接收到 typescript 的报错提示,然后顺手改一下就行了。如果是改了接口名字,那么前端看一下 git 记录就知道你改了哪些名字,也不需要在口头沟通,或者等测试报错才知道你改了接口。 这样对于后端而言省了每天提醒前端我又改了什么什么的时间,对于前端省了每天要找后端对你又改了什么什么,怎么我测试的时候还没问题,测试一测就又出问题的时间,还少写了 interface 文件。 |
47 6IbA2bj5ip3tK49j 2020-06-16 20:14:58 +08:00 spring cloud contract 真的是垃圾,道理我都懂,用起来就是难用。 一个简单的 json array 为空列表 -> 合法 json array 不为空 -> 判断里面 item 字段 都做不到(只能通过很恶心的办法实现 |
48 zqx 2020-06-17 06:52:33 +08:00 via Android 需求评审-设计交互评审-前端和后端分别技术评审,然后再出接口文档,再开发,基本不会改了,除非产品需求变更了 |
50 hejingyuan199 2020-06-17 11:20:54 +08:00 我没有认真读前面的留言。不好意思。 我们的做法是,后端先把基础弄起来后。 前端给我们一个接口清单,我们去做。 毕竟前端跟客户最贴近。 不过如果遇到前端太胡闹的时候 就得吵吵架。 让前端提要求以后, 他们就不太 BB 地改需求了, 毕竟理亏在他们。 |
51 sunxiansong 2020-06-17 14:09:27 +08:00 与其避免接口变化不如拥抱变化,让变化可控、可测试、可追踪 - 首先会有一份 api 风格说明,说明一般的通用的数据结构风格、错误处理、token 机制 - 后端通过 cli 工具导出后端模型到前端的 ts 结构,前端可以拷贝或直接使用数据模型。导出的代码也包含了可能的错误码、常量枚举 - 后端直接写 ts http 调用的代码,并附上最小可测试代码( jest 测试代码),在代码中标注文档(状态码、错误码等),这步其实主要是 route 标注,前端甚至可以直接复用 http 调用的代码 - 生成的 ts 数据结构和 http 调用代码放在 git 上,提交时填写恰当的注释标注 api 变更,这步主要是确保前端可以详细的跟踪 api 变动,前端可以 watch 文档工程追踪 api - 时间充足的话,最好还是写足够的 api 集成测试 我以前还做过其他的尝试,在测试环境用 AOP 拦截请求,用 json schema 记录请求的 route/request body/response body,然后写到数据库里,再人工标注 api 注释,缺点就是首次请求之前不会有记录。 |