Laravel API Request Validation - php

Hello: I am writing an api with Laravel.
When I try to use request validation in the controller, I get a 405 method not allowed. When I remove the request validation, everything runs smoothly.
Here is my route:
Route::post('product/create', 'Api\v1\ProductController#create');
Here is my controller:
<?php
namespace App\Http\Controllers\Api\v1;
use App\Http\Requests\CreateProduct;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use App\Handlers\Products;
use Illuminate\Support\MessageBag;
class ProductController extends Controller
{
/**
* Create Product.
*/
public function create(CreateProduct $request)
{
echo 'product created...';
}
}
Here is my request validator:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CreateProduct extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'title' => 'required',
'price' => 'required',
'short_description' => 'required'
];
}
/**
* Set custom validation messages.
*
* #return array
*/
public function messages()
{
return [
'title.required' => 'Please enter a title.',
'price.required' => 'Please enter a price.',
'short_description.required' => 'Please enter a short description.'
];
}
}
When I remove "CreateProduct $request" from the "create" method, everything works.
How can I use Laravel's request validation for api calls?

Set validation in Product Controller.
public function create(Request $request)
{
$rules=array(
'title' => 'required',
'price' => 'required',
'short_description' => 'required'
);
$messages=array(
'title.required' => 'Please enter a title.',
'price.required' => 'Please enter a price.',
'short_description.required' => 'Please enter a short description.'
);
$validator=Validator::make($request->all(),$rules,$messages);
if($validator->fails())
{
$messages=$validator->messages();
$errors=$messages->all();
return $this->respondWithError($errors,500);
}
echo 'product created...';
}

as #oseintow suggested:
if ($exception instanceof ValidationException) {
return response()->json(['errors'=>$exception->errors()], JsonResponse::HTTP_UNPROCESSABLE_ENTITY);
}

I had the same problem when I was testing my API with PostMan. It turns out I was using the wrong Headers (Accept and Content-Type should be application/json but instead I was using the application/x-www-form-urlencoded for Content-Type).
After correcting that the custom request was working just fine.

Add this to your exception > handler.php > render method
if($exception instanceof \Illuminate\Validation\ValidationException){}
return parent::render($request, $exception);
Hope it helps

just simply add ","
i think after this every thing run smoothly
this is how i use rules for code readability
https://pastebin.com/ivBEf7mT
public function rules()
{
return [
'title' => 'required',
'price' => 'required',
'short_description' => 'required',
];
}

Related

how to detect if a field has input in laravel

I was trying to create a validation in laravel controller, where if one of the fields has input, then it will validate the rest of the fields to be 'required'. But it prompts Error
Class 'Illuminate\Support\Facades\Input' not found. Please help
if(Input::has('quantity1') || has('unit1') || has('dimension1') || has('price1')){
$data = $request->validate([
'quantity1' => 'required',
'unit1' => 'required',
'dimension1' => 'required',
'price1' => 'required',
]);
Use required_with laravel validation rule...
$data = $request->validate([
'quantity1' => 'required_with:unit1,dimension1,price1',
'unit1' => 'required_with:quantity1,dimension1,price1',
'dimension1' => 'required_with:quantity1,unit1,price1',
'price1' => 'required_with:quantity1,unit1,dimension1',
]);
Input is deprecated.
I would highly suggest creating a custom request class and using that.
The benfits include:
Conforming to SOLID principles.
Easy place to manage your rules and messages.
Easy place to handle permissions should you choose.
Can be extended and reused as needed.
--
Here are the steps how to do that:
Run php artisan make:request YourCustomRequestClassNamae
Fill the new app\Http\Requests\YourCustomRequestClassNamae.php file with:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class YourCustomRequestClassNamae extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'quantity1' => 'required',
'unit1' => 'required',
'dimension1' => 'required',
'price1' => 'required',
];
}
}
In the controller do something like:
<?php
namespace App\Http\Controllers;
...
use App\Http\Requests\YourCustomRequestClassNamae;
...
class YourControllerName extends Controller
{
...
public function yourMethodName(YourCustomRequestClassNamae $request)
{
$validatedData = $request->validated();
...
If the validation above fails it will return back with a 422 and the messages automatically ready to be pulled from the message bag.
Sources:
https://laravel.com/docs/master/validation#form-request-validation
Example in the wild:
https://github.com/jeremykenedy/larablog/blob/master/app/Http/Requests/StoreTagRequest.php
https://github.com/jeremykenedy/larablog/blob/master/app/Http/Controllers/Admin/TagController.php#L7
https://github.com/jeremykenedy/larablog/blob/master/app/Http/Controllers/Admin/TagController.php#L56

Hw can I get Url params (id for example) in request made by php artisan make:request

I want to create a Request made by php artisan make:request wherein rules I can add a param, for instance I have the following validator in the controller:
$validator = Validator::make($request->all(), [
'title' => 'required|unique:posts|max:{{number}}',
'body' => 'required',
]);
Where number is from url parameter
How can I get this url parameter in my Request class?
Here is my Request class:
<?php
namespace Modules\Blog\Http\Requests;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Http\Exceptions\HttpResponseException;
class SaveBlogCategoriesRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
dd($request->param);
return [
'lang' => 'required',
'name' => 'required',
'slug' => "required|unique:blog_categories_id,slug,", // here I want to add id from param
];
}
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
protected function failedValidation(Validator $validator)
{
$data = [
'status' => false,
'validator' => true,
'msg' => [
'e' => $validator->messages(),
'type' => 'error'
],
];
throw new HttpResponseException(response()->json($data));
}
}
For the request class, you dont need to instantiate the validator
class ModelCreateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
//if you need the input, you can access it via $this->request;
$param = $this->request->get('param');
//or you can also access it directly (yeah I know it not intuitive)
$param = $this->param
return [
'lang' => 'required',
'name' => 'required',
'slug' => "required|unique:blog_categories_id,slug,".$param,
];
}
}
Use dd($this) to get the request object in request class

