草庐IT

开放平台架构指南

编码砖家 2023-03-28 原文

1.前言

2010年前,大型社交网站如腾讯QQ、新浪微博都搭建了开放平台。中小型互联网公司接入开放平台,能够获取社交平台的海量用户,有效的降低获客成本,获得社交平台的其他能力。对于用户而言,用一个社交帐号登录各种网站或APP,体验也会更好。后来,许多行业如电商、金融等都开放了业务核心API。这些行业的竞争非常激烈,公司希望通过开放平台与合作伙伴保持更高效的协作,实现资源交换或者流量变现。

广义的开放平台是个庞大的结构,它站在核心业务系统的前面,承接着所有的流量。公司所有的客户端比如Web站点、手机APP、智能硬件都对接开放平台API,只是各自的权限不同,可以访问的资源不同。狭义的开放平台只是打开了一扇门,让合作伙伴进来参与业务互动。从业务层面上看,开放平台仅仅是流量渠道之一。

本文重点讨论的是狭义的开放平台。

2.需求分析

2.1 总体需求

业务系统相当于酒店,开放平台是专门招待外宾的特殊客房,合作伙伴(以下统称商户)就是外宾。外宾进入酒店有专门的通道,不和其他客户的共用。外宾可以在房间睡觉、点餐,但是不能去其他房间串门。主观上,酒店希望接纳更多的外宾,但是招待能力始终有上限,因此一定要限制外宾活动的频率,否则没有足够的人力招待其他的住客。在系统设计上,开放平台有四个重要的要求:

  • 1)接口访问授权:商户帐号仅能访问被授权的接口,也不允许访问到其他商户的资源。
  • 2)接口访问限流:商户访问接口必须限流,不能对公司的核心系统造成冲击。
  • 3)内部业务隔离:商户最忌讳接口出入参数频繁变化,内部系统要做好业务规划和多版本设计,尽可能保证接口出入参数不变动。
  • 4)数据安全:加密敏感数据,比如用户手机号、银行卡号。
2.2 平台角色

开放平台的使用者只有两个:商户和平台管理员,平台管理员可以划分为超级管理员、商务经理、产品经理。

  • 1)超级管理员:拥有最高系统管理权限。
  • 2)商务经理:商务经理负责与商户洽谈合作事宜,审核商户资料的真实性,推动合作的进度。
  • 3)产品经理:产品经理根据商务经理与商户签订的合同,确定产品流程的细节,解答商户的业务疑问,联合开发人员协助商户对接API。如果有需要,甚至要为商户设计新的API。
2.3 项目构成
  • 1)开放API

商户的开发水平和意愿不一样,接入方式可以分为三种:

  1. 全API:商户端技术人员开发前端页面,后端调用开放平台API,包装为自己的前端接口,串联这些前端接口完成产品流程。
  2. 内嵌H5:商户端技术人员在产品的合适位置嵌入开放平台提供的H5地址,用户可以打开这个地址,完成产品流程。
  3. 内嵌SDK:开放平台提供Android或IOS平台的SDK,商户端技术人员自行集成在产品中,完成产品流程。
  • 2)商户服务系统

商户服务系统至少包含商户入驻、参数配置功能,部分业务还需要佣金结算、订单统计等功能。

  1. 商户入驻:商户先提交企业资料,商务经理审核通过之后,商户才能正常访问开放API。
  2. 参数配置: 配置对接开放API的一些参数,比如接入方式。
  • 3)商户管理系统

商户管理系统主要用于查询、修改、编辑商户信息、审批商户的配置信息以及其他辅助功能。

3.系统架构

3.1 系统架构

采用成熟的分布式组件实现架构,如下图所示:

3.2 业务边界

为了业务的整体可控,核心业务系统不应该迎合开放平台的变化,而是开放平台适配核心系统。开放平台的业务边界是只做渠道功能,不做核心业务,通过调用核心系统的接口完成业务操作。

3.3 数据闭环


核心系统没有意愿保存商户ID或者其他与渠道有关的数据,数据闭环是指商户发起的请求(比如创建订单),先保存在开放平台的数据库,开放平台再向核心系统发起请求。这份数据并不需要特别完整,但是至少包含业务主键。当有需要的时候,通过查询核心系统接口来弥补缺失的数据。自主冗余数据的好处有两点:1.减少了调用链,加快接口查询速度;2.更容易实现根据商户ID分页查询数据、订单统计、佣金结算等功能。

