编写API-破坏XML(两个)

第一个MyStore API出现在10年前。 一直以来,我们都在开发API的现有版本并开发新版本。 而且API的多个版本已经被掩埋。

本文将涉及很多内容:如何创建API,云服务为何需要它,为用户提供了我们要踩的什么耙子以及下一步要做的事情。

我叫Oleg Alekseev oalexeev ,我是MySklad的技术总监兼联合创始人。

为什么要为服务创建API


我们的客户是成千上万的企业家,他们正在积极使用云解决方案:银行,在线商店,产品会计,CRM。 已连接到一个-已经很难停止。 现在,第五,第八,第十项服务使企业家的工作更加轻松,但是用户可以在这些云服务之间手动传输数据。 工作变成一场噩梦。

显而易见的解决方案是使用户能够在云服务之间传输数据。 例如,将数据导入和导出为文件,然后可以将其下载到所需的服务。 文件通常更改为每种服务的格式。 这或多或少是简单的手动工作,但是随着这些服务数量的增加,执行它变得更加困难。

因此,下一步就是API。 有了它,云服务就可以从一个点连接多个服务中受益。 这种生态系统的出现由于其他机会吸引了新客户。 具有新功能的产品变得更加有利可图。

如果您创建自己的程序接口,那么它会以程序员的形式吸引第三方卖家,他们会借助API来了解您的产品。 他们开始根据提议的API构建解决方案,并通过自动化其客户的任务来赚钱。

MyStore的计费系统基于简单的流程。 最主要的是处理原始文件,具有在原始文件的基础上接收和运送货物以及接收业务报告的能力。 也有数据传输,例如到云会计,以及从银行系统或零售店的收据。 我们还与在线商店合作:我们接收有关商品的信息并发送余额数据。

MyStore中在线商店周围的数据周期

第一个MyStore API


MyStore使用API​​已有10多年的时间,我们已经获得了各种集成,可以让您交换数据,与银行合作,付款和使用外部电话。

在第一年,我们就可以上传XML格式的任何数据。 然后,让用户使数据保持脱机状态,而不是将数据保持在某种形式的云中变得更加容易理解和熟悉,我们为此提供了帮助。 通过从界面手动导出开始卸载。 也就是说,该API尚未被调用。

然后,我们开始与Rusagro合作-他们已经使用“成人” ERP来计划生产和销售,但是MySklad中工厂的汽车装载是自动化的。 因此,我们得到了该API的初步知识:服务和ERP之间的交换是通过发送包含所有类型文档的数据的大文件进行的。

对于批量数据交换,这是一个不错的选择,但是连同他们必须传输依赖关系的文档:有关货物,承包商和仓库的信息。 这样的垃圾填埋场在出口时很难产生,但是在进口时却很难拆卸,因为所有信息都打包在一起:关于新文件和关于现有文件的信息。

第一个XML API持续时间不长-两年后,我们开始重建它。 即使在他的工作开始时,我们在构建软件界面时也会犯一些错误。

XML API的制作方式:一位建筑师的插图。顺便说一句,等他的文章。
XML API的制作方式:一位建筑师的插图。 顺便说一句,等他的文章。

这是我们的主要错误:

  1. JAXB标记直接在实体bean上完成。 我们使用Hibernate与数据库进行通信,并且JAXB标记是在同一bean上进行的。 该错误几乎立即出现:对数据结构的任何更新导致需要紧急通知使用该API的任何人,或者建立拐杖以确保与以前的数据结构兼容。
  2. API是作为一种补充而增长的,最初我们还不确定它构成产品的哪一部分。 我们甚至没有考虑过API是否很重要,是否有必要保持其第一个客户的向后兼容性。 在某个时候,API用户的数量约为总数的5%,因此没有引起注意。 适时进行的通用过滤使我们成为后端。 这种过滤完全不是GraphQL,而是类似的-它通过许多查询字符串参数进行工作。 有了如此强大的工具,用户难以抗拒,因此请求已转移给我们,以便直接从其在线商店的UI发送。 这种情况令人意外,因为提供这样的服务应该要求不同的收费,并且需要对API本身作为产品有所不同。
  3. 由于API并不是作为主要产品开发的,因此API的文档是根据反向原理通过反向工程制作和发布的。 这种方法看起来很简单方便,但是与合同工作相反。 这是当某个组件具有预定义的工作方案时。 开发人员根据此方案和任务实施它,对组件进行测试,客户收到与分析师的想法相符的产品。 另一方面,逆向工程会抛出一个简单存在的产品:拐杖,奇怪的解决方案和自行车,而不是必需的功能。
  4. 仅通过Nginx日志或应用程序服务器就可以分析通过API发出的整个请求流。 这不允许我们隔离主题领域,除了可能按用户和订户划分主题领域。 如果无法规范应用程序或客户的注册,则无法分析情况。 这个问题对API的开发影响最小;更多的是了解它的相关性和功能。

