请原谅我,因为我还不熟悉这个RESTFUL的事情,我一直在阅读博客等......他们都有不同的实现/指导方针,只有真正的指导方针才是Richardson成熟度模型,它指明了Hypermedia的含义。 / p>
我知道超媒体设计的好处是通过根URL链接注释驱动机器/用户交互,并且它将像链接更改时一样可以改进,使用幂等/安全的http动词等增强缓存...
我正在尝试设计一个RESTFUL API Web服务,并且我打算使用GENERIC MEDIA TYPE,例如HAL或Collection + Json或Siren等...或者可能创建我自己的媒体类型,我认为我不想马上进入...
使用通用媒体类型,我会有一个有效载荷,一个数据结构或DTO对象,无论你怎么称呼它,比如“具有许多地址的许多申请人模型的应用模型等......”
1)我是否必须在某处指定数据结构定义?或某种表格模板?我已经看到了一些例子,他们把这些数据的定义放在人们可读的格式中,比如“someurl / doc?或者我们应该使用像json schema这样的东西?
2)我见过的一些例子用vcard / foaf等链接中的类型装饰了他们的数据项......例如。 “name”:“http://xmlns.com/foaf/0.1/name”。那是什么意思? 我看到的一些例子就像引用他们的someurl / doc#name来描述名称对象等...
3)是否意味着如果应用程序模型的有效负载发生变化,合同的解释器会发生变化?因此所有客户端都像以前一样破解,就像在SOAP中一样?
4)另一种选择,我认为我可以有一个可进化的项目结构,比如集合+ json项目对象,其中Name,Value,Prompt构成了实际的结构,这样客户端的合同变化最小化消耗它。请告知我应该如何设计我的对象,基本上说我有一个带有多个地址的应用程序对象以及多个地址来简化问题。
约什
答案 0 :(得分:3)
目前最好的做法是尽可能避免创建新的内容类型,因此您可以回避这一点。
application/x-www-form-urlencoded
请求正文,那么HTML表单将是提供工作模板的绝佳方式。name
是foaf:name
,它告诉您名为name
的字段包含http://xmlns.com/foaf/0.1/name
类型的值。您应该阅读有关RDF(资源描述格式)的信息,并查看Turtle和N3之类的表示,这些表示应该更加清晰。虽然链接关系与诸如owl:sameAs
或foaf:name
之类的RDF属性不同,但是作为URI(而不是简单字符串)的关系的概念来自那里。两者都表示为directed graph中的边。在我看来,您的设计是一个简单的树结构,其中包含一个根资源,其中包含一个集合列表,每个集合都包含一个叶子资源列表。我似乎在这里遗漏了一些东西,因为那里没什么复杂的。
我将假设申请人是指申请工作的人,而地址是指他们居住或工作的地方(而不是电子邮件地址)。下面的一些内容可能很明显,但我将其包含在可能遇到此问题的其他读者中。
使用HAL的示例实现将是:
请求:
GET / HTTP/1.1
Host: example.com
Accept: application/hal+json
响应:
HTTP/1.1 200 OK
{ "_links": {
"self": { "href": "/" },
"http://example.com/docs/applicant": [
{ "href": "/applicant1" },
{ "href": "/applicant2" },
{ "href": "/applicant3" }]
} }
然后客户端会查找具有关系http://example.com/docs/applicant
的超链接,这只是一个字符串,如果您愿意,可以是fishmonkeygiraffe
- 使字符串成为http URL,允许客户端开发人员找到您的文档更容易,以及通过为其添加唯一字符串前缀来确定关系:您自己的域。
响应格式可以是任何支持超文本的格式,例如HTML,只要客户端知道如何在其中找到超链接(< LINK>和< A>元素),或者您可以在HTTP链接中返回它们如果需要将检索到的资源写入磁盘,则客户端负责存储它们。
客户端然后请求它想要查看的那个:
GET /applicant1 HTTP/1.1
Host: example.com
Accept: application/hal+json
响应:
HTTP/1.1 200 OK
{ "_links": {
"self": { "href": "/applicant1" },
"http://example.com/docs/applicant-address": [
{ "href": "/applicant1/address1" },
{ "href": "/applicant1/address2" },
{ "href": "/applicant1/address3" }]
} }
显然,“applicant1”可以是你喜欢的任何东西,例如“申请人/ 1”或“职位空缺/甜蜜经理/申请人/戴夫史密斯”。客户端只是遵循它给出的URL。
然后,客户端会选择类型http://example.com/docs/applicant-address
的超链接来检索:
GET /applicant1/address1 HTTP/1.1
Host: example.com
Accept: application/hal+json
响应:
HTTP/1.1 200 OK
{ "_links": {
"self": { "href": "/applicant1/address1" },
"edit-form": { "href": "/applicant1/address1/edit" },
"http://example.com/docs/applicant": { "href": "/applicant1" }
},
"street": "5 Dungeon Drive",
"town": "Snotty Hill",
"county": "London",
"postcode": "NE5 2LT",
"country": "GB",
}
现在客户想要修改地址,因此它遵循带有“edit-form”关系的超链接:(见IANA link relations)
GET /applicant1/address1/edit HTTP/1.1
Host: example.com
Accept: text/html
响应:
HTTP/1.1 200 OK
<!DOCTYPE HTML>
<form action="/applicant1/address1" method="POST">
<input name="street" value="5 Dungeon Drive">
et cetera
</form>
导致:
POST /applicant1/address1 HTTP/1.1
Host: example.com
Content-Type: application/x-www-form-urlencoded
street=5%20Dungeon%20Drive&...
我使用过HAL,因为HAL就像是XML + XLink的JSON版本,只需输入SO示例就更简单了;)即它是一种支持超媒体的通用解析格式,仅此而已。所有交互都由链接关系引导。 Web浏览器知道如何处理rel="stylesheet"
链接,因为它知道该关系意味着什么。以上引用的IANA定义的链接关系列表是您应该首先选择的(item
和collection
非常有用),然后如果您要查找的内容不够具体,请尝试查找与您所在行业相关的公共链接关系列表(例如,查看市场领导者发布的API),并在可能的情况下重新使用这些链接关系。这将允许工具变得可互操作,因为它们都在寻找相同的链接关系。您在问题中的都柏林核心示例是公开定义的RDF属性的类似存储库。
对于超链接,耦合(契约)不是在客户端和您的站点之间,而是客户端和一组关系。这种关系应尽可能众所周知(这就是维基百科在说“对超媒体的一般理解”时的意思。) 对于资源字段,如果您希望对资源进行一般性处理,那么我建议使用基于RDF的解决方案,使用与您的业务领域紧密相关的着名RDF属性。 Several RDF serialisations into JSON exist但目前没有明确的领导者。在这一点上,你可能最好只支持XML。博客文章 JSON to RDF in six easy steps 可能是一种深入了解RDF基础知识的方法。