流明验证不会指定哪些字段失败

时间:2016-11-07 00:34:10

标签: php laravel api lumen

我正在尝试在我的Lumen API中包含验证,但是当验证失败时我对响应有些困难:

BooksController.php

  public function store(Request $request)
  {
    $this->validateBook($request);

    $book = Book::create($request->all());
    $data = $this->item($book, new BookTransformer());

    return response()->json($data, 201, [
      'Location' => route('books.show', ['id' => $book->id]),
    ]);
  }

  private function validateBook(Request $request)
  {
    $this->validate($request, [
      'title'       => 'required|max:255',
      'description' => 'required',
      'author_id'   => 'required|exists:authors,id',
    ], [
      'description.required' => 'Please fill out the description.',
    ]);
  }

我已修改我的处理程序以检查ValidationException的实例,但无论出于何种原因,我的响应总是相同的......

Handler.php

  public function render($request, Exception $e)
  {
    if ($request->wantsJson()) {
      $response = [
        'message' => (string) $e->getMessage(),
        'status'  => 400,
      ];

      if ($e instanceof HttpException) {
        $response['message'] = Response::$statusTexts[$e->getStatusCode()];
        $response['status']  = $e->getStatusCode();
      } else if ($e instanceof ModelNotFoundException) {
        $response['message'] = Response::$statusTexts[Response::HTTP_NOT_FOUND];
        $response['status']  = Response::HTTP_NOT_FOUND;
      } else if ($e instanceof ValidationException) {

        // [BUG] Shouldn't this display the fields that have failed?
        $response['message'] = 'how do I display what fields failed?'; 
        $response['status']  = Response::HTTP_UNPROCESSABLE_ENTITY;        

      }

      if ($this->isDebugMode()) {
        $response['debug'] = [
          'exception' => get_class($e),
          'trace'     => $e->getTrace(),
        ];
      }

      return response()->json(['error' => $response], $response['status']);
    }

    return parent::render($request, $e);

  }

如果我删除了检查代码而不是ValidationException的代码块,那么我的回复总是一样的:

{
  "error": {
    "message": "The given data failed to pass validation.",
    "status": 400
  }
}

然而,对于客户端试图与API接口的任何人来说,这将被证明是一场噩梦,因为它没有指定哪些字段失败并且不包含我的自定义错误消息。

我期待更多的东西:

{
  "error": {
    "message": "The given data failed to pass validation.",
    "errors": {
         "title": "The title is required.",
         "description": "Please fill out the description."
     },
    "status": 422
  }
}

我做错了什么?我怎样才能做到这一点?

2 个答案:

答案 0 :(得分:1)

事实证明,我需要让父处理程序处理错误响应,而不是检查ValidationException的实例并返回我自己的自定义响应。修订后的代码如下:

<强> Handler.php

  public function render($request, Exception $e)
  {
    if ($request->wantsJson() && !($e instanceof ValidationException)) {
      $response = [
        'message' => (string) $e->getMessage(),
        'status'  => 400,
      ];

      if ($e instanceof HttpException) {
        $response['message'] = Response::$statusTexts[$e->getStatusCode()];
        $response['status']  = $e->getStatusCode();
      } else if ($e instanceof ModelNotFoundException) {
        $response['message'] = Response::$statusTexts[Response::HTTP_NOT_FOUND];
        $response['status']  = Response::HTTP_NOT_FOUND;
      }

      if ($this->isDebugMode()) {
        $response['debug'] = [
          'exception' => get_class($e),
          'trace'     => $e->getTrace(),
        ];
      }

      return response()->json(['error' => $response], $response['status']);
    }

    return parent::render($request, $e);
  }

答案 1 :(得分:0)

如果您只想获得验证字段错误,可以从getResponse方法的内容中获取它。结果是一个json字符串,所以你需要json_decode它

public function render($request, exception $e)
{
    $rendered = parent::render($request, $e);
    $statusCode = $rendered->getstatuscode();
    $errorResponse = [
        'error' => true,
        'code' => $statusCode,
        'message' => $e->getmessage(),
    ];
    if ($e instanceof ValidationException) {
        $errorResponse['message'] = json_decode($e->getResponse()->content());
    }
    return response()->json($errorResponse, $statusCode);
}