您好!
欢迎来到京东云开发者社区
登录
首页
博文
课程
大赛
工具
用户中心
开源
首页
博文
课程
大赛
工具
开源
更多
用户中心
开发者社区
>
博文
>
架构研究:中台与前台的依赖方向(以2个中台api 设计为例)
分享
打开微信扫码分享
点击前往QQ分享
点击前往微博分享
点击复制链接
架构研究:中台与前台的依赖方向(以2个中台api 设计为例)
自猿其说Tech
2021-06-23
IP归属:未知
78240浏览
计算机编程
精益创新
### 1.单向的依赖关系 本文的观点是,对于中台来说, api设计是最重要的设计之一。相对业务闭环的开发时期,api 设计重要性突显,api 定义是产品定义的重要组成。 本文提出一个观点: 从api 角度,中台不依赖前台 。有2个含义: - 中台提供的api 尽量不参杂任何具体某个前台业务的语义。 - 前台对中台的扩展,中台是无感的,就是是不需要专门上线的 。 下边结合一些具体的例子进行研究,然后研究一些业界的案例。 **缺点:** 这种单向的依赖关系,对于api 设计的要求是很高的。 **优点:** 中台独立发展 。 以上2个含义,用2个词 ① 最少知识 ② 易扩展性 <center>![](//img1.jcloudcs.com/developer.jdcloud.com/a6fe40b3-5526-4616-836d-3ae46f155b6520210623143107.png)</center> 下边的案例研究,考察案例的这2个方面 。 ### 2.案例研究 本文的案例,不是线上的,仅供研究使用。 #### 2.1产品校验api 这是pms一个校验用户下单前信息是否合规的接口的设计: ```java CheckProductResponse checkProduct(RequestProfile requestProfile, CheckProductRequest checkProductRequest); public class RequestProfile implements Serializable { private String traceId; private String tenantId; private String locale; private String timeZone; private HashMap<String, Object> ext = new HashMap(); } public class CheckProductRequest implements Serializable { private BusinessIdentity businessIdentity; private ChannelInfo channelInfo; private CustomerInfo customerInfo; private ConsignorInfo consignorInfo; private ConsigneeInfo consigneeInfo; private List<CargoInfo> cargoInfos = new ArrayList<CargoInfo>(); private List<ProductInfo> productInfos = new ArrayList<ProductInfo>(); private FinanceInfo financeInfo; private ShipmentInfo shipmentInfo; private Map<String, String> extendProps = new HashMap<String, String>(); } public class CheckProductResponse implements Serializable { * 返回码值 1:通过,-1:失败(未知异常),主流程校验不通过码值,例如必要参数校验不通过。 private String code; private String message; * 产品校验结果对象,Key为主产品编码,Value为此产品包含的校验信息。 private List<ProductResult> productResults = new ArrayList<ProductResult>(); * 如果存在降级产品,则将包含降级的全部结果放入此list private List<ProductResult> degradeProductResults = new ArrayList<ProductResult>(); } ``` **2点考察:** ① 最少知识 CheckProductRequest 不包含具体某个前台的语义,具有独立性。 ② 易扩展性: CheckProductRequest 是一个具体的类,虽然留了 extendProps, 但是是否具有可扩展性,取决于谁去理解这些properties, 如果是中台,就不具备本文所说的可扩展性含义。 考察结论: 这个api不依赖于前台的语义,易扩展性待考察。 #### 2.2 接单api ```java [ { "businessUnit": "", "ext": { "1": "test" }, "locale": "zh-CN", "tenantId": "1000", "timezone": "GMT+8", "traceId": "236209028496559" }, { "businessUnit": "1", "cargoInfos": [ { "cargoHeight": "2", "cargoLength": "2", "cargoName": "玩具枪测试商品", "cargoQuantity": 3, "cargoVolume": "23.9900", "cargoWeight": "0.1", "cargoWidth": "2" } ], "channelNo": "0010001", "channelOrderNo": "12010201092151", "consigneeInfo": { "consigneeAddress": "北京大兴区亦庄经济开发区科创十一街18号院", "consigneeCityName": "大兴区", "consigneeCityNo": "2810", "consigneeCoordinateType": 1, "consigneeCountyName": "亦庄经济开发区", "consigneeCountyNo": "51081", "consigneeLatitude": "39.786289", "consigneeLongitude": "116.563599", "consigneeMobile": "13717847870", "consigneeName": "王雅楠测试", "consigneePhone": "15801338888", "consigneeProvinceName": "北京", "consigneeProvinceNo": "1", "consigneeTownNo": "0" }, "consignorInfo": { "consignorAddress": "科创十一街18号院", "consignorCityName": "大兴区", "consignorCityNo": "2810", "consignorCoordinateType": 1, "consignorCountyName": "亦庄经济开发区", "consignorCountyNo": "51081", "consignorLatitude": "39.78871998", "consignorLongitude": "116.56803131", "consignorMobile": "010-10058655", "consignorName": "郭玉锐1", "consignorPhone": "15801338888", "consignorProvinceName": "北京", "consignorProvinceNo": "1", "consignorTownName": "", "consignorTownNo": "1123" }, "customerOrderNo": "WYG123456115", "deliveryFulfillmentNo": "010K0417", "financeInfo": { "settlementType": 1 }, "productInfos": [ { "productNo": "ed-m-0001" } ], "remark": "aaaaa", "shipmentInfo": { "deliveryType": 1, "expectDeliveryEndTime": 1600235919690, "expectDeliveryStartTime": 1600063119690, "expectPickupEndTime": 1609332617000, "expectPickupStartTime": 1606740617000, "pickupType": 1 } } ] ``` **2点考察:** ① 最少知识 不依赖具体承运商的特殊知识, 具有独立性。但是有些信息有点多,譬如 “traceId, consignorLatitude" ② 易扩展性: api 留有扩展点,具体如何用未知。 **考察结论:** 这个api 有一些多余的知识,有扩展性。 ### 3.api 产品研究 研究一下这2个案例的相关的业界的一些产品。 #### 3.1ship engine , api 服务商 https://www.shipengine.com/ 这是一个 api 服务商。 它代理了很多真实物流商的 api。 这是它的api 的价值: <center>![](//img1.jcloudcs.com/developer.jdcloud.com/7bc6d5a9-9f6b-4708-b942-1c1aa2a31bc420210623143438.png)</center> 一个api 的例子: ##### 3.1.1update shipment 的api https://shipengine.github.io/shipengine-openapi/#operation/update_shipment ```java { "carrier_id": "se-28529731", "service_code": "usps_first_class_mail", "external_order_id": "string", "items": [], "external_shipment_id": "string", "ship_date": "2018-09-23T00:00:00.000Z", "ship_to": { "name": "John Doe", "phone": "+1 204-253-9411 ext. 123", "company_name": "The Home Depot", "address_line1": "1999 Bishop Grandin Blvd.", "address_line2": "Unit 408", "address_line3": "Building #7", "city_locality": "Winnipeg", "state_province": "Manitoba", "postal_code": "78756-3717", "country_code": "CA", "address_residential_indicator": "no" }, "ship_from": { "name": "John Doe", "phone": "+1 204-253-9411 ext. 123", "company_name": "The Home Depot", "address_line1": "1999 Bishop Grandin Blvd.", "address_line2": "Unit 408", "address_line3": "Building #7", "city_locality": "Winnipeg", "state_province": "Manitoba", "postal_code": "78756-3717", "country_code": "CA", "address_residential_indicator": "no" }, "warehouse_id": "se-28529731", "return_to": { "name": "John Doe", "phone": "+1 204-253-9411 ext. 123", "company_name": "The Home Depot", "address_line1": "1999 Bishop Grandin Blvd.", "address_line2": "Unit 408", "address_line3": "Building #7", "city_locality": "Winnipeg", "state_province": "Manitoba", "postal_code": "78756-3717", "country_code": "CA", "address_residential_indicator": "no" }, "confirmation": "none", "customs": { "contents": "merchandise", "non_delivery": "return_to_sender", "customs_items": [] }, "advanced_options": { "bill_to_account": null, "bill_to_country_code": "CA", "bill_to_party": "recipient", "bill_to_postal_code": null, "contains_alcohol": false, "delivered_duty_paid": false, "dry_ice": false, "dry_ice_weight": { "value": 0, "unit": "pound" }, "non_machinable": false, "saturday_delivery": false, "use_ups_ground_freight_pricing": null, "freight_class": 77.5, "custom_field1": null, "custom_field2": null, "custom_field3": null, "origin_type": "pickup", "collect_on_delivery": { "payment_type": "any", "payment_amount": { "currency": "usd", "amount": 0 } } }, "origin_type": "pickup", "insurance_provider": "none", "order_source_code": "amazon_ca", "packages": [ { "package_code": "small_flat_rate_box", "weight": { "value": 0, "unit": "pound" }, "dimensions": { "unit": "inch", "length": 0, "width": 0, "height": 0 }, "insured_value": { "0": { "currency": "usd", "amount": 0 }, "currency": "usd", "amount": 0 }, "label_messages": { "reference1": null, "reference2": null, "reference3": null }, "external_package_id": "string" } ], "validate_address": "no_validation" } ``` 这个api 代表了 shipping 的关键因素以及一些扩展点。proxy 与被proxy 的语义是一致的,范围大小不同。 在验证方面,有地址验证api。 https://shipengine.github.io/shipengine-openapi/#tag/addresses 这个api产品,对本文的观点的帮助在于,api 服务商proxy 了很多真实承运商的api, 有点类似交易中台的位置。 <center>![](//img1.jcloudcs.com/developer.jdcloud.com/a7b75cb2-3a4e-48c4-8b68-e641ee7afbbc20210623143621.png)</center> ### 4.对案例的另外几种设计 在研究的基础上,对于2个api 案例,尝试另外的一些设计。在api 设计的时候,也进行多种方案的比较,是比较好的实践。 #### 4.1 产品校验 案例中的api 的可扩展性是待研究内容。 产品的校验,不同的产品校验逻辑不交叉,似乎没必要集中处理。 ##### 4.1.1 不提供集中校验 ① 不提供集中的校验服务,可以提供一些工具服务。 ② 可以代理各个前台的校验服务 #### 4.2接单 可考虑去掉一些多余的知识,添加一些必要的知识 。 具体不再展开。 ### 5.结论 本文从案例的角度,研究了依赖相关的中台api 设计的一些原则。参考了国外api服务商的一些做法。 依赖研究是企业架构的一个重要方面,希望对于中台架构有所帮助。 ### 参考 **这是一个api 服务商** https://www.shipengine.com/shipping/ https://shipengine.github.io/shipengine-openapi/#operation/update_shipment https://www.altexsoft.com/blog/shipment-tracking-integration-apis-edis-carriers-aggregators/ **vtex 的api 列表** https://developers.vtex.com/vtex-rest-api/reference/logistics-api-overview ------------ ###### 自猿其说Tech-JDL京东物流技术发展部 ###### 作者:中台技术部-仓储平台组 李建奇
原创文章,需联系作者,授权转载
上一篇:spring七种事务传播行为
下一篇:当我们谈论前端组件化的时候,我们在谈论什么
相关文章
Taro小程序跨端开发入门实战
Flutter For Web实践
配运基础数据缓存瘦身实践
自猿其说Tech
文章数
426
阅读量
2149963
作者其他文章
01
深入JDK中的Optional
本文将从Optional所解决的问题开始,逐层解剖,由浅入深,文中会出现Optioanl方法之间的对比,实践,误用情况分析,优缺点等。与大家一起,对这项Java8中的新特性,进行理解和深入。
01
Taro小程序跨端开发入门实战
为了让小程序开发更简单,更高效,我们采用 Taro 作为首选框架,我们将使用 Taro 的实践经验整理了出来,主要内容围绕着什么是 Taro,为什么用 Taro,以及 Taro 如何使用(正确使用的姿势),还有 Taro 背后的一些设计思想来进行展开,让大家能够对 Taro 有个完整的认识。
01
Flutter For Web实践
Flutter For Web 已经发布一年多时间,它的发布意味着我们可以真正地使用一套代码、一套资源部署整个大前端系统(包括:iOS、Android、Web)。渠道研发组经过一段时间的探索,使用Flutter For Web技术开发了移动端可视化编程平台—Flutter乐高,在这里希望和大家分享下使用Flutter For Web实践过程和踩坑实践
01
配运基础数据缓存瘦身实践
在基础数据的常规能力当中,数据的存取是最基础也是最重要的能力,为了整体提高数据的读取能力,缓存技术在基础数据的场景中得到了广泛的使用,下面会重点展示一下配运组近期针对数据缓存做的瘦身实践。
自猿其说Tech
文章数
426
阅读量
2149963
作者其他文章
01
深入JDK中的Optional
01
Taro小程序跨端开发入门实战
01
Flutter For Web实践
01
配运基础数据缓存瘦身实践
添加企业微信
获取1V1专业服务
扫码关注
京东云开发者公众号