4 API设计

4.1 RESTful风格

接口设计遵循 RESTful 协议,它有下面的特性:

  • 资源是由 URI 来指定,URI 中可以包含请求参数。
  • 对资源的操作如获取、创建、修改和删除,要采用 HTTP 协议提供的动作标识 如GET、POST、PUT 和 DELETE 等。
  • 资源的表现形式可以是XML、HTML、JSON,多数采用JSON。

采用RESTful API的好处有三点:

  • 基于HTTP协议,轻量级,使用广泛
  • 接口设计面向资源,具有自解释性。
  • 以 XML,JSON 做数据交换,格式简单。

在实际的运用中,严格遵循 RESTful 协议有下面三点缺陷:

  • 1)HTTP动词过多

开发人员使用过多的HTTP动词,心智负担较大;用动词标记操作资源满足不了复杂的业务需求,最后还得通过接口名称来区分;某些请求如 PUT、DELETE 可能被中间层设备过滤掉。

  • 2)URL支持参数

URL里面包含参数占位符比如GET /Api/Orders/{id}/OrderItems/{id},阅读性不佳。如果根据 URL 来统计接口调用次数,分析系统需要额外处理相同地址不同参数的情况。

  • 3)HTTP状态码表现力不足

通过20X、30X、4XX、5XX等有限的响应码无法表达复杂的业务状态。

为了解决以上三点缺陷,建议接口遵循如下规范:

  • HTTP 动词仅采用 GET、POST。
  • URL里面不允许使用参数占位符。
  • 返回结果采用自定义的业务状态码。

通常每个接口都有一个资源地址,为了更灵活些,可以设计为仅有一个入口地址,在参数里面增加接口名称,来区分不同的业务操作。参考淘宝API文档,如下所示:

请求地址:http://gw.api.taobao.com/router/rest
请求参数:

名称 类型 必须 描述
method String API接口名称,例如:taobao.user.buyer.get
timestamp String 时间戳,格式为yyyy-MM-dd HH:mm:ss,时区为GMT+8,例如:2015-01-01 12:00:00
4.2 分类原则

遵循MECE原则,根据业务领域进行接口分类。

MECE(发音me see)是Mutually Exclusive Collectively Exhaustive的缩写,意思是“相互独立,完全穷尽”,也就是对问题的分析,能够做到不重复、不遗漏,从而直达问题的核心,并找到问题的解决方法。由《金字塔原理》作者巴巴拉·明托1973年发明,也是麦肯锡思维过程的一条基本准则。

4.3 版本管理

不同版本的相同接口,将版本号标识统一后置,如下所示:

# 老版本
http://openapi.test.com/order/create_order
# 新版本
http://openapi.test.com/order/create_order/v2
4.4 返回数据

所有接口的返回数据都采用固定的JSON格式,如下所示:

{
  "code":200,
  "msg":"OK",
  "data":{
    "order_id":"2012120112304512",
    "product_name":"男士卫衣"
  }
}
  • code:父编号,一般是请求成功、异常等标识。
  • msg:父编号信息,一般是请求结果的信息提示。
  • data:具体的业务数据。
4.5 安全措施
  • 1)接口MD5签名
  1. 对所有API请求参数(包括公共参数和业务参数,但除去sign参数、值为空和值为数组类型的参数),根据参数名称的ASCII码表顺序升序排列,比如:foo=1, bar=2, foo_bar=3, foobar=4排序后的顺序是bar=2, foo=1, foo_bar=3, foobar=4。

  2. 将排好序的参数名、参数值用&拼装在一起,采用utf-8编码,比如:bar=2&foo=1&foo_bar=3&foobar=4。

  3. 在拼装的字符串尾部加上预先分配的密钥值 secret_value 后,再进行MD5算法摘要,如:md5(bar=2&foo=1&foo_bar=3&foobar=4&secret=secret_value)。

  • 2)数据加密

加密敏感数据比如用户信息,常见加密算法可以是RSA或者AES。

  • 3)IP白名单

