【问题标题】:REST API Design: How to break down the API object to make more scalable and robust APIREST API 设计:如何分解 API 对象以制作更具可扩展性和健壮性的 API
【发布时间】:2017-02-21 06:09:01
【问题描述】:

我们有手机电子商务网站。我们正在构建用于 POST、PUT、DELETE、UPDATE 手机的 restful api。

每部手机都将具有以下基本功能:价格、制造商、制造年份、颜色、折扣。

除此之外,大多数手机也会有图像。

另外,其中很少有制造商保修。让我们说其中的 50%。

而且很少有手机会提供融资选项,例如我们已与某些银行合作为这些手机提供贷款。几乎 80% 将拥有此设施。

我们为此决定了两种设计 api 的方法:

方法 1. 所有这些都在同一个 JSON 对象中。只有一个 API,例如:

  {   
    "basicInfo": {
      "price": "",
      "mfgYear": "",
      "manufacturer": ""
    ...
  }, 
    "images":{...},  
    "warranty":{...},    
    "finance":{...}    
   }

方法 2. 将所有这些 JSON 对象分开。例如:

   First Api for "basicInfo".
   Second Api for "images".
   Third Api for "warranty".
   Fourth Api for "finance"

我可以弄清楚每种方法的优缺点:

方法1: 优点: 我们在服务器上收集所有库存信息。这意味着更少的 API 命中,更少的服务器负载。此外,将来如果我们实施一些队列处理以将这些股票信息保存到数据库中,则在股票插入数据库之前不会发布图像/保修/财务的情况,因为我们将所有信息放在一起。因此,我们将首先将股票插入数据库,然后将记录插入其他具有外键关系的表中。 缺点:此 API/资源有多种职责。会越来越大,以后这个API的领域可能会太多。在我看来,这也违反了单一责任原则。

方法2: 优点: 这看起来有点干净和有条理。看起来每个 API 都有自己定义的职责。对我来说看起来可扩展。如果对一个 API 进行更改,则不太可能影响其他 API。 缺点:服务器上的 API 点击次数更多。在发布库存之前发布相关库存资源的机会更大。例如,我们可以在插入库存之前将图像出列。

Approach3. 提供两种选择。允许使用基本信息发送其他信息以及为这些资源创建单独的 API 的示例。

哪种方法最好,即更安静、可扩展且性能更好?

【问题讨论】:

    标签: rest api asp.net-web-api api-design


    【解决方案1】:

    仅根据您提供的信息,以下是我对设计此系统的看法。为电话、保修和融资信息提供单独的端点。积极缓存保修,因为这些很少会改变。在手机的 JSON 表示中包含指向保修和融资信息的链接。让/phones/{phoneId} 端点支持名为“expand”之类的查询参数。如果服务器看到expand=warrantyexpand=financingexpand=warranty, financing,则除了提供链接外,还要在电话资源中嵌入相关的 JSON。现在客户可以选择他们需要的信息并获取它。

    对于图像,如果可能的话,使用 CDN 来处理它们,并且只包含一个链接。如果您需要在 API 中管理它们,那么我会将它们与上述保修和融资一样对待。确保它们被非常积极地缓存,因为手机的外观不会经常改变。如果您需要更改图像,请使用新的文件名。

    可以在JSON API 的规范中看到这种方法的一个示例,其中相关属性称为“包含”。 JSON API 对你来说可能太重了,但它有一些好主意,值得浏览规范。

    最后,请注意像这样的开放式问题更适合https://softwareengineering.stackexchange.com/。 Stack Overflow 适用于回答正确的问题。

    【讨论】:

    • 帖子怎么样。我想你已经回答了它。帖子应该分开还是我们应该只给一个Api?
    • @sahil 您真的希望客户通过POSTing 将保修更新为/phones?这对我来说似乎是个坏主意。我想多部手机将共享保修。同样,如果供应商和产品线相同,则多部独立手机的融资信息可能相同。要求客户更新这些事情以单独执行。
    • 每部手机都会有不同的 EMI 金额、使用期限,并且会有提供此服务的银行名称和少数其他字段。现在,我们应该将财务信息作为电话 api 帖子的一部分还是将其作为单独的资源保留?
    【解决方案2】:

    我不是 JSON 专家,但 AFAIK 可以堆叠这些对象,这样您就可以对插入/更新进行分层(完整)推送,也可以完成(或预期不完整)get-calls。

    这样您就不必搞砸每一个推/拉动作,并且在扩展时仍然很灵活。 您还可以(或者很可能想要)调用专门的例程来插入/更新每个子对象,这样您就可以将它们作为 REST API 的一部分提供和使用。

    对于拉取,您可以将缺失的节点标记为undecided,或者已经检查数据库并将其标记为unloadednot available

    请记住,如果您为所有子对象(APP.1 或 3)提供 API,则始终由调用者对这些调用进行排序 - 尤其是在调用时删除通常以相反的顺序完成。

    如果您决定使用复杂的 API(1 或 3),您仍然可以使用队列和超时。因此,您可以将请求(主要是写入)存储在队列中,并在短暂的超时后 - 在将数据转发到插入/更新(/删除)例程之前检查队列的完整性。

    【讨论】:

      【解决方案3】:

      APPROACH1:优点:[...] 我们将首先将股票插入数据库,然后将记录插入具有外键关系的其他表中。

      如果你想构建一个健壮的 API,那么你可以这样做,因为它可以让你安全地执行事务。

      缺点:此 API/资源有多种职责。会越来越大,以后这个API的字段可能会太多。

      您可以减少这种检索required fields only 的负面影响。

      【讨论】:

      • 我们可以通过在方法2中插入股票之前不允许发布图像/财务信息来实现安全交易。您还有其他理由支持方法 1 吗?
      • 对 API 消费者来说是业务逻辑migrates 吗?
      • 是的。我们也可以这样做。
      猜你喜欢
      • 2010-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多