所以我想允许用户在向服务器运行rest API请求时请求.xml或.json响应。 (很像推特)
但我不相信以下方式是最好的方法,因为它意味着重复的代码,肯定有更好的方法来允许.xml或.json响应。
$app->get('/books/:id.xml', function ($id) use ($app) {
$app->render('/xml/books.xml', array('id' => $id));
});
$app->get('/books/:id.json', function ($id) use ($app) {
$app->render('json/books.json', array('id' => $id));
});
OR
// Define app routes
$app->get('/hello/{name}.{type}', function ($request, $response, $args) {
//return $response->write("Hello " . $args['name']);
if($args['type'] == 'xml')
{
return 'this is xml';
}
var_dump(parse_url($_SERVER['REQUEST_URI']));
});
如果有人知道怎么做,那就太好了。
答案 0 :(得分:0)
考虑在URI的末尾使用Accept
请求的HTTP标头的值而不是文件扩展名。
我认为使用标头更可靠,更“正确”的方式来确定应该返回数据的格式。
URI应该用于指向特定资源。客户端应发送Accept
标头,告诉您应该返回数据的格式。
除了作为实现RESTful服务的标准方法之外,它还消除了改变路由的麻烦(如第二个例子)。
如果您同意此类实施,则需要excellent library来解决您的问题。
它有很多用途,这是一个用例的例子:
<?php
use Negotiation\Negotiator;
use Psr\Http\Message\ServerRequestInterface as Request;
use Psr\Http\Message\ResponseInterface as Response;
class YourController
{
public function __construct(Negotiator $negotiator, DataProvider $someDataProvider)
{
$this->negotiator = $negotiator;
$this->someDataProvider = $someDataProvider;
}
/**
* Processing request.
*
* We get data, then we use Negotiator to detect what format the requestor prefers.
* Then we return data in requested format or in case format is not supported,
* fall back to JSON.
*
*
* @param Request $request
* @param Response $response
* @return Response
*/
public function __invoke(Request $request, Response $response)
{
$data = $this->someDataProvider->getSomeData();
$mediaType = $this->determineMediaType($request);
switch ($mediaType) {
case 'application/json':
default:
// $data = $data->asJson();
// transform data to JSON...
break;
case 'application/xml':
$data = $data->asXml();
// transform data to XML...
break;
}
// Write data to body of response
$response->getBody()->write($data);
// Set appropriate response header
return $response->withHeader('Content-Type', $mediaType);
}
/**
* Find preferred data format from Accept header.
*
* Uses Negotiator to determine whether JSON or XML should be returned.
*
* @param Request $request
* @return string
*/
private function determineMediaType(Request $request)
{
$acceptHeader = $this->extractAcceptHeader($request);
// Set list of "known" formats, i.e. formats that your service supports
$known = ['application/json', 'application/xml'];
// Let negotiator determine what format should be used
$mediaType = $this->negotiator->getBest($acceptHeader, $known);
if ($mediaType) {
return $mediaType->getValue();
} else {
return 'application/json'; # if request has unexpected value of accept header, default to JSON
}
}
/**
* Extract Accept header value from Request object
* @param Request $request
* @return string
*/
private function extractAcceptHeader(Request $request)
{
return $request->getHeaderLine('Accept');
}
}
此类是路由回调的示例。这样的实现允许您轻松扩展支持的格式列表,而不会篡改路由。