on forhand:抱歉,如果我误解了超媒体或Restfull概念:这是一项正在进行的工作......)
我试图弄清楚超媒体和水印(http://www.markus-lanthaler.com/hydra),并在设计我的api之前有一些关于将信息返回给客户的问题。
说我在www.myshop.com上有一个网店
对根的HTTP GET可以返回(例如)表示为链接的资源列表(在json-ld文档中):
...
"@id": "/api",
"products" : "www.myshop.com/api/products",
"customers":"www.myshop.com/api/customers"
...
关于hydra的第一个问题,我怎么能在这里添加动作?似乎客户端需要在加载应用程序之前加载另一个文档。我的意思是潜在的行为不是从www.myshop.com/api中检索到的文件或者我是否错过了什么?
然后更进一步,我已经声明产品是一个水印:链接,以便客户端可以通过HTTP GET跟踪该链接(与之交互)并检索产品列表。这将是一个这样的列表:
....
{
"@id": "/api/products/123",
"@type": "vocab:Product"
},
{
"@id": "/api/products/124",
"@type": "vocab:Product"
},
....
此处客户端收到产品列表(可能是分页集合)。但是,如果客户希望将其显示给用户,请说明一个 [产品ID,价格,名称] (不是所有产品属性)的表格
第二个问题:如果客户没有向服务器发送每个产品的请求,我怎么能这样做,但仍然提供获取产品详细信息的链接,(或者甚至这里有四个链接:一个用于获取详细信息,一个用于删除,一个用于与朋友共享,另一个用于将其添加到购物篮)?
事实上,由于文档中没有链接,我很难弄清楚hydra是如何发挥作用的?我认为Hal使用这种方法在文档本身中有链接(如果我是对的)并且我试图找到hydra如何做这个链接......
问候
答案 0 :(得分:4)
有点晚了,但我会尽力回答你的问题塞德里克。
说我在www.myshop.com上有一个网店
对根的HTTP GET可以返回(例如)资源列表 表示为链接(在json-ld文档中):
关于hydra的... "@id": "/api", "products" : "www.myshop.com/api/products", "customers":"www.myshop.com/api/customers" ...
第一个问题,我怎么能在这里添加动作?好像是 客户端需要在加载应用程序之前加载另一个文档。 我的意思是潜在的行动不在从中检索到的文献中 www.myshop.com/api或者我错过了什么?
这里基本上有两个选项:1)将操作直接嵌入到响应中;或者2)将操作附加到属性(products
,customers
)。
方法1)看起来有点像这样:
...
"@id": "/api",
"products" : {
"@id": "http://www.myshop.com/api/products",
"operation": {
"@type": "Operation",
"method": "POST",
"expects": "Product"
}
}
...
虽然方法2)会将相同的操作附加到引用的Hydra ApiDocumentation中的products
属性:
...
"@id": "...products",
"supportedOperation": {
"@type": "Operation",
"method": "POST",
"expects": "Product"
}
...
请注意,1)我使用了operation
,而2)我使用了supportedOperation
。此外,您应使用比Operation
更具体的类型。
关于你的第二个问题:
使用HTTP GET并检索产品列表。这将是一个这样的列表:
.... { "@id": "/api/products/123", "@type": "vocab:Product" }, { "@id": "/api/products/124", "@type": "vocab:Product" }, ....
这里客户端收到产品列表(可能是分页的 采集)。但是,如果客户想要将其显示给用户,请允许 用[产品ID,价格,名称]表示一张表(并非所有产品都有 属性)
第二个问题:如果没有客户端发送,我怎么能这样做? 向服务器请求每个产品,但仍然提供链接 获取产品的详细信息,(甚至这里有四个链接 :一个用于获取详细信息,一个用于删除,一个用于获取 与朋友分享,最后一个将其添加到购物篮中?)
您可以直接在集合中添加尽可能多的信息(包括链接)。
....
{
"@id": "/api/products/123",
"@type": "vocab:Product",
"name": "Product 123",
"price": "9.99"
},
{
"@id": "/api/products/124",
"@type": "vocab:Product",
"name": "Product 124",
"price": "19.99"
},
....
这样,如果集合中没有包含所需信息,则客户只需要取消引用该项目。
事实上,我很难弄清楚hydra是如何进入的 通过在文档中没有链接来玩吗?
当然,您在文档中也有链接。链接只是其值恰好是URL(具有@id
属性的对象的属性,除非您在上下文中将属性的类型设置为@id
以除去它,而不是专门处理它们。
答案 1 :(得分:2)
注意:Hydra部分答案我不太确定,我认为JSON-LD和REST是可以的。
您可以使用@base
和JSON-LD的相对IRI,或者您可以在@context
中定义名称空间,之后您可以将相对IRI用作ns:relativeIRI
。每一个都比返回完整的IRI更好。 (使用客户端的通用JSON-LD解析器而不是简单的JSON解析器更容易解析结果。)
您可以使用Hydra词汇定义自己的@vocab
,也可以在@context
中添加“操作”定义。如果您想“添加动作”,则必须在词汇表中使用hydra:Operation
子类。像这样的东西(但我不是Hydra专家):
{
"@id": "vocab:ProductList",
//...
"hydra:supportedOperations": [
{
"@type": "hydra:CreateResourceOperation",
"method": "POST",
"expects": "vocab:Product"
}
//...
]
}
通常,通过REST,如果您需要具有较少属性的相同资源,则必须为该资源添加新的IRI,例如:/myresource?fewer=1
。例如,在您的情况下:/api/products/?fields="id, price, name"
没问题。
如果你想要多个链接,你可以选择Hydra 2个;您可以添加新的hydra:Link
作为媒体资源,也可以使用hydra:Operation
添加新的supportedOperation
作为method: GET
。我想获取操作是针对具有用户输入的搜索,但如果您不想为每个链接添加新属性,我认为您没有其他选择。
实际上Hydra确实有链接和操作支持。也许它不清楚,但JSON-LD是一种RDF格式,你可以在其中定义RDF三元组。因此,您"customers":"www.myshop.com/api/customers"
使用的IRI只是资源标识符而不是链接。链接应该具有IRI,标题,方法(GET),语言,内容类型,iana:关系等...因此不可能仅使用单个IRI(资源标识符)来描述您可以遵循的链接。通过处理REST资源,客户端永远不应该检查IRI结构以了解如何显示它从您那里获得的内容。您必须检查链接的其他属性,尤其是iana:relations或Hydra可能是操作类型来执行此操作。因此,例如在您的情况下,www.myshop.com/api/dav8ufg723udvbquacvd723fudvg
是客户列表中完全有效的IRI。我们只使用漂亮的IRI,因为它更容易配置在服务器端生成它们,并为它们配置路由器。
在进一步的问题之前,请检查Hydra vocab。如您所见,Class
可以supportedOperations
和supportedProperties
都是集合。 Link
是Property
子类,可以有一个Operation
。通过集合,我认为你必须使用Collection
类,其中member
包含集合的项目...请注意,通过JSON-LD,通过定义单个项目或多个项目没有区别具有相同类型的项目。在上下文中,您只需要定义类型,并且属性的值可以包含单个项目或项目数组...如果您想要一些约束,我猜您必须添加一些OWL三元组,并且验证器使用它们检查值。