API设计中的功能结构

时间:2015-08-26 05:06:22

标签: web-services api rest api-design

通过'功能结构',我的意思是我们如何组织和协调不同的API端点,以便为客户提供所需的功能。 此处的上下文是用于通过GPS跟踪的移动电话消费的网络API,我认为大多数功能都需要蜂窝或WiFi连接。

我个人更喜欢更“模块化”的方法,其中每个端点主要完成一件事,并且它们的集合满足所有要求。当然,您可能需要组合这些端点的一些子集或序列以实现某些功能。 总体而言,我尝试在计算和功能方面尽量减少端点之间的重叠。

另一方面,我知道其他一些人在以下方面更喜欢客户端方便(或简单)而不是模块化:

  1. 如果客户端需要实现某项功能,那么应该存在一个单个 API端点,该端点就是这样做的,这样客户端只需要一个请求即可实现最少的功能请求之间的缓存/逻辑。

  2. 对于GET端点,如果某些功能涉及多个级别/种类的数据,则他们更喜欢单个端点返回的尽可能多的数据(通常是所有必需的数据)。具有讽刺意味的是,他们可能还需要一个专用端点,用于使用相应的“最高级别”ID检索“最低级别”数据。例如,如果A对应于B s的集合,并且每个B对应于C s的集合,那么他们将更喜欢检索所有C的直接端点相关的A给出{{1}}。

  3. 在某些极端情况下,他们会要求一个带有模糊命名的端点(例如/ api / data),它返回来自不同底层数据库表的相关数据(换句话说,不同资源)基于查询字符串参数的不同组合。

  4. 据我所知,人们更喜欢上述便利,目的是:1。减少履行功能所需的API请求数量; 2.最小化客户端的数据缓存和数据逻辑,以降低客户端的复杂性,这可以说是一个“简单”的客户端,简化了与服务器的交互。

    但是,我也想知道这样做的成本从长远来看是否在其他方面是不合理的,特别是在服务器端API的性能和维护方面。因此我的问题是:

    1. 构建API功能的经验教训是什么?

    2. 我们如何确定在移动应用中实现功能所需的最佳请求数量?当然,如果所有其他条件相同,单个请求是最好的,但实现这样的单一请求实现通常会在其他方面带来惩罚。

    3. 鉴于客户端请求数量与服务器端API的性能和可维护性之间存在争议,为实现合理的设计,有哪些方法可以达到平衡?

1 个答案:

答案 0 :(得分:13)

您要问的是至少涉及API设计的三个主要方面:

  1. 本体设计(组织)
  2. 请求/响应设计(复杂性/性能)
  3. 维护注意事项
  4. 根据我的经验(主要来自与API生产和消费方面的大型组织合作以及与数百名开发人员讨论该主题),让我们看看每个领域,解决具体问题你提起......

    本体设计

    在您的设计中需要考虑的几件事情可能会暗示:

      

    总的来说,我尝试在计算和功能方面尽量减少端点之间的重叠。

    这种方法使API容易可被发现。如果您正在发布API供其他开发人员使用而您可能知道或可能不知道(并且可能有或没有足够的资源来真正支持),这种模块化 - 使他们易于查找和了解 - 创造一种不同的方便"导致更容易采用和重用您的API。

      

    我知道其他人更喜欢方便而不是模块化:1。如果客户需要功能,那么API中应该存在一个完全相同的端点......

    这种方法最令人想到的公开示例可能是Google Analytics Core Reporting API。它们实现了一系列查询字符串参数来构建一个返回所请求数据的调用,例如:

    https://www.googleapis.com/analytics/v3/data/ga
    ?ids=ga:12134
    &dimensions=ga:browser
    &metrics=ga:pageviews
    &filters=ga:browser%3D~%5EFirefox
    &start-date=2007-01-01
    &end-date=2007-12-31
    

    在该示例中,我们通过浏览器查询Google Analytics帐户12134,其中broswer是指定日期范围内的Firefox。

    考虑到API公开的指标,维度,过滤器和细分的数量,他们有一个名为Dimensions & Metrics Explorer的工具,可以帮助开发人员了解如何使用API​​。

    一种方法从一开始就使API可被发现并且更容易理解。另一个需要更多的支持工作来解释消费API的复杂性。使用上述Google API并不容易发现的一件事是,某些细分和指标不兼容,因此如果您通过一个键/值对进行调用,则可能无法再通过某些其他对。< / p>

    请求/响应设计

      

    此处的上下文是适用于移动应用程序的API。

    这仍然非常广泛,并且更好地定义(如果可能的话)您打算如何使用移动应用程序&#34;使用可以帮助您设计API。

    1. 您是否打算让他们完全脱机使用?如果是这样,可能需要进行繁重/完整的数据缓存。

    2. 您是否打算将它们用于低带宽和/或高延迟/错误率连接方案?如果是这样,可能需要繁重/完整的数据缓存,但小/离散数据请求也是如此。

    3.   

      对于GET端点,他们通常更喜欢单个端点返回的尽可能多的数据,尤其是当涉及多个级别/层数据时

      如果您知道自己只是处于良好的移动连接方案中,或者您可以随时高速缓存数据(从而脱机访问或出现问题),这是安全的。

        

      我理解人们更喜欢方便,目的是减少实现功能所需的API调用次数......

      找到快乐中间立场的一种方法是在数据密集型调用中实施paging。例如,可以在GET中传递查询字符串,指定&#39; pagesize&#39;。因此,可以通过100次连续呼叫一次返回100个记录100个记录,或者通过10个呼叫一次返回1,000个记录。

      通过这种方法,您可以设计和发布API,而无需了解您的消费者需要什么。尽管上面的分页示例使用前面引用的Google API,但它仍然可以在更加语义设计的API中使用。例如,假设您有GET /customer/phonecalls,您仍然可以将其设计为接受pagesize值并进行连续调用以获取与phonecalls相关联的所有customer

      维护

        

      我还想知道这样做的成本[减少实现功能和最小化数据缓存所需的API调用的数量]从长远来看是不合理的,特别是对于API的性能和维护。

      如果您的API集合将会发展到任何重要的复杂性和规模,那么这里的关键指导原则是separation of concerns

      如果将所有内容捆绑在一起构成一个大型服务并且其中的一小部分发生变化,会发生什么?您现在不仅要创建一个维护问题,还要为您的API使用者创建。

      是否&#34;突破变化&#34;真的会影响他们使用的API部分吗?他们需要时间和精力来解决这个问题。将API功能设计为离散的语义服务,可以让您创建路线图并以更易理解的方式对其进行版本化。

      为了进一步阅读,我建议查看Martin Fowler关于Microservices Architecture的着作:

        

      简而言之,微服务架构风格是一种方法   将单个应用程序开发为一套小型服务   在自己的进程中运行并与轻量级通信   机制

      虽然关于如何设计和构建微服务有很多争论。在实践中,阅读这些内容应该有助于进一步塑造您对您所面临的API设计决策的思考,并为您准备参与&#34;当前&#34;关于这个主题的讨论。