每当我拨打/api/v1/posts/1
时,呼叫都会转发到show
方法
public function show(Post $post) {
return $post;
}
在PostController.php
资源控制器中。如果帖子确实存在,则服务器返回JSON响应。但是,如果帖子不存在,则服务器返回纯HTML,尽管请求显然期望JSON作为回报。这是Postman的演示。
问题是API应该返回application/json
,而不是text/html
。所以,这是我的问题:
1。如果我们使用隐式路由模型绑定时发生异常,Laravel是否内置支持自动返回JSON(如上面的show
方法,当我们有404)?
2. 如果是,我该如何启用它? (默认情况下,我得到纯HTML,而不是JSON)
如果它没有在每个 API控制器上复制以下内容的替代方法
public function show($id) {
$post = Post::find($id); // findOrFail() won't return JSON, only plain HTML
if (!$post)
return response()->json([ ... ], 404);
return $post;
}
3。在app\Exceptions\Handler
中是否有通用的方法?
4. 标准错误/异常响应包含什么?我用Google搜索了这个,但发现了许多自定义变体。
5. 为什么JSON响应仍然构建在隐式路由模型绑定中?为什么不简化开发人员生活并自动处理这种低级别的麻烦?
在Laravel IRC的人员建议我单独留下错误响应,认为标准HTTP异常在默认情况下呈现为HTML 以及使用API的系统之后,我留下了一个难题应该处理404s而不看身体。我希望更多的人加入讨论,我想知道你们会如何回应。
答案 0 :(得分:6)
我在app/Exceptions/Handler.php
中使用此代码,可能您需要进行一些更改
public function render($request, Exception $exception)
{
$exception = $this->prepareException($exception);
if ($exception instanceof \Illuminate\Http\Exception\HttpResponseException) {
return $exception->getResponse();
}
if ($exception instanceof \Illuminate\Auth\AuthenticationException) {
return $this->unauthenticated($request, $exception);
}
if ($exception instanceof \Illuminate\Validation\ValidationException) {
return $this->convertValidationExceptionToResponse($exception, $request);
}
$response = [];
$statusCode = 500;
if (method_exists($exception, 'getStatusCode')) {
$statusCode = $exception->getStatusCode();
}
switch ($statusCode) {
case 404:
$response['error'] = 'Not Found';
break;
case 403:
$response['error'] = 'Forbidden';
break;
default:
$response['error'] = $exception->getMessage();
break;
}
if (config('app.debug')) {
$response['trace'] = $exception->getTrace();
$response['code'] = $exception->getCode();
}
return response()->json($response, $statusCode);
}
此外,如果您将使用formRequest验证,则需要覆盖方法response
,否则您将被重定向,这可能会导致一些错误。
use Illuminate\Http\JsonResponse;
...
public function response(array $errors)
{
// This will always return JSON object error messages
return new JsonResponse($errors, 422);
}
答案 1 :(得分:3)
- 是否有在app \ Exceptions \ Handler中使用的通用方法?
醇>
您可以检查通用异常处理程序中是否需要json。
// app/Exceptions/Handler.php
public function render($request, Exception $exception) {
if ($request->expectsJson()) {
return response()->json(["message" => $exception->getMessage()]);
}
return parent::render($request, $exception);
}
答案 2 :(得分:-1)
我们通过创建一个负责返回响应部分的基本控制器来处理它的方式。看起来像这样,
class BaseApiController extends Controller
{
private $responseStatus = [
'status' => [
'isSuccess' => true,
'statusCode' => 200,
'message' => '',
]
];
// Setter method for the response status
public function setResponseStatus(bool $isSuccess = true, int $statusCode = 200, string $message = '')
{
$this->responseStatus['status']['isSuccess'] = $isSuccess;
$this->responseStatus['status']['statusCode'] = $statusCode;
$this->responseStatus['status']['message'] = $message;
}
// Returns the response with only status key
public function sendResponseStatus($isSuccess = true, $statusCode = 200, $message = '')
{
$this->responseStatus['status']['isSuccess'] = $isSuccess;
$this->responseStatus['status']['statusCode'] = $statusCode;
$this->responseStatus['status']['message'] = $message;
$json = $this->responseStatus;
return response()->json($json, $this->responseStatus['status']['statusCode']);
}
// If you have additional data to send in the response
public function sendResponseData($data)
{
$tdata = $this->dataTransformer($data);
if(!empty($this->meta)) $tdata['meta'] = $this->meta;
$json = [
'status' => $this->responseStatus['status'],
'data' => $tdata,
];
return response()->json($json, $this->responseStatus['status']['statusCode']);
}
}
现在您需要在控制器中扩展它
class PostController extends BaseApiController {
public function show($id) {
$post = \App\Post::find($id);
if(!$post) {
return $this->sendResponseStatus(false, 404, 'Post not found');
}
$this->setResponseStatus(true, 200, 'Your post');
return $this->sendResponseData(['post' => $post]);
}
}
你会得到这样的回应
{
"status": {
"isSuccess": false,
"statusCode": 404,
"message": "Post not found"
}
}
{
"status": {
"isSuccess": true,
"statusCode": 200,
"message": "Your post"
},
"data": {
"post": {
//Your post data
}
}
}
答案 3 :(得分:-3)
您只需使用use Illuminate\Support\Facades\Response;
即可。
那么,回复就是:
public function index(){
$analysis = Analysis::all();
if(empty($analysis)) return Response::json(['error'=>'Empty data'], 200);
return Response::json($analysis, 200, [], JSON_NUMERIC_CHECK);
}
现在你将有一个JSON返回....