【问题标题】:Laravel validation always returns 200 OK from APILaravel 验证总是从 API 返回 200 OK
【发布时间】:2019-03-02 10:47:40
【问题描述】:

我想将验证器与控制器分开,但 API 在 Postman 中总是以 200 OK 响应。

请求验证

class PostRequest extends FormRequest
{
    use Types;

    public function authorize()
    {
        return true;
    }

    public function rules()
    {
        // $auth = $this->request->user();
        return [
            'name'       => 'required|string|max:255',
            'country_id' => 'required|exists:countries,id',
            'city'       => 'required|max:255',
            'phone_no'   => 'required|regex:/[0-9]{10,13}/',
            'occupation' => 'required|max:255'
        ];
    }
}

SenderController

public function store(PostRequest $request)
{
    $auth = $request->user();

    $sender = Sender::create([
        'name'          => $request->name,
        'country_id'    => $request->country_id,
        'city'          => $request->city,
        'phone_no'      => $request->phone_no,
        'occupation'    => $request->occupation
    ]);
    return new Resource($sender);
}

当我发送没有name 的请求时,它将返回状态为200 的响应。当我忘记输入名称时,我想在响应中显示$validator->errors()。我该怎么做?

路由和呼叫

Route::post('sender', 'V1\SenderController@store');

POST: localhost:8000/api/v1/sender

【问题讨论】:

  • 可以分享一下邮递员的截图吗
  • 我已经发布了截图@ShaielndraGupta
  • “将我的验证器与我的控制器分开”是什么意思?
  • 我的意思是我通常在我的控制器中使用验证,但现在,我想尝试像我现在所做的那样分离文件@emotality
  • 所以注入一个普通的Request 而不是PostRequest,不是吗?顺便说一句,如果您的密钥与现在相同,您只需 Sender::create($request->all());Sender::create($request->only(['key1', 'key2'])); 即可,无需重新创建相同的结构。 :)

标签: php laravel validation


【解决方案1】:

如果你是从邮递员那里请求,那么总是检查标题并设置

Accept = 'application/json'

【讨论】:

    【解决方案2】:

    您应该确保发送带有Accept: application/json 标头的请求。

    否则 - Laravel 不会检测到它是一个 API 请求,也不会生成带有错误的 422 响应。

    【讨论】:

      【解决方案3】:

      使用注入的FormRequest 对象显示验证错误的正确方法是覆盖failedValidation

      如前面在评论部分所述,注入的FormRequest 对象会自行验证请求,无需在控制器主体中再次验证它(这是它的主要好处之一)。如果验证失败,您无论如何都不会点击控制器主体。

      创建一个扩展 FormRequest 并覆盖 failedValidation 的抽象类。

      <?php
      
      namespace App\Http\Requests;
      
      use Illuminate\Contracts\Validation\Validator;
      use Illuminate\Foundation\Http\FormRequest;
      use Illuminate\Http\Exceptions\HttpResponseException;
      use Illuminate\Http\Response;
      
      abstract class BaseFormRequest extends FormRequest
      {
          /**
           * Get the validation rules that apply to the request.
           *
           * @return array
           */
          abstract public function rules(): array;
      
          /**
           * Determine if the user is authorized to make this request.
           *
           * @return bool
           */
          abstract public function authorize(): bool;
      
          /**
           * Handle a failed validation attempt.
           *
           * @param  Validator  $validator
           *
           * @return void
           */
          protected function failedValidation(Validator $validator): void
          {
              $errors = $validator->errors();
      
              throw new HttpResponseException(response()->json([
                  'errors' => $errors
              ], Response::HTTP_UNPROCESSABLE_ENTITY));
          }
      }
      

      您现在可以在所有 API 请求验证类上扩展 BaseFormRequest。验证错误现在将显示为带有不可处理实体 (422) HTTP 代码的 JSON 编码消息。

      来源:https://medium.com/@Sirolad/laravel-5-5-api-form-request-validation-errors-d49a85cd29f2

      【讨论】:

        【解决方案4】:

        我通过在 PostRequest.php 中添加更多代码解决了这个问题

        public $validator = null;
        protected function failedValidation($validator)
        {
            $this->validator = $validator;
        }
        

        我使用控制器显示错误消息

        if (isset($request->validator) && $request->validator->fails()) {
                return response()->json([
                    'error_code'=> 'VALIDATION_ERROR', 
                    'message'   => 'The given data was invalid.', 
                    'errors'    => $request->validator->errors()
                ]);
            }
        

        【讨论】:

          【解决方案5】:

          您必须在保存之前验证您的请求

          public function store(PostRequest $request)
          {
              $auth = $request->validate();
          
              if($auth->fails())
              {
                   return response()->json($auth->errors());
              }
              $sender = Sender::create([
                  'name'          => $request->name,
                  'country_id'    => $request->country_id,
                  'city'          => $request->city,
                  'phone_no'      => $request->phone_no,
                  'occupation'    => $request->occupation
              ]);
               return new Resource($sender);
          
          }
          

          【讨论】:

          • 如果你方法注入一个 FormRequest 对象,它会自动进行验证。
          • 为什么它会在构造函数中自动进行验证..? @GeorgeHanson
          • 您能引用文档吗?我从来没见过这个,一直用-&gt;validated()
          • @emotality 验证方法用于检索已验证的输入数据,而不是运行验证过程。
          【解决方案6】:

          您的 Postman 响应是发回 welcome.blade.php 默认视图。这意味着它没有命中您的控制器方法,因为该方法返回 Resource 实例。这意味着验证器不会运行。

          检查您发出请求的路线是否绝对是正确的路线。还要检查您是否发出 POST 请求而不是 GET 请求。

          【讨论】:

          • 你是对的,它调用了我的welcome.blade.php.. 但是如果我通过验证,它会调用实际的API
          • 它根本没有达到验证。你能发布你的路线,你提出请求的网址和请求方法吗?
          • 那么,我应该怎么做才能让它通过验证?
          • 我可以看到你已经添加了路线。您在 Postman 中发布的 URL 是什么?您发出请求的 URL 很可能是错误的。
          • 路由是否在api前缀路由组内?如果没有,那么您不需要在您请求的网址中使用api。尝试将您的路线从 Route::post('sender', 'V1\SenderController@store'); 更改为 Route::post('api/v1/sender', 'V1\SenderController@store');
          猜你喜欢
          • 2022-10-04
          • 2015-01-04
          • 2013-11-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-01-14
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多