Im using Dingo to build out an API and up until this point I've had no problems with the routes, until trying to add show into the controller, I'm just getting a 404.
Details here:
{
"error": {
"message": "404 Not Found",
"status_code": 404,
"debug": {
"line": 179,
"file": "/var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php",
"class": "Symfony\\Component\\HttpKernel\\Exception\\NotFoundHttpException",
"trace": [
"#0 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(546): Illuminate\\Routing\\RouteCollection->match(Object(Dingo\\Api\\Http\\Request))",
"#1 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(525): Illuminate\\Routing\\Router->findRoute(Object(Dingo\\Api\\Http\\Request))",
"#2 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Routing/Router.php(511): Illuminate\\Routing\\Router->dispatchToRoute(Object(Dingo\\Api\\Http\\Request))",
"#3 /var/www/html/myapi/api/vendor/dingo/api/src/Routing/Adapter/Laravel.php(81): Illuminate\\Routing\\Router->dispatch(Object(Dingo\\Api\\Http\\Request))",
"#4 /var/www/html/myapi/api/vendor/dingo/api/src/Routing/Router.php(513): Dingo\\Api\\Routing\\Adapter\\Laravel->dispatch(Object(Dingo\\Api\\Http\\Request), 'v1')",
"#5 /var/www/html/myapi/api/vendor/dingo/api/src/Http/Middleware/Request.php(126): Dingo\\Api\\Routing\\Router->dispatch(Object(Dingo\\Api\\Http\\Request))",
"#6 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(114): Dingo\\Api\\Http\\Middleware\\Request->Dingo\\Api\\Http\\Middleware\\{closure}(Object(Dingo\\Api\\Http\\Request))",
"#7 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/CheckForMaintenanceMode.php(46): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))",
"#8 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Illuminate\\Foundation\\Http\\Middleware\\CheckForMaintenanceMode->handle(Object(Dingo\\Api\\Http\\Request), Object(Closure))",
"#9 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Dingo\\Api\\Http\\Request))",
"#10 /var/www/html/myapi/api/vendor/dingo/api/src/Http/Middleware/Request.php(127): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))",
"#11 /var/www/html/myapi/api/vendor/dingo/api/src/Http/Middleware/Request.php(103): Dingo\\Api\\Http\\Middleware\\Request->sendRequestThroughRouter(Object(Dingo\\Api\\Http\\Request))",
"#12 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): Dingo\\Api\\Http\\Middleware\\Request->handle(Object(Illuminate\\Http\\Request), Object(Closure))",
"#13 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))",
"#14 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(102): Illuminate\\Routing\\Pipeline->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))",
"#15 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(151): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))",
"#16 /var/www/html/myapi/api/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(116): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))",
"#17 /var/www/html/myapi/api/public/index.php(54): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))",
"#18 {main}"
]
}
}
}
Here is a portion of my route file
api.php
$api->group(['middleware' => 'jwt.auth'], function(Router $api) {
$api->get('protected', function() {
return response()->json([
'message' => 'Access to protected resources granted! You are seeing this text as you provided the token correctly.'
]);
});
$api->get('refresh', [
'middleware' => 'jwt.refresh',
function() {
return response()->json([
'message' => 'By accessing this endpoint, you can refresh your access token at each request. Check out this response headers!'
]);
}
]);
$api->get('leads', 'App\\Api\\V1\\Controllers\\LeadController#index');
$api->get('leads/{$id}', 'App\\Api\\V1\\Controllers\\LeadController#show');
$api->post('leads/store', 'App\\Api\\V1\\Controllers\\LeadController#store');
$api->put('leads/update/{$id}', 'App\\Api\\V1\\Controllers\\LeadController#update');
$api->post('leads/update/{$id}', 'App\\Api\\V1\\Controllers\\LeadController#update');
});
And the show function in the controller:
LeadController.php
public function show(Lead $leads, $id)
{
dd($id);
$lead = Lead::with('user', 'source', 'industry', 'status')->find($id);
//if(!$lead)
// return $this->response->error('invalid_data', 400);
//return fractal($lead, new LeadTransformer())->respond();
}
I've attempted to do a Die'n'Dump to ensure the ID is coming through, but it doesn't appear to be getting that far. Both the #index and #store work no problems and if I change LeadController#index to LeadController#show, the route works, and I of course get the error regarding the second parameter.
Really at a loss as to why this won't work, so help here would be really appreciated.
Wow, from looking too hard, and not enough sleep, the reason it didn't work was because the variable was set as {$id} not {id} as it should have been.
When using these variables, don't use the $ sign!
Related
I've been searching a solution in Google but couldn't find anything similar tho this.
I'm basically trying to create a custom response upon the error methodNotAllowed in the framework Laravel 8.x
So I have this route:
Route::get('/test', function(Request $request){
return response([
'status' => 200,
'data' => 'Test'
]);
});
On requesting GET:/api/test I'm getting the expected response:
{
"status": 200,
"data": "Test"
}
But when requesting POST:/api/test or any other method it obviously throws an error 405 Method Not Allowed because I haven't setup any router for this.
Is there a "cleen way" to change the error response from 405 Method Not Allowed to
{
"status": 405,
"data": "Method Not Allowed"
}
By a "cleen way" I mean not creating aditional 100 routes just for catching the right method.
The Solution was adding the custom Response to App\Exceptions\Handler by doing this:
Add this to the top:
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
And add the custom response to the method register:
public function register()
{
$this->renderable(function (MethodNotAllowedHttpException $e, $request) {
return response()->json([
'status' => 405,
'message' => 'Method Not Allowed'
], 405);
});
}
Source: https://laravel.com/docs/8.x/errors
I'm trying to get some data from a Laravel API endpoint but I'm getting some very unusual redirect issues and disallowed methods. I will start by showing my javascript code first, then laravel code second.
First, I ran the following javascript code from the developer console of various websites with various top level domains to ensure I can authenticate without any CORS issues:
fetch("https://api.example.com/login",{
method:"post",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({"email":"test#test.com","password":"test","remember_me":true})
})
.then(r=>r.json())
.then(r=>console.log(r));
// I get a perfect response like this:
{ data: { message: "Yay! Success!", token: "86|S5isCezrsYb1aToAsI3xZb9Ot9Tu7WU8XeOK1q8C" } }
I then take the token and do another get request from my developer console to the /auth/user end point to get my account details like this
fetch("https://api.example.com/auth/user",{
method:"get",
header:{
Authorization:"Bearer 86|S5isCezrsYb1aToAsI3xZb9Ot9Tu7WU8XeOK1q8C",
Accept: "application/json"
},
})
.then(r=>r.json())
.then(r=>console.log(r));
But something completely weird happens. The https://api.example.com/auth/user gives my developer console a 302 response. Then my developer console automatically (without any intervention from me) makes a GET request to https://api.example.com/login. The https://api.example.com/login then gives a 405 response with this message:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException: The GET method is not supported for this route. Supported methods: POST. in file /var/www/api/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php on line 117
#0 /var/www/api/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php(103): Illuminate\Routing\AbstractRouteCollection->methodNotAllowed(Array, 'GET')
#1 /var/www/api/vendor/laravel/framework/src/Illuminate/Routing/AbstractRouteCollection.php(40): Illuminate\Routing\AbstractRouteCollection->getRouteForMethods(Object(Illuminate\Http\Request), Array)
#2 /var/www/api/vendor/laravel/framework/src/Illuminate/Routing/RouteCollection.php(162):
...etc...
This is my Laravel code:
~/routes/api.php
Route::post('login', ['as' => 'login', 'uses' => 'Api\UserController#login']); //->middleware(['throttle:6,1']);
Route::middleware('auth:sanctum')->get('/auth/user', function (Request $request) {
return $request->user();
});
~/app/Http/Controller/Api/UserController.php
public function login(LoginRequest $request)
{
$user = User::where('email', $request->email)->first();
if (!$user || !Hash::check($request->password, $user->password)) {
throw ValidationException::withMessages([
'message' => ['The provided credentials are incorrect.'],
]);
exit;
} else if (!$user->active) {
throw ValidationException::withMessages([
'message' => ['Your account approval is pending.'],
]);
exit;
}
return response()->json([
'data' => [
"message" => __("Yay! Success!"),
"token" => $user->createToken('authentication-token')->plainTextToken,
],
]);
}
So my question is, why can't the /auth/user endpoint return information about the user I'm logged in with?
EDIT
I tried php artisan route:clear which had no effect.
I tried changing the route from /auth/user to authuser in both the route/api.php and my fetch() call, and suddenly I have a CORS error. Is the auth/ path a reserved word of some kind?
Oh...i guess this config/cors.php also matters:
'paths' => [
'api/*',
'auth/user',
'login',
'logout',
'sanctum/csrf-cookie',
],
UPDATE
I created a few more routes like this:
~/routes/api.php
Route::middleware(['auth:sanctum'])->group(function () {
Route::resource('blah1', Api\Blah1::class)->only(['index', 'store', 'show', 'update', 'destroy']);
Route::resource('blah2', Api\Blah1::class)->only(['index', 'store', 'show', 'update', 'destroy']);
// .. etc...
Route::get('/auth/user', function (Request $request) {
return $request->user();
});
});
~/config/cors.php
'paths' => [
'api/*',
'auth/user',
'blah*',
'login',
'logout',
'sanctum/csrf-cookie',
],
I noticed that POSTMAN has ZERO problems getting information from auth/user and blah1, blah2, etc...
However, it is just the browser that will always give a 302 and cause a redirect when pinging auth/user, blah1, blah2, etc.... FireFox shows me these responses:
If I remove the middleware('auth:sanctum'), then I no longer get the 405 and 302 issue. However, $request->user() becomes null without the middleware('auth:sanctum'). I need a way to get the user information from Authorization: Bearer <token>
I am using Laravel as an API base, but I am struggling to show meaningful validator messages in my JSON response. I am using Laravel 8.
This is the response when my validator fails:
{
"message": "The given data was invalid.",
"errors": {
"image": [
"validation.mimes"
]
}
}
But instead of the validation.mimes i want an actual meaningful message, like The :attribute must be a file of type: :values..
I've tried overriding the exception in Exceptions\Handler.php but I still can't seem to access actual error messages?
protected function invalidJson($request, ValidationException $exception) {
return response()->json([
'success' => false,
'message' => $exception->getMessage(),
'errors' => $exception->errors()
], $exception->status);
}
Any help is appreciated.
Thanks
I'm working on a project and I came across a problem, explain:
I'm doing a POST to a webserver using the Guzzle http, follows the :
public function sendPost($direction, array $data, array
$options = ['http_errors'=>false])
{
$url = $this->interpolate( self::BASE_PATH."/{direction}",
[
'direction' => $direction
]);
$options = array_merge($options,['body'=>json_encode($data)]);
return $this->client->post($url, $options);
}
The method is working correctly and I am returning the following:
{
"id": "jdhj9h830027hd73hs9q9js9",
"direction": "left",
"status": "Success",
"code": {
"id":"1",
"desc": "ok",
"error": false,
"msg":null
}
}
What I can not do is the following:
A method that returns only the given "jdhj9h830027hd73hs9q9js9", that is, the "id" parameter.
can anybody help me?
PS. By using the "sendPost ()" method I can access the data I need separately, however I can not do this through another method, such as a "getId ()".
Thank you in advance for your help.
Just try:
return ($this->client->post($url, $options))->id;
$api->version('v1', ['middleware' => 'api.auth'], function($api){
$api->get('auth/user', 'App\Http\Controllers\Api\ApiUserController#getAuthUser');
$api->get('auth/getInfo', 'App\Http\Controllers\Api\ApiUserAppointmentController#getInfo');
$api->get('auth/show/{id}', 'App\Http\Controllers\Api\ApiUserAppointmentController#show');
});
public function show($id)
{
echo $id;die;
}
Error
"message": "404 Not Found",
"status_code": 404,
"debug": {
"line": 161,
"file": "C:\\xampp\\htdocs\\G2Project\\medcrip\\vendor\\laravel\\framework\\src\\Illuminate\\Routing\\RouteCollection.php",
I stuck when adding parameter in get method don't know why this is say not found. if i remove {id} from route it works fine but when i do add {id} that says to me not found.
Please advice thanks in advance
To make the auth/show/{id} route work, you should use this URI:
/api/auth/show/53
instead of this:
/api/auth/show/?id=53