Json REST资源根据状态返回不同的对象
我正试图定义一个RESTAPI,但有一个需求遇到了问题。 我有一个API用户可以做的动作,这是同一件事,但可以用两种不同的方式来做 例如,假设我的用户使用我的API来更改灯光的强度。我会有一个类似的URL 空气污染指数/光照/强度 用户必须更改强度的一个选项是将强度设置为最大亮度的%,另一个选项是将强度设置为以流明为单位的精确值(有一个检测器),用户可以通过低、中、高的“精度”(它改变达到正确强度所需的时间) 我希望用户能够获得当前强度,这意味着他处于哪种模式,取决于模式、百分比或流明值以及精度 这就是我丢失的地方,我的GET将返回一个JSON对象,例如,发送类似Json REST资源根据状态返回不同的对象,json,rest,Json,Rest,我正试图定义一个RESTAPI,但有一个需求遇到了问题。 我有一个API用户可以做的动作,这是同一件事,但可以用两种不同的方式来做 例如,假设我的用户使用我的API来更改灯光的强度。我会有一个类似的URL 空气污染指数/光照/强度 用户必须更改强度的一个选项是将强度设置为最大亮度的%,另一个选项是将强度设置为以流明为单位的精确值(有一个检测器),用户可以通过低、中、高的“精度”(它改变达到正确强度所需的时间) 我希望用户能够获得当前强度,这意味着他处于哪种模式,取决于模式、百分比或流明值以及精度
{
"Mode" = "Percent",
"Percent" = 50.5
}
当我处于“百分比”模式时
当我处于“流明”模式时
如果看起来还可以,我如何告诉用户应该解析哪种类型的“对象”
让用户发送更改的最佳方式是什么?我在考虑有两个URL,每个模式一个,比如
PUT/api/光照/强度/精确和PUT/api/光照/强度/百分比
两者都在等待类似于上面的JSON对象,没有模式。具体取决于您的API和用户的需求。对RESTful API的相同GET方法调用应始终返回相同的值:URL中的信息定义的资源表示形式,而不返回其他值。如果您在系统中维护状态,则违反了REST规则。(Edit:正如Gimly所指出的,这一说法并不清楚。系统维护自身内部状态并不违反RESTful设计,特别是当请求使用
PUT
、POST
或DELETE来更改系统状态时。请求依赖该状态进行retu是违法的注册资源的表示形式,或请求状态更改。每个请求都应该是自包含的。)
我将使用查询字符串更改表示的格式:
GET /api/light/intensity
GET /api/light/intensity?f=percent
这样一来,/api/light/intensity
总是引用相同的资源(默认为“精确”表示法,其中数据最多),查询字符串“过滤”表示法,类似于搜索查询。它删除了一些数据(在本例中,是精确的亮度和精度),以支持以某个最大值的百分比表示的相对表示。或者,您可以将其视为控制输出格式:GET/foo.json
vsGET/foo.xml
。资源相同,但表示形式不同
要更新资源,可以按照前面的描述获取对象。您的服务器必须了解不同的格式,但您可以将放入裸URL,或者再次使用查询参数控制服务器所需的格式,然后使用值而不是流明或百分比,使负载更加抽象:
PUT /api/light/intensity
Payload: {"value": 200, "precision": "high"}
PUT /api/light/intensity?f=percent
Payload: {"value": 50.5}
这允许您为light
资源构建API,使强度
成为资源的一个属性。然后,“百分比”在输出中成为一种方便的表示形式,因此当您返回整个灯光
资源时,它的内容如下:
"light": {
"name": "the light",
"id": 12345,
"intensity": 200,
"max-intensity": 400,
...
}
因此API用户可以根据强度
和最大强度
计算当前百分比。(当然,你可以用“百分比”代替“最大强度”,让用户用另一种方式计算,但我觉得提供绝对值和让数学计算相对值更自然
编辑
请参阅Tichodroma的答案,了解更好的处理方法。我留下答案是因为评论中的讨论对我很有用,将来可能对其他人有用。使用。这允许:
- 客户端告诉服务器它想要
获取的资源的表示形式
- 服务器告诉客户端它返回给客户端的资源的表示形式
- 客户机告诉服务器它将资源的什么表示放到服务器上
定义两种供应商内容类型:
application/vnd.com.example.light.intensity.percentage+json
application/vnd.com.example.light.intensity.lumens+json
客户端告诉服务器它想要哪一个:
GET /api/light/intensity/
Accept: application/vnd.com.example.light.intensity+percentage
服务器响应:
200 OK
Content-Type: application/vnd.com.example.light.intensity+percentage
{
"Percent" = 50.5
}
客户希望更改强度:
PUT /api/light/intensity/
Content-Type: application/vnd.com.example.light.intensity+percentage
{
"Percent" = 42.7
}
服务器从内容类型
头知道如何解释JSON正文。在本例中,它以“百分比”模式处理请求
如果使用第二种内容类型,客户端和服务器将知道如何将请求/响应解释为“Lumes”模式
编辑:请注意,GET
和PUT
请求使用相同的URL,因为请求是关于相同的资源:光强度。唯一不同的是此资源的表示形式。正确的处理方法是内容类型。您的方法是对相同的资源使用不同的URL列出光照强度。这不是RESTful。一个资源,一个URL。除非我缺少输入错误,否则URL是相同的:/api/light/intensity
。表示形式从默认值(“精确”,用OP的术语)更改为相对值(或“百分比”)基于查询字符串。查询参数可以控制不同的筛选器和格式,而不会违反资源本身的规范地址。我是否误解了您的评论??f=percent
是URL的一部分。查询字符串参数通常用于
PUT /api/light/intensity/
Content-Type: application/vnd.com.example.light.intensity+percentage
{
"Percent" = 42.7
}