在接口访问的前置层,只允许在白名单里的IP的请求。商户通过商户服务系统自行管理IP白名单。

4.6 数据推送

数据推送是指系统主动通知商户数据的变化,满足部分商户对数据的实时性要求。举个例子,商户创建订单成功,通过订单查询接口GET http://openapi.domain.com/query_order获得订单状态。如果商户希望尽快知道订单状态,可以定时轮询订单查询接口,但是效率低且浪费资源。系统主动通知商户订单的状态,能有效解决这个问题。商户需要按规范开发接口,接受指定格式的数据。数据推送增加系统了的复杂性,又会造成两个问题:

  • 业务状态的顺序性

订单有多个状态而且有业务顺序性,由于网络延迟的未知性,订单状态数据可能无序的推送给商户,这时商户可以通过业务逻辑去保证订单状态的正确性。

  • 推送数据可能遗漏

系统推送数据一般采用MQ异步发送,即便有手段保证消息不丢失,但是商户的网络故障依然会造成推送失败。这种故障有两个方式解决:1.系统在T+1时段提供T日的对账文件,里面包含订单号和订单状态,商户根据对账文件批量更新遗失的订单号状态;2.商户定时轮询订单状态。

4.7 API文档

为了便于商户查阅和测试API,采用 https://www.apifox.cn/ 管理API文档。

