对于RESTful服务,客户机如何找到资源属性的有效值?
作为RESTful API提供的资源的功能发现的一部分,我正在寻找一种方法让服务为属性宣布可接受的值。考虑下面的示例,其中<代码> Apple < /Cord>资源具有属性>代码>颜色< /代码>:对于RESTful服务,客户机如何找到资源属性的有效值?,rest,jsonschema,discovery,capability,Rest,Jsonschema,Discovery,Capability,作为RESTful API提供的资源的功能发现的一部分,我正在寻找一种方法让服务为属性宣布可接受的值。考虑下面的示例,其中 Apple < /Cord>资源具有属性>代码>颜色< /代码>: GET /apples/17 这一请求产生: { "name": "My yummy apple", "color": "green" } 对于一个客户来说,要理解什么样的颜色值是有效的,例如PUTting一个新版本的苹果,我可以想出很多可能的方法。然而,我在这里没有找到任何最佳实践。HTTP选
GET /apples/17
这一请求产生:
{
"name": "My yummy apple",
"color": "green"
}
对于一个客户来说,要理解什么样的颜色
值是有效的,例如PUT
ting一个新版本的苹果,我可以想出很多可能的方法。然而,我在这里没有找到任何最佳实践。HTTP选项动词似乎不适合这种细粒度的发现。我是否应该向/apples
集合添加一个数组属性:
GET /apples
答复:
{
...
"colorValues": ["red", "green"]
}
有没有更好更常用的方法
编辑:
刚刚意识到一种可能的方法是为所有“真实”资源的模式添加资源。类似于GET/schemas/apple
的东西,可以为apple
资源生成JSON模式表示。修改json-schema.org中的示例:
{
"id": "http://foo.bar/schema#",
"$schema": "http://json-schema.org/draft-04/schema#",
"description": "schema for an apple resource",
"type": "object",
...
"colorValues": {
"enum": [ "red", "green" ]
}
}
不过,我还没有找到这样的例子。一种可能的方法是使用两种资源:
苹果
和颜色
。这将是非常容易为您的潜在客户获得可用的颜色在一个安静的方式。超媒体呢?有,您可以创建自己的,但最好还是坚持使用一些广泛使用的
例如,如果您想实现以下功能,那么获得apple将如下所示:
GET /apples/17
{
"name": "My yummy apple",
"_links": {
"self": {
"href": "/apples/17"
},
},
"colour": {
"id": "green",
"href": "/colours/green"
}
}
把所有颜色都列出来怎么样?像这样的事情:
GET /colours
{
"_links": {
"self": {
"href": "/colours"
}
},
"_embedded": {
"colours": [
{
"_links": {
"self": {
"href": "/colours/green"
}
},
"id": "green"
},
{
"_links": {
"self": {
"href": "/colours/red"
}
},
"id": "red"
}
]
}
}
这是设计API的现代方法,例如
Amazon AppStream web服务是一个基于资源的API,它使用
超文本应用语言(HAL)。HAL为
将API的资源和关系表示为超链接。
使用HAL,您可以使用HTTP方法(GET、PUT、POST、DELETE)进行提交
请求并在响应中接收有关API的信息。
应用程序可以使用返回的信息浏览
API的功能
编辑:
如果不同的实体允许不同的颜色,你可以这样做
GET /apples/17
{
"name": "My yummy apple",
"_links": {
"self": {
"href": "/apples/17"
},
"available_colours": {
"href": "/apples/17/available_colours"
}
},
"colour": {
"id": "green",
"href": "/colours/green"
},
"_embedded": {
"available_colours": [
{
"_links": {
"self": {
"href": "/colours/green"
}
},
"id": "green"
},
{
"_links": {
"self": {
"href": "/colours/red"
}
},
"id": "red"
}
]
}
}
正如您所看到的,它的结构非常灵活。JSON Hyper Schema非常适合这种情况
GET /apples/17
-
然后,客户机可以在schema/apple
上取消对超模式的引用,以了解接下来可以使用哪些链接
GET /schema/apple
-
这是一个您熟悉的JSON模式,但包含一个额外的关键字links
,它描述了您可以从此资源中遵循的链接。客户端使用原始JSON数据中的值评估href
URI模板。因此,在这种情况下,链接的计算结果为
{
"rel": "http://foo.bar/relation/edit",
"href": "/apple/17",
"method": "PUT",
"schema": { "$ref": "#" }
}
此链接指示客户端可以向/apple/17
发出PUT
请求,请求主体应根据/schema/apple
处的模式进行验证({“$ref”:“#”}
表示此模式)
这为您的功能提供了一个可读的和机器可执行的描述。机器可执行部分很重要,因为经常可以在不破坏现有客户机的情况下对API进行更改
注意:此代码是用JSON超模式草稿-04编写的。最近发布了一个新版本草案-05。它做出了一些有争议的改变。目前我仍在推荐草案04。该规范可在。宝贵的输入中找到-我可以肯定地看到它的用途!但在更一般的意义上(例如,传递一组整数值属性的最大允许值),它在我看来相当乏味?例如,假设总共有5种不同的苹果颜色,但不同的实体允许使用不同的颜色?@MarcusJohansson您好,我已经编辑了答案,并为指定实体添加了一些额外的示例,其中包含
可用的\u颜色
。非常感谢!感谢您在这方面的投入。我认为这种方法抓住了我保持定义和模式非常紧凑的雄心。谢谢你的意见!
HTTP/1.1 OK
Content-Type: application/schema+json
{
"id": "http://foo.bar/schema/apple",
"$schema": "http://json-schema.org/draft-04/hyper-schema#",
"type": "object",
"properties": {
"id": { "type": "string", "readOnly": true },
"name": { "type": "string" },
"color": { "enum": ["red", "green"] }
},
"required": ["id", "name", "color"],
"links": [
{ "rel": "self", "href": "/apple/{id}" },
{
"rel": "http://foo.bar/relation/edit",
"href": "/apple/{id}",
"method": "PUT",
"schema": { "$ref": "#" }
}
]
}
{
"rel": "http://foo.bar/relation/edit",
"href": "/apple/17",
"method": "PUT",
"schema": { "$ref": "#" }
}