【问题标题】:How to proper design a REST API response?如何正确设计 REST API 响应?
【发布时间】:2017-06-07 10:52:57
【问题描述】:

我们有一个案例,我们有一个休息端点,响应将根据应用程序流而有所不同。 json 中的属性会有所不同,所以问题是我们是否想要一个包含 json 的响应,该响应会根据应用程序的流而具有不同的结构。

正如我现在所看到的,我们基本上有三个选择。我们可以有两个属性,其中一个总是为空(客户或业务客户):

{
  "data": {
    "target": "Business",
    "customer": null,
    "businessCustomer": {
        ....
    }
}

{
  "data": {
    "target": "Customer",
    "customer": {
        ....
    },
    "businessCustomer": null,
}

或者我们将只有一个属性,其中该 json 对象的内容会有所不同(始终填充客户):

{
  "data": {
    "target": "Customer or business",
    "customer": {
        ....
    }
}

我认为仅使用一个属性可能很难使用数据。您将如何在强类型语言中以流畅的方式对其进行序列化...

哪种方式最好?提前致谢!

【问题讨论】:

  • customerbusinessCustomer 是两个独立的实体吗?
  • 为不同类型的请求创建新调用。不要混淆您的数据类型。将它们分开,因为它们是不同的。如果你把它混合起来,那么下一步呢?当您有不同类型的调用要实施时,您是否会一直混淆?
  • 我认为您的 REST API 不应该根据消费者的行为来改变其响应 - 它应该是不可知的。
  • 如果您的 Customer 和 BusinessCustomer 实体相似并且可以从基类派生,那么 stackoverflow.com/questions/6348215/… 可能会有所帮助?
  • 是的,我会这么说,但从技术上讲,他们可以共享一个基类@Tom

标签: c# json rest api


【解决方案1】:

我们在开发中遇到了类似的情况,并使用资源类型解决了它,并为它的所有子类型创建了一个基类。它是一个通用实现,客户端代码负责检查@type 并从它们那里创建相应的对象。

CustomerResource (Considering this as Base Class)
    BusinessCustomerResource (Extended from Customer Resource)

对于商业客户资源:

{
    "someOtherElement": "value",
    "customer" : {
                    "@type" : "BusinessCustomerResource",
                    "faxNumber" : "35635636",
                    "email" : "test@gmail.com",
                    "phone" : "2503334444",
                    "contactName" : "name",
                    "firstName" : "Owner",
                    "lastName" : "lastName"
                    ...
                    "address" : {
                      "@type" : "InternationalAddressResource",
                      "province" : "AB",
                      "country" : "Canada",
                      ...
                    }
                }
}

对于客户资源:

{
    "someOtherElement": "value",
    "customer" : {
                    "@type" : "CustomerResource",
                    "email" : "test@gmail.com",
                    "phone" : "2503334444",
                    "firstName" : "Owner",
                    "lastName" : "lastName"
                    ...
                    "address" : {
                      "@type" : "PostalAddressResource",
                      "province" : "AB",
                      "country" : "Canada",
                      ...
                    }
                }
}

【讨论】:

  • 是的,这似乎是一种方法。但是目前我们没有共享基类,而且我不喜欢传递 @type 属性...
【解决方案2】:

我建议使用通用的响应格式。您可以在现实世界中观察到类似的示例(示例:HTTP 请求/响应)。

你可以像下面这样标准化它:

{
  "statusCode": 0,
  "statusDesc": "Response description",
  "value": null
}

这里 statusCodestatusDesc 在您的所有响应中都是通用的,并且 value 会根据 api 而变化(在您的情况下,您可以通过customerbusinessCustomer)。通过这样做,客户可以使用通用工具来了解它是成功/失败并采取相应的行动。

【讨论】:

  • 响应格式已经是“普通”了。 80% 的属性(现在在我的示例中显示)在所有响应中都是相同的。我将您的建议解释为您推荐一个属性而不是两个属性来分隔客户实体。
猜你喜欢
  • 2014-09-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多