有关开放平台架构指南的更多相关文章

  1. ruby - Ruby 和 Ruby on Rails 中的三层架构 - 2

    我是一名决定学习Ruby和RubyonRails的ASP.NETMVC开发人员。我已经有所了解并在RoR上创建了一个网站。在ASP.NETMVC上开发,我一直使用三层架构:数据层、业务层和UI(或表示)层。尝试在RubyonRails应用程序中使用这种方法,我发现没有关于它的信息(或者也许我只是找不到它?)。也许有人可以建议我如何在RubyonRails上创建或使用三层架构?附言我使用ruby​​1.9.3和RubyonRails3.2.3。 最佳答案 我建议在制作RoR应用程序时遵循RubyonRails(RoR)风格。Rails

  2. Ruby 和指南针路径与 yeoman 项目 - 2

    我安装了ruby​​、yeoman,当我运行我的项目时,出现了这个错误:Warning:Running"compass:dist"(compass)taskWarning:YouneedtohaveRubyandCompassinstalledthistasktowork.Moreinfo:https://github.com/gruUse--forcetocontinue.Use--forcetocontinue.我有进入可变session目标的路径,但它不起作用。谁能帮帮我? 最佳答案 我必须运行这个:geminstallcom

  3. Simulink方法总结和避坑指南(一)——Simulink入门与基本调试方法 - 2

    文章目录一、项目场景二、基本模块原理与调试方法分析——信源部分:三、信号处理部分和显示部分:四、基本的通信链路搭建:四、特殊模块:interpretedMATLABfunction:五、总结和坑点提醒一、项目场景  最近一个任务是使用simulink搭建一个MIMO串扰消除的链路,并用实际收到的数据进行测试,在搭建的过程中也遇到了不少的问题(当然这比vivado里面的debug好不知道多少倍)。准备趁着这个机会,先以一个很基本的通信链路对simulink基础和相关的debug方法进行总结。  在本篇中,主要记录simulink的基本原理和基本的SISO通信传输链路(QPSK方式),计划在下篇记

  4. ruby - Ruby gems 的问题(损坏?)试图让指南针在 npm 中工作 - 2

    我不是Ruby专家,但想弄清楚发生了什么,因为我试图让指南针在节点应用程序中工作,但我的Ruby似乎坏了。打字:ruby--version让我:ruby2.1.1p76(2014-02-24revision45161)[x86_64-darwin13.0]我安装了Homebrew,之前遇到过Ruby版本的问题,但它似乎已安装并且可以正常工作。但是,当我使用gem输入请求时,出现此错误:$gem-hErrorloadingRubyGemsplugin"/Users/user_dir/.rvm/gems/ruby-2.1.1@global/gems/executable-hooks-1.3

  5. ruby-on-rails - 具有六边形架构和 DCI 模式的框架和数据库适配器 - 2

    我尝试用Ruby设计一个基于Web的应用程序。我开发了一个简单的核心应用程序,在没有框架和数据库的情况下在六边形架构中实现DCI范例。核心六边形中有小六边形和网络,数据库,日志等适配器。每个六边形都在没有数据库和框架的情况下自行运行。在这种方法中,我如何提供与数据库模型和实体类的关系作为独立于数据库的关系。我想在将来将框架从Rails更改为Sinatra或数据库。事实上,我如何在这个核心Hexagon中实现完全隔离的rails和mongodb的数据库适配器或框架适配器。有什么想法吗? 最佳答案 ROM呢?(Ruby对象映射器)。还有

  6. 设计一个亿级高并发系统架构 - 12306火车票核心场景DDD领域建模 - 2

    “架设一个亿级高并发系统,是多数程序员、架构师的工作目标。许多的技术从业人员甚至有时会降薪去寻找这样的机会。但并不是所有人都有机会主导,甚至参与这样一个系统。今天我们用12306火车票购票这样一个业务场景来做DDD领域建模。”开篇要实现软件设计、软件开发在一个统一的思想、统一的节奏下进行,就应该有一个轻量级的框架对开发过程与代码编写做一定的约束。虽然DDD是一个软件开发的方法,而不是具体的技术或框架,但拥有一个轻量级的框架仍然是必要的,为了开发一个支持DDD的框架,首先需要理解DDD的基本概念和核心的组件。一.什么是领域驱动设计(DDD)首先要知道DDD是一种开发理念,核心是维护一个反应领域概

  7. ruby - 使用指南针安装 bootstrap sass - 2

    我正在尝试安装bootstrap-sass并收到以下错误。我试过旧版本的sass,但bundler一直在安装3.3.0。WARN:UnresolvedspecsduringGem::Specification.reset:sass(~>3.2)WARN:Clearingoutunresolvedspecs.Pleasereportabugifthiscausesproblems./Library/Ruby/Gems/2.0.0/gems/compass-0.12.2/lib/compass/sass_extensions/monkey_patches/browser_support.r

  8. NFT交易平台开发 创建NFT数字藏品平台 - 2

    为什么需要NFT市场?NFTMarketplace允许用户购买、出售、交易、查看或创建自己的NFT,就像他们需要一个市场来购买物理或数字世界中的大多数产品一样。几乎每个人都可以进入NFT市场,但要做到这一点,用户必须满足以下要求:一个NFT市场用户账户,允许您在给定平台上购买NFT。你需要一个与区块链兼容的加密钱包来购买NFT。NFTMarketplace非常重要,因为它连接了买卖双方,并为用户提供了多种工具来快速创建自己的NFT。艺术家可以在市场上列出要出售的NFT,买家可以通过投标过程探索市场并购买物品。NFT市场开发过程解释创建NFT市场是一个耗时的过程,需要编程知识和理解。那么搭建NF

  9. Ruby跨平台EOF符号的写法 - 2

    在Ruby中是否有一种平台无关的方式将EOF符号写入字符串。在*nix中,我认为符号是^D,但在Windows中是^Z,这就是我问的原因。 最佳答案 EOF不是一个字符,它是一个状态。终端使用控制字符来表示此状态(C-d)。没有这样的事情是“读一个EOF字符”,写一个也是一样的。如果您正在写入文件,请在完成后将其关闭。看这个mailinglistpost:ItsoundslikeyouarethinkingofEOFasanin-bandbutspecialcharactervaluethatmarkstheendoffile.It

  10. JMockit 使用指南 - 2

    目录配置模拟模拟类型与实例期望录制-回放-验证指定调用计数验证指定自定义结果验证调用参数联级模拟部分模拟模拟未实现的类其他伪装伪装方法及类伪装未实现类本文主要内容如何在SpringBoot中配置使用JMockit如何mock/faking依赖的对象如何对行为mock如何VerificationJMockit之所以强大,是因其使用了javaagent对类的字节码做了修改,在JVM的所有mock工具中,它是功能最强大的。同时注解又是最少的。配置在SpringBoot项目中使用JMockit隔离代码做单元测试,需要做以下配置引入JMockit依赖。dependencies>dependency>gr

随机推荐