数据解耦,才是前后分离的本质

时间:2022-04-27 05:59:36

用产品思维设计API(二)——数据解耦,才是前后分离的本质 前言

最近公司内部在重构项目代码,包括API方向的重构,期间遇到了很多的问题,不由得让我重新思考了下。
- 一个优雅的API该如何设计?
- 前后端分离之后,API真的解耦分离了吗?
- 不断的版本迭代,API的兼容性该如何做?

ps.这里所说的API仅为Web API,提供APP\WEB开发使用。

年前,我司内部的接口已经进入了一个完全的重构阶段,参考了市面上各大平台的API和文档,自己也总结出了很多的心得。这里向大家分享一下,接下来一个月,我们向从下面几个方面向大家介绍一个优雅的API(至少我认为挺优雅)该如何设计。

RESTful就是个骗局 ()

数据解耦,才是前后分离的本质()

版本控制,没有你想的这么简单

随意定义错误码,你还在这样干?

安全,就只能用HTTPS?

ps. 打一个广告,公司内部现在在招聘各种技术岗位,Java、Android、前端等,待遇保证能让你涨30%,有兴趣的朋友可以加韬哥的微信(微信号:stchou_zst),二维码在文章最后。

明确需求就开始研发,哪里错了?

一个移动应用的从无到有,必须经过需求讨论、交互/UI设计、数据库设计、API设计、APP开发、联调、测试等阶段。而在整个研发的流程中API的设计有起到了承上启下的作用。

我们这里从新回顾一个APP迭代的开发流程:

需求 —— 采用用例图描述需求

分析 —— 明确解决问题的细节

设计 —— 给出交互、设计解决方案

开发 —— 将类用某面向对象语言实现

测试 —— 单元测试等

通常,我们都会在需求理清楚之后,产品给出交互图就开始了整个数据库设计、UML、API开发等等。

数据解耦,才是前后分离的本质

等等,貌似有哪里不对。设计出来之后,对接的人往往是前端\客户端研发同事,后台同事只管需要下发哪些数据,真的不需要理解前端的交互吗?

数据展示型API——面向用户设计

作为后端研发人员,你的用户是谁?——毫无以为,肯定是调用API的其他段的开发同事。那么API的开发就得对用户负责(负责,并不仅是写一个方便阅读的文档而已)。

Android、iOS、H5三端的同事如何调用的你的API?

他们在调用你的API绘制界面上使用是否费劲?

后期迭代中API能否兼容?

客户端是否要发版?强制更新?

……

都是你需要考虑的。

这里我们也不卖关子,直接说出鄙人得出的结论:

需要参与计算的值统一按照存储类型下发,仅作为显示的值统一按字符串下发。

### 后台研发:前端展示关我屁事!

我们的结论说起来很简单,但是在实际的工作中我们能够看到,许多的同事并没有一个全局的可发展的思维,我能做出来就行了,需要的数据都有,你们怎么展示,怎么交互我不管了。

ps.越是在大型企业之中,牛人越多,牛人越多的地方自以为是的人就越多。别问我怎么知道的,鬼知道我经历了什么。

多说无益,马上来个Demo,如下所示,我们要做一个产品的详情页:

数据解耦,才是前后分离的本质

这个页面看起来功能并没有多少,简单分析一下:

4个跳转按钮

一个展示内容的Tab

一个头部特殊展示信息。

大概估算一下客户端研发时间,3天左右,够了。

Ok,当你你屁颠屁颠的向上级汇报你的工作量完了之后,1天后API开发好了,简单的调了一下API你瞬间就石化了。API返回结果如下:

