I have a controller (API\Fields) with a method named store, the route to that method is set up like this:
POST /api/templates/{template}/fields -> API\Fields#store
Everything worked properly until I created a very simple form request validation class with the following rules (This is the only thing I changed besides the return value for the authorize method):
return [
'name' => ['required', 'alpha_num'],
'coordinates' => ['required', 'json'],
'type' => ['required', BaseField::RULE],
'page' => ['required', 'numeric'],
'readonly' => ['sometimes', 'boolean'],
'required' => ['sometimes', 'boolean']
];
After I created the class, I simply changed the request class from Request, to CreateFieldsRequest and it messed pretty much the whole routing for that route up. Instead of calling store, Laravel seems to be calling index. When I restore CreateFieldsRequest back to just the Request class, it behaves as it should again.
I haven't been able to find any information on this topic, and I've verified over and over that I don't have some sort of incorrect routing or redirections on any of the related classes.
Any help or guidance with this would be greatly appreciated, thank you!
When I run the request through the Chrome developer console as a POST request, Laravel kicks it back as a "GET" request, not sure why.
A FormRequest that fails validation issues a redirect. It's the default behavior.
If you issue an AJAX request, or request a JSON response with an Accept header, it'll respond with a JSON list of validation errors and a 422 HTTP code instead.
After running a very simple test I realized that this seems to be an issue with Postman. If you are experiencing this issue stick to adding a _method=POST parameter on your POST body, or simply use XHR or a different API testing tool.
Edit: After further testing I realized the issue had not been fixed. When I run the request through the Chrome developer console as a POST request, Laravel kicks it back as a "GET" request, not sure why.
Related
I have a simple route in Laravel 8 to return some request data. But when I send the request in Postman with POST selected, I get an error of "The GET method is not supported for this route." Keep in mind, I have POST selected in Postman, not GET.
Here is the route:
Route::post('post-route', 'UserController#postFunction');
Here is is the function being called in UserController:
public function postFunction(Request $request) {
return [
'id1' => $request->id1,
'id2' => $request->id2,
];
}
In Postman I am passing the data as json:
{
'id1': 1234,
'id2': 4321
}
I am simply trying to make sure I am passing the correct data in the request but I am getting this error. Why is it trying to hit a GET request?
You can't test your POST, PUT or DELETE routes with Postman because Laravel uses the CSRF middleware protection.
If you really want to use Postman, you need to comment it to disable this middleware temporarly in app/Http/Kernel.php:
protected $middlewareGroups = [
'web' => [
(...)
//\App\Http\Middleware\VerifyCsrfToken::class,
],
(...)
];
But don't forget to enable it again once you want to deploy your project in production!
If you don't want to disable temporarly the CSRF middleware, you can follow the steps mentioned here https://gist.github.com/ethanstenis/3cc78c1d097680ac7ef0, but it's a little longer.
I'm writing a test suite for a Laravel application. I'm making assertions against an endpoint that uses Laravel request validation to validate the user input. It automatically redirects the user back to the previous page.
$request->validate([
'name' => 'required',
'email' => 'required|email',
'timeslot' => 'required'
]);
Currently, I am asserting that I if I post invalid data to this endpoint, I receive a redirect status code back. This is fine, but I would also like to assert, more specifically, that the user is redirected back to the previous page.
I feel that to test this condition properly, I need to somehow 'push' a URL into my test suite's/application's browser history, then assert that the redirect URL is that same URL.
How can I do this?
In a Laravel test, to simulate a previus Url, you use the $this->from($url) method provided by the TestCase class.
An example of it's usage:
$this->from('/home')
->get('/profile')
->assertSee('User profile');
You may even use it with the route() or url() helper:
$this->from(route('home'))
->get('/profile')
->assertSee('User profile');
I have a problem with Request validation. Everything works but one pattern. And its if I dont want the field to be required but once it is filled I want it to match a regex.
But it throws regex error when I leave the field empty.
Any tips on how I should handle it?
BTW: I made a custom Request class where I take care of the validation so if the solution could be also in the Request and not directly in Controller that would be great.
return [
'dic' => 'max:12|regex:/^[a-zA-Z]{2}[0-9]{8}[0-9]*$/',
];
return [
'dic' => 'nullable|max:12|regex:/^[a-zA-Z]{2}[0-9]{8}[0-9]*$/',
];
nullable won't check the other rules when the field is empty.
I did move from Lumen to Laravel and now converting my project over. Everything is working except the validation. For some reason, if I try to validate, it just redirects to the welcome.blade.php view. What could cause this?
I am using only the API part of routes, not the view. I am not dealing with views. I am using the stateless part of Laravel.
According to documentation, I can validate like this:
$this->validate($request, [
'title' => 'required|unique|max:255',
'body' => 'required',
]);
If validation passes, your code will keep executing normally. However,
if validation fails, an
Illuminate\Contracts\Validation\ValidationException will be thrown.
I also tried to force it to return JSON response without success:
$validator = $this->validate($request, ['email' => 'required']);
if ($validator->fails()) {
$messages = $validator->errors();
return new JsonResponse(['status' => 'error', 'messages' => $messages]);
}
However, mine doesn't fail but just returns the welcome view with response code of 200. I have tried pretty much all the possible validation methods from the documentation and from google. Non of them are working.
I even tried with clean laravel install, declared one test route and test controller which had the validation and the result is the exact same.
Is the validation even meant to be compatible with the restful/stateless part of Laravel?
Any suggestion is much appreciated.
1- first the unique key needs a table, per example if you want the email to be unique in the users table you do as follows:
'email' => 'required|unique:users',
I think may be you have placed your route in route/web.php file. Replace that code from web.php to api.php
Try to place your API endpoints in route/api.php file.
And remember you need to add prefix /api in your route.
Ex : test.com/api/users.
I am testing POSTing data to an API endpoint we've created using Laravel 5.2, but none of the parameters seem to be reaching the application in the test. The endpoint expects json and responds with json and uses a FormRequestValidator which has required rules for active and make parameters. The test fails with status code 422 and the examining the response body it states the active and make parameters are required even though they are being passed in the call so therefore for some reason when the request reaches the the Form Request Validator, the input is not there.
However, when I invoke the endpoint with json body including make and active from Postman or the UI app we've built it works fine, it is only failing in the PHPUnit tests therefore it must be something with PHPUnit or the test setup being incorrect. Here is the test:
public function testItStoresCars()
{
// Arrange
$user = User::first();
//Act
$this->json(Request::METHOD_POST, '/v1/cars', [
'active' => true,
'make' => 'Audi'
],
['Authorization' => 'Bearer '.\JWT::fromUser($user)]));
// Assert
$this->assertResponseOk();
}
I know the Authorisation header is set correctly from other tests passing.
I've tried disabling middleware, using the $this->post helper method and manually setting the headers as well as using the $this->call method with setting the Headers and encoding the data using json_encode but I always get the same 422 response. I'm wondering has anyone encountered this issue or can see an error?
Controller Code
public function store(CreateCarRequest $request)
{
$car = $this->carRepo->save($request->all());
return response()->json(car);
}
FormRequest
class CreateCarRequest extends Request
{
public function rules()
{
return [
'active' => 'required|boolean',
'make' => 'required',
];
}
}
422 is the error response for validation errors.. which means either your data is not posted or it doesn't pass server validation, try
$this->json(Request::METHOD_POST, '/v1/cars', [
'active' => true,
'make' => 'Audi'
],
['Authorization' => 'Bearer '.\JWT::fromUser($user)]))->dump();
dump() should show you the errors