How to pass non required fields through FormRequest?

I'm using FormRequest for Validation.
I'm creating record in DB. There a some fields which are not required, how can i get them through FormRequest. At, the moment i'm only getting fields which are in rules() method.
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class CategoryRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'title_tr' => 'required|min:2|max:255',
'description_tr' => 'required',
'parent_id' => 'required',
'seo_title_tr' => 'required',
'meta_description_tr' => 'required'
];
}
public function messages(){
return [
'title_tr.required' => trans('admin.category.validation_errors.title_tr'),
'description_tr.required' => trans('admin.category.validation_errors.description_tr'),
'seo_title_tr.required' => trans('admin.category.validation_errors.seo_title_tr'),
'meta_description_tr.required' => trans('admin.category.validation_errors.meta_description_tr'),
];
}
}
you can use sometimes
Validating When Present In some situations, you may wish to run
validation checks against a field only if that field is present in the
input array. To quickly accomplish this, add the sometimes rule to
your rule list:
public function rules()
{
return [
'username' => 'sometimes',
];
}
You can make it nullable as shown below.
public function rules()
{
return [
// ...
'not_required_field' => 'nullable',
];
}

Laravel: Custom validation messages in Custom Form Requests

I am trying to keep my controller clean and move the custom request validation in to a separate class as:
public function register(RegisterUserRequest $request)
and in there define all the usual functions, such as
public function rules(),
public function messages(), and
public function authorize()
However, the frontend is expecting the following data to display:
title (title related to the validation error message), description (which is the the actual validation error message), and status (=red, yellow etc)
How can I actually customise the response of the request?
Something like this, does not seem to be working:
protected function failedValidation(\Illuminate\Contracts\Validation\Validator $validator)
{
$response = new Response(['data' => [],
'meta' => [
'title' => 'Email Invalid'
'description' => '(The error message as being returned right now)',
'status' => 'red'
]);
throw new ValidationException($validator, $response);
}
Any ideas?
you can do this by making request in laravel as the following :
php artisan make:request FailedValidationRequest
this command will create class called FailedValidationRequest in
App\Http\Request directory and you cab write your rules inside this class as the following:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class FailedValidationRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'title' => 'required'
'description' => 'required',
'status' => 'required|numeric'
];
}
}
and if you want to customize the error message you can download the language you want from this link using composer:
https://packagist.org/packages/caouecs/laravel-lang
and write the language you want by copying the languge folwder to the lang directory in your resource folder.
'custom' => [
'title' => [
'required' => 'your custom message goes here',
],
'decription' => [
'required' => 'your custom message goes here',
],
],

Laravel custom request not found

I got my custom request RegisterRequest and I'm trying to use it but for some reason I always get this error like i'm not including it:
ReflectionException in RouteSignatureParameters.php line 25:
Class App\Http\Controllers\RegisterRequest does not exist
this is my request:
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
class RegisterRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return false;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'username' => 'required',
'email' => 'required',
'emailconfirm' => 'required',
'password' => 'required',
'passwordconfirm' => 'required',
];
}
public function messages(){
return [
'username.required' => 'Username is required',
],
}
}
and this is how i'm trying to use it:
use App\Http\Requests\RegisterRequest;
and in my method:
public function RegisterPost(RegisterRequest $request){
return response()->json($request->all(),200);
}
I always get 500 internal server error with message that request does not exists.
This command may help:
composer dump-autoload

Categories