用于非资源响应的JSON API

时间:2018-04-10 12:56:58

标签: rest api json-api jsonapi-resources

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

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

http://jsonapi.org/format/

  

每个资源对象必须包含一个id成员和一个类型成员。 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。但我不喜欢他们两个。

2 个答案:

答案 0 :(得分:3)

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

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

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

答案 1 :(得分:2)

I'm no JSON API expert- but it's worth noting that while JSON API is a concrete specification, it is not the same thing as JSON, nor as a REST API. If you don't like its semantics, I agree with commenters who argue, "Don't use it." If you are going to use JSON API, do so in a compliant way, where every response is a resource; every resource has an ID and a type; and additional information is supplied as attributes of the resource.

Toward your question, I'm thinking about something similar where my application returns computation results. Now on the one hand, these are not strictly "resources" and so I've been toying with the idea of returning the raw result as an array (which I believe would be valid JSON, with a caveat), e.g:

[ 47 ] 

On the other hand, there is the idea that the results are the results of a computation that the client specified RESTfully, in which case one of the following two cases is likely true:

  • The same request submitted later is likely to have the same result. This suggests that in fact the result really is a resource.
  • The same request submitted later is likely to have a different result. This suggests that the client may want to track how results change for various queries, and so at least the query parameters should be part of the response.

In both cases, the response really is a 'result' object, and even though it doesn't have an ID per se, it does have an identity. If nothing else fits, the ID could be the query that generated the response.

This seems RESTful to me. User @n2ygk suggests that this is not correct as regards the JSON API spec, that an ID should simply be a unique ID and not have another semantic interpretation.

I'd love to hear other perspectives.