【问题标题】:JSON API for non-resource responses用于非资源响应的 JSON API
【发布时间】:2018-05-10 02:15:27
【问题描述】:

目前,我正在开发新产品并为公共和内部需求制作 REST API。我从 {json:api} 规范开始,我对它非常满意,直到遇到一些我无法找到答案的问题。

根据 JSON API 规范,每个资源必须包含id

http://jsonapi.org/format/

每个资源对象都必须包含一个 id 成员和一个 type 成员。 id 和 type 成员的值必须是字符串。

这在很多情况下都很好,但不是全部。

我们的大多数端点都是关于“资源”的

如果我要一个“东西”集合 (http://example.com/things)

{
  "data": [{
    "type": "things",
    "id": "1",
    "attributes": {
      "title": "first"
    },
    "links": {
      "self": "http://example.com/things/1"
    }
  }, {
    "type": "things",
    "id": "1",
    "attributes": {
      "title": "second"
    },
    "links": {
      "self": "http://example.com/things/2"
    }
  }]
}

如果我要求一个“事物”资源 (http://example.com/things/1)

{
  "data": {
    "type": "things",
    "id": "1",
    "attributes": {
      "title": "first"
    },
    "links": {
      "self": "http://example.com/things/1"
    }
  }
}

但是如何处理与资源无关且没有 ID 的端点?

例如,在我们的应用程序中,有一个端点http://example.com/stats 应该返回当前登录用户的统计信息。喜欢

{
  "active_things": 23,
  "last_login": "2017"
}

这个“资源”没有 id(它实际上不是资源,是吗?)。后端只是为登录用户收集一些“统计信息”并返回一个统计对象。在这个应用程序中有很多这样的端点,例如,我们有 通知中心 页面,用户可以在其中更改不同通知的电子邮件地址。

所以前端应用程序(单页应用程序)首先必须获取当前值并将请求发送到GET http://example.com/notification-settings

{
  "notifications_about_new_thing": "arunas@example.com",
  "notification_about_other_thing": "arunas@example.com"
}

还有更多这样的端点。问题是 - 如何以 JSONAPI 格式返回这些响应?这些端点中没有 ID。

最大的问题是 - 为什么没有其他人面临这个问题(至少我找不到任何关于这个的讨论)? :D 我做过的所有 API 都有一些没有“id”的端点。

我有两个想法,第一个是伪造id,比如"id": "doesnt_matter",第二个——不要对这些端点使用json-api。但我不喜欢他们两个。

【问题讨论】:

  • 对于当前登录用户的示例,id 不能是用户 ID 吗?
  • 不要使用 json-api。
  • @NathanHughes 是的,它可以.. 但我不喜欢它:)) 然后我也应该向http://example.com/stats/<user-id> 发送请求?..
  • @Quazer 不将其用于这些端点或根本不使用它?
  • @ArūnasSmaliukas 如果使用 JSONAPI 作为先验的外部系统没有连接到您的项目 - 不要使用 JSONAPI。使用自己的 JSON。 C# 的端点 - RestRequest、Python - 请求。

标签: rest api json-api jsonapi-resources


【解决方案1】:

以 REST 的方式思考,一切都可以(必须)成为一种资源。没有“登录”用户,因为 RESTful API 中没有会话,因为它们是无状态的。 REST API 调用之间没有维护会话状态,因此您必须明确用户是谁。

在这种情况下,资源是具有一些统计属性的用户(在简单的情况下)或者可能与单独的统计关系有关系(更复杂,未显示):

GET /users/1234 { "data": { "type": "users", "id": "1234", "attributes": { "name": "etc.", "active_things": 23, "last_login": "2017" } } }

【讨论】:

    【解决方案2】:

    我不是 JSON API 专家,但值得注意的是,虽然 JSON API 是一个具体的规范,但它与 JSON 不同,也与 REST API 不同。如果你不喜欢它的语义,我同意评论者的观点,“不要使用它”。如果您打算使用 JSON API,请以合规的方式使用,其中每个响应都是资源;每个资源都有一个 ID 和一个类型;并且附加信息作为资源的属性提供。

    对于您的问题,我正在考虑类似的事情,我的应用程序返回计算结果。现在,一方面,这些不是严格意义上的“资源”,所以我一直在考虑将原始结果作为数组返回(我相信这是valid JSON,但需要注意的是),例如:

    [ 47 ] 
    

    另一方面,有人认为结果是客户端以 REST 方式指定的计算结果,在这种情况下,以下两种情况之一可能是正确的:

    • 稍后提交的相同请求很可能具有相同的结果。这表明事实上结果确实一种资源。
    • 稍后提交的同一个请求可能会有不同的结果。这表明客户端可能希望跟踪各种查询的结果如何变化,因此至少查询参数应该是响应的一部分。

    在这两种情况下,响应确实是一个“结果”对象,即使它本身没有 ID,但它确实有一个标识。如果没有其他合适的,ID 可能是生成响应的查询。

    这对我来说似乎是 RESTful。用户 @n2ygk 认为这对于 JSON API 规范是不正确的,ID 应该只是一个唯一的 ID,并且没有其他语义解释。

    我很想听听其他观点。

    【讨论】:

    • 我认为 jsonapi.org 规范与术语 JSON 和 API 之间存在很多令人遗憾的混淆,前者是 JSON API 的特定标准模式。仔细阅读 jsonapi.org 规范仍然需要您将此结果表示为具有 typeidattributes 等的资源。推荐的 id 是一个 UUID(全局唯一),因此您可以选择每次返回一个新的或缓存结果并返回相同的....不过,我不会使用具有其他语义的 ID。
    • 感谢您的意见。我已经更新了我的答案(希望如此)以反映它。
    猜你喜欢
    • 2017-07-02
    • 1970-01-01
    • 2019-04-11
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多