Restful API 设计内容输出
Restful API Design Content Output
在 SO 成员的大力帮助下,我终于准备好我的 API 输出,他们回答了我所有的问题。顺便谢谢你。
但我想知道输出中的一件事。当我调用 URL 接收 API 内容时,我得到如下信息:
[
{
"data": [
{
"incidentReference": "R-20150405-887f93",
"latitude": 48.259698,
"longitude": 11.434679,
"archived": false
},
(...)
]
}
]
我读了这本书 "Build APIs you won't hate",它是很多东西的重要资源。但我不认为,我看到的输出是正确的。我的意思是,命名空间是我想要的东西。但它不应该是这样的吗?
{
"data": [
{
"incidentReference": "R-20150405-887f93",
"latitude": 48.259698,
"longitude": 11.434679,
"archived": false
},
(...)
]
}
那么整个事情不应该只是 JSON 吗?在我的例子中,它是 return 另外在一个数组中。完成这项工作的功能是:
public function index()
{
$incidents = Incident::all();
if( ! $incidents) {
return Response::json([
'error' => [
'message' => 'There are no incidents in the database.',
'code' => 100
]
], 404);
} else {
return $this->respond([
$this->respondWithCollection($incidents, new IncidentTransformer)
]);
}
}
public function respond($data, $headers = []) {
return Response::json($data, $this->getStatusCode(), $headers);
}
protected function respondWithCollection($collection, $callback) {
$resource = new Collection($collection, $callback);
$rootScope = $this->fractal->createData($resource);
return $rootScope->toArray();
}
所以是的,respondWithCollection return 是一个数组,但这在声明 return Response::json
的响应函数中处理,所以我希望在调用资源时有 json 输出。
这样可以吗?
下一个结构
{"data" : [{}, {}]}
当你有额外的字段时很好,例如项目总数、页数等:
{"data" : [{}, {}], "page":1, "total": 100}
不然还是用简单的结构真好:
[{"incidentReference": "R-20150405-887f93", ...}, {...}]
我建议您避免使用任何深层嵌套结构。
RESTful 响应应尽可能简单:输出纯 json 数据 仅 。因此,limit 和 offset 不应包含在服务器响应中,因为该客户端已经知道该信息。如果你格式化响应,你将不得不连接所有想要与你的响应服务交互的设备/平台/系统。
服务器应该 return 客户端不知道的额外信息,例如查询 collection 的一部分时的总元素。但我会为此使用 header 。这样,服务器仍然是 return 简单的 json 数组,它不仅可以由您的客户端处理,还可以由许多其他设备/平台/应用程序处理。
我的意见:仅输出纯 json 并使用 header 获取额外信息,例如此示例:
api/incidents/index.php :
// sanitize $_GET array, then output
$total = $incidents->getTotal();
$output = json_encode($incidents->fetch($GET['LIMIT'], $_GET['OFFEST'])); // pure example, I don't know how your framework works
// output
header('HTTP/1.1 200 OK');
header('Content-Type: application/json');
header('Collection-Total: '.$total);
header('Content-Length: ' . strlen($output));
echo $output;
例如,使用 jquery 访问此资源的 Web 应用程序如下所示:
var limit = 10;
var offset = 200;
$.ajax({
type: 'GET',
url:'http://mywebsite.com/api/incidents/',
data: {
'LIMIT': limit,
'OFFSET': offset
},
success: function(data, textStatus, request){
console.log('Incidents received...');
console.log(data);
console.log('There is ' + request.xhr.getResponseHeader('Collection-Total') + ' incidents in total');
},
});
我会避免嵌套结构,就像 Roman 所说的那样。 RESTful 资源需要有自己的标识符 (URI)。它必须 return 一个 object (项目)或 object 的数组(collection 个项目),像这样:
api/incidents // returns an array of objects
api/incident/[id] // returns a unique object (incident), using incident id in the URI
api/incidentreference/[id] // return an unique object (incident reference), usign incident reference id in URI
这种方法还导致了有趣的 cache 可能性,因为所有元素(项目或 collections)都有自己的标识符 (URI)。如果您使用 URI,Web 协议/平台/设备可能会缓存所有服务器结果并自动优化您的整个应用程序。
我还建议您的服务 return 200 OK 响应,即使没有要输出的元素也是如此。 404 表示找不到资源。已找到资源,但现在不包含任何元素。它稍后可能包含元素。某些设备/浏览器/平台可能会以不同方式处理 404 HTTP 代码。我可能错了,但我的 REST 服务总是 return 200 OK / 空 json 数组,我从来没有遇到过问题。但是,访问不存在的资源 (url) 将 return 404。
在 SO 成员的大力帮助下,我终于准备好我的 API 输出,他们回答了我所有的问题。顺便谢谢你。
但我想知道输出中的一件事。当我调用 URL 接收 API 内容时,我得到如下信息:
[
{
"data": [
{
"incidentReference": "R-20150405-887f93",
"latitude": 48.259698,
"longitude": 11.434679,
"archived": false
},
(...)
]
}
]
我读了这本书 "Build APIs you won't hate",它是很多东西的重要资源。但我不认为,我看到的输出是正确的。我的意思是,命名空间是我想要的东西。但它不应该是这样的吗?
{
"data": [
{
"incidentReference": "R-20150405-887f93",
"latitude": 48.259698,
"longitude": 11.434679,
"archived": false
},
(...)
]
}
那么整个事情不应该只是 JSON 吗?在我的例子中,它是 return 另外在一个数组中。完成这项工作的功能是:
public function index()
{
$incidents = Incident::all();
if( ! $incidents) {
return Response::json([
'error' => [
'message' => 'There are no incidents in the database.',
'code' => 100
]
], 404);
} else {
return $this->respond([
$this->respondWithCollection($incidents, new IncidentTransformer)
]);
}
}
public function respond($data, $headers = []) {
return Response::json($data, $this->getStatusCode(), $headers);
}
protected function respondWithCollection($collection, $callback) {
$resource = new Collection($collection, $callback);
$rootScope = $this->fractal->createData($resource);
return $rootScope->toArray();
}
所以是的,respondWithCollection return 是一个数组,但这在声明 return Response::json
的响应函数中处理,所以我希望在调用资源时有 json 输出。
这样可以吗?
下一个结构
{"data" : [{}, {}]}
当你有额外的字段时很好,例如项目总数、页数等:
{"data" : [{}, {}], "page":1, "total": 100}
不然还是用简单的结构真好:
[{"incidentReference": "R-20150405-887f93", ...}, {...}]
我建议您避免使用任何深层嵌套结构。
RESTful 响应应尽可能简单:输出纯 json 数据 仅 。因此,limit 和 offset 不应包含在服务器响应中,因为该客户端已经知道该信息。如果你格式化响应,你将不得不连接所有想要与你的响应服务交互的设备/平台/系统。
服务器应该 return 客户端不知道的额外信息,例如查询 collection 的一部分时的总元素。但我会为此使用 header 。这样,服务器仍然是 return 简单的 json 数组,它不仅可以由您的客户端处理,还可以由许多其他设备/平台/应用程序处理。
我的意见:仅输出纯 json 并使用 header 获取额外信息,例如此示例:
api/incidents/index.php :
// sanitize $_GET array, then output
$total = $incidents->getTotal();
$output = json_encode($incidents->fetch($GET['LIMIT'], $_GET['OFFEST'])); // pure example, I don't know how your framework works
// output
header('HTTP/1.1 200 OK');
header('Content-Type: application/json');
header('Collection-Total: '.$total);
header('Content-Length: ' . strlen($output));
echo $output;
例如,使用 jquery 访问此资源的 Web 应用程序如下所示:
var limit = 10;
var offset = 200;
$.ajax({
type: 'GET',
url:'http://mywebsite.com/api/incidents/',
data: {
'LIMIT': limit,
'OFFSET': offset
},
success: function(data, textStatus, request){
console.log('Incidents received...');
console.log(data);
console.log('There is ' + request.xhr.getResponseHeader('Collection-Total') + ' incidents in total');
},
});
我会避免嵌套结构,就像 Roman 所说的那样。 RESTful 资源需要有自己的标识符 (URI)。它必须 return 一个 object (项目)或 object 的数组(collection 个项目),像这样:
api/incidents // returns an array of objects
api/incident/[id] // returns a unique object (incident), using incident id in the URI
api/incidentreference/[id] // return an unique object (incident reference), usign incident reference id in URI
这种方法还导致了有趣的 cache 可能性,因为所有元素(项目或 collections)都有自己的标识符 (URI)。如果您使用 URI,Web 协议/平台/设备可能会缓存所有服务器结果并自动优化您的整个应用程序。
我还建议您的服务 return 200 OK 响应,即使没有要输出的元素也是如此。 404 表示找不到资源。已找到资源,但现在不包含任何元素。它稍后可能包含元素。某些设备/浏览器/平台可能会以不同方式处理 404 HTTP 代码。我可能错了,但我的 REST 服务总是 return 200 OK / 空 json 数组,我从来没有遇到过问题。但是,访问不存在的资源 (url) 将 return 404。