尝试第二个:REST API


在2010年,我们尝试建立一个带有在线会计的交换系统BukhSoft。 它没有起飞。 但是在集成过程中,出现了完整的API:一种REST交换服务,其中没有诸如以RPC调用形式进行的操作调用之类的自由。 与API的所有通信都进入了标准模式以供休息:查询字符串包含实体的名称,并使用http方法设置对其执行的操作。 我们在更新实体时添加了过滤功能,现在用户可以使用其系统构建复制。

在同一年,出现了一个API用于卸载仓库和商品余额。 通过API,用户可以使用系统中最有价值的部分-交换原始文档和有关货物余额和成本的估计数据。

2015年12月,RetailCRM发布了第一个第三方库来访问我们的API。 他们开始非常积极地使用它,尽管整个服务的普及程度有所提高,但API的负担却比Web界面的负担增长得更快。 曾经,增长变成了负载的跳跃。

这里是黑鹰的沦陷。还是我们经历的耙。

解决方案很简单-给每个人平等的资源。

而且这种跳跃(如左箭头所示)导致为我们的API提供服务的服务器大为惊讶。 在一周的时间里,我们了解了此负载的确切产生。 事实证明,这些正是从客户方面广播到我们的API的请求。 大约有50位客户将其全部吃光。 那时我们意识到了我们的错误之一-完全没有限制。

结果,我们引入了同时请求数量的限制。 从一个帐户可以同时打开不超过两个请求。 这足以在复制模式下工作,以便以批处理模式交换数据。 从那时起,那些想将我们用作后端的人被迫遵守关税政策,因为他们在软件中引入了多个帐户的工作。

整理


自2014年以来,对现有API的需求已成为业务的重要组成部分,并且与客户进行数据交换时,API本身生成的数据量最大。 2015年,我们启动了一个清理API的项目。 我们选择JSON而不是XML作为格式,并开始根据先前版本的实现过程中揭示的功能来构建它:

  1. 能够管理版本。 通过版本控制,您可以开发新版本而不会影响现有应用程序,也不会影响用户。
  2. 用户查看其收到的响应中的元数据的能力。
  3. 交换大文件的能力。 如果我们处理位置数超过4-5千的文档,则对于服务器而言将成为问题:较长的事务,较长的http请求。 我们建立了一种特殊的机制,使您可以部分更新文档并通过将其发送到服务器来管理该文档的各个位置。
  4. 复制工具-在以前的版本中。
  5. 负载限制就像以前版本中耙过的耙子一样。 引入了对一段时间内请求数,并发请求数和来自一个ip地址的请求数的限制。

从那时起,我们发布了两个次要版本的API,并启动了几个专门的API,但总的来说,方法保持不变。 更新的交换格式和新的体系结构可以更快地纠正API中的缺陷。

今天的MyStore API


今天,MyStore API解决了许多问题:

  • 与在线商店,会计系统,银行进行数据交换;
  • 接收结算数据,报告;
  • 用作客户端应用程序的后端-我们的移动应用程序和桌面收银台通过API进行工作
  • 发送有关MyStore中数据更改的通知-Webhooks;
  • 电话;
  • 忠诚度系统。

基于该API,我们的首席执行官Askar Rakhimberdiev rhino在四个小时内编写了一个电报机器人,将其余部分通过API提取: github.com/arahimberdiev/com-lognex-telegram-moysklad-stock

现在干数字。

以下是旧REST API的统计信息:

  • 400家公司;
  • 600个用户;
  • 每天200万个请求;
  • 每天200 Gb的传出流量。

这就是我们所有MyStore API涉及的内容:

  • 超过70个集成(其中一些可以在这里找到www.moysklad.ru/integratsii );
  • 8500家公司;
  • 12,000个用户;
  • 每天4600万次请求;
  • 2 Tb /天的传出流量。

接下来是什么


API开发计划正在积极讨论中。 我们尝试考虑用户提供给我们的操作经验。 并非总是,并非所有事情都立即完成,但并非遥不可及的是新版本的API,它具有更方便的元数据和较轻的结构,用于身份验证的OAuth,用于接口中内置应用程序的API。

您可以在MySklad的集成开发人员的特殊网站上关注新闻: dev.moysklad.ru

Source: https://habr.com/ru/post/zh-CN453136/


All Articles