JSON
{
"totalCount": 99,
"data": [
{
"id": 8055,
"sTitle": "浙金信托-汇城47号",
"productTypeId": 1,
"zdPrice2": 0.93,
"nianHuaShouYiStart": 6.7,
"nianHuaShouYiEnd": "7.0",
"jdt": 0,
"touZiLingYu": "基础设施类",
"level": 99,
"saleStatus": 20,
"category": 30,
"jdTime": "2017-01-04 09:33:27",
"raiseProgress": "【2017年1月4日9时更新】本期第一期,本期规模不限,开放打款中,封账时间根据进款情况安排,有下一期。(三大一小配比,需要录音录像)",
"touZiMenkan": 100,
"collectCount": 4,
"hasCollect": false,
"redPack": "",
"fundType": null,
"visitCount": 47315,
"docPreviewCount": 4,
"producttagids_intarray": "\t13\t4\t71",
"productTags": "4,基础设施类;13,固定收益类;71,三年期;",
"title": "浙金信托-汇城47号(第1期)",
"bid": 1,
"statusId": 40,
"qiXian": 36,
"peibi": "三大一小配比",
"pmName": "王月",
"pmUserName": "王月",
"daXiao": "严格配比",
"lingYu": "基础设施类",
"shouYiType": "固定收益类",
"payStatus": "半年付息",
"downLoad": "Upload/ProductPDF/20161223/浙金-汇城47号_521.zip",
"groupName": null,
"zdPrice": 0.5,
"addr": null,
"companyId": 23,
"adminId": 521,
"groupMaxPrice": 0,
"nianHuaShouYiExt": "",
"companyName": "恒天",
"fxList": [
{
"title": "100万≤X<300万",
"price": "0.93%",
"isFloat": false,
"earningRate": "6.7%",
"packingRate": 6.7
},
{
"title": "300万≤X",
"price": "0.5%",
"isFloat": false,
"earningRate": "7%",
"packingRate": 7
}
],
"sourceRepayment": "1.安顺市西秀区财政收入\n2.融资人西秀城投的经营收入\n3.担保人西秀工投的经营收入",
"fundInvest": "用于受让西秀城投持有的对西秀区*的标的债权",
"windControl": "1.安顺市西秀区工业投资(集团)有限公司提供连带责任保证担保\n2.受让西秀城投对西秀区*已纳入国务院地方债务系统的8.05亿应收账款",
"highlights": "市场稀缺*《预案》承认地方*存量债务政信、发债融资主体16年11月已发行15亿7年期债券完全覆盖本次融资本息及期限!",
"productOrganizationId": 307,
"productOrganizationPic": "Upload/ProductOrganization/20160118/2016011818020432129312.jpg",
"bqqsr": "2017-01-03 00:00:00",
"province": 520000,
"proviceName": "贵州省",
"cityName": "安顺市",
"dyl": -1,
"addrId": null,
"updateTime": "2017-01-04 17:58:13",
"listingTime": "2016-12-23 16:29:35",
"parentId": 8055,
"phase": 1,
"issuerCompanyId": 0,
"issuerCompanyName": "",
"issuerId": 2492,
"issuerPhone": "13552818811",
"issuerName": "陈敏 ",
"project": 3,
"attr": 3,
"jianBan": "",
"appointmentCount": 5,
"downloadCount": 716,
"sendEmailCount": 21,
"cashback": "",
"tagsArray": [
{
"id": "13",
"name": "固定收益类"
},
{
"id": "4",
"name": "基础设施类"
},
{
"id": "71",
"name": "三年期"
}
],
"bestEarningRate": "7%",
"bestEarningRate_fore": 7,
"bestEarningRate_back": "0",
"bestPrice": "0.93%",
"bestPrice_fore": 0,
"bestPrice_back": "93",
"bestGroupPrice": "待定",
"bestGroupPrice_fore": "待定",
"bestGroupPrice_back": 0,
"bestEmployeePrice": "待定",
"bestEmployeePrice_fore": "待定",
"bestEmployeePrice_back": 0,
"saleStatusName": "在售",
"isNew": false,
"isHot": false,
"isHotSale": true,
"isRecommend": false,
"packingRate": 0,
"returnCash": 0
}
],
"isSuccess": true,
"code": 0,
"runSpanTime": 41
}

不就是展示页面吗?也没啥交互啊!也没有什么逻辑处理啊!为什么这么难?

看完之后,我相信估计没有一个人是在不看文档的情况下能理解每一个字段是什么信息的。一系列的问题随之出现。

产品名字”是哪个字段?该在哪里展示?

大小配比”是哪个字段?该在哪里展示?

发行机构”是哪个字段?该在哪里展示?

产品期限”是哪个字段?该在哪里展示?

………

是不是要建立一个大的Bean来存储这个对象?

是不是要缓存里面信息?本地缓存数据库怎么建立?

同级别的产品类型还有13个,是不是每一个类别我都得看一次文档,重复一下这个恶心的事。

………

当然,我们不能这么做,这个API让调用它的研发者感到恶心,就是没有服务好用户。

API从数据上必须解耦,不能将整个数据库的理解扔给前端。

重新设计!!!!按照解耦法则分析一下这个页面: