I'm new in Laravel 4 development, can't find enough information about resource method in Route class
Route::resource();
How to use it?
It's a great way to setup API's. It implements RESTful in a clever way. The recourse controller route can catch a request and maps it to a specific method in the controller based on the RESTful state.
routes.php
/*
|--------------------------------------------------------------------------
| Application Routes
|--------------------------------------------------------------------------
|
| Here is where you can register all of the routes for an application.
| It's a breeze. Simply tell Laravel the URIs it should respond to
| and give it the Closure to execute when that URI is requested.
|
*/
// Route group for API versioning
Route::group(array('prefix' => 'api/v1'), function() {
Route::resource('posts', 'PostController');
});
For example:
POST = store() (Create a new entry)
DELETE = destroy($id) (Delete an entry)
GET = index() (Get all entries)
GET = show($id) (Get one entry)
PUT = update($id) (Update an entry)
A practical example:
How do I create a RESTful API in Laravel to use in my BackboneJS app
Related
I have a quick question I know it wouldn't take so much time to fix but somehow I don't seem to easily find the solution.
I am building a basic api for a mobile application. I placed by api routes in api.php
<?php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
/*
|--------------------------------------------------------------------------
| API Routes
|--------------------------------------------------------------------------
|
| Here is where you can register API routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| is assigned the "api" middleware group. Enjoy building your API!
|
*/
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
Route::post('/v1/meeting/record', 'App\Http\Controllers\Attendance#record');
The problem is anytime I send a request to this route it responds with page status 419 (Page Expired).
This is my record method in the Attendance Controller
public function record(Request $request)
{
return response()->json([
"message" => "student record created"
], 201);
}
I added the api/* to the excludes in verifycsrftoken.php but it didn't change anything.
Am I doing anything wrong?
php artisan route:cache
This has fixed it for me in the past.
Here is a discussion on all of the ways to clear cache:
https://dev.to/kenfai/laravel-artisan-cache-commands-explained-41e1
import your controller at the top of the controller class
App\Http\Controllers\Attendance;
then define your route as such
Route::post('/v1/meeting/record', [Attendance::class,'record']);
try this and let me know. thanks
I have been using RESTful controllers in my Laravel project. By including:
Route::controller('things', 'ThingController')
in my routes.php, I can define functions in the ThingController like:
public function getDisplay($id) {
$thing = Thing::find($id)
...
}
so that GETting the URL "...things/display/1" would automatically be directed to the controller function. This seems pretty handy and has been working great for me so far.
I noticed many of my controller functions start with getting a model by id from the url, and I thought it would be nice to be able to use route model binding to do this for me instead. So I updated my routes.php to
Route::model('thing', 'Thing');
Route::controller('things', 'ThingController')
and changed the ThingController functions to
public function getDisplay($thing) {
...
}
I assumed this would magically work the way I wanted it to (like everything else I've tried so far in Laravel has) but unfortunately I get "Trying to get property of non-object" when I attempt to use $thing in the function. Is this something that should be able to work and I have just done it wrong, or can route model binding only work with routes explicitly named in routes.php?
If you don't mind with URI path, method name and just work only show, edit and update method, you can use Resource Controller to generate URI string which can define model binding.
In routes.php change to
Route::model('things', 'Thing');
Route::resource('things', 'ThingController');
You can use php artisan routes command to see all URIs
$ artisan routes | grep ThingController
GET|HEAD things | things.index | ThingController#index
GET|HEAD things/create | things.create | ThingController#create
POST things | things.store | ThingController#store
GET|HEAD things/{things} | things.show | ThingController#show
GET|HEAD things/{things}/edit | things.edit | ThingController#edit
PUT things/{things} | things.update | ThingController#update
PATCH things/{things} | | ThingController#update
After that you can threat parameter as Thing object without explicitly name route.
/**
* Display the specified thing.
*
* #param Thing $thing
* #return mixed
*/
public function show(Thing $thing)
{
return $thing->toJson();
}
If you want to access ThingController#show, pass your model ID and Laravel will retrieve it automatically.
http://example.com/things/1
{"id":1,"type":"Yo!"}
You can use Route:resource and still provide other methods. Place the route you need just before that particular Route::resource line.
Eg:
Route::model('things', 'Thing');
Route::get('things/{things}/owner', 'ThingController#getOwner');
Route::resource('things', 'ThingController');
Then create the corresponding method in your controller.
public function getOwner($things) {
return Response::json($things->owner()->get());
}
Here is the official documentation from the Laravel 4.2 docs:
Source: http://laravel.com/docs/controllers#resource-controllers
Adding Additional Routes To Resource Controllers
If it becomes necessary for you to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to Route::resource:
Route::get('photos/popular');
Route::resource('photos', 'PhotoController');
This is my scenario:
We need to use some Laravel API methods in the same web app where they are stored. (I'm using Laravel 5.5)
I have the api routes used by third parts applications with Bearer Token and the worked like a charm.
So, I've created other routes group that doesn't use "api:auth" middleware but the "auth" one (with "web" middleware addition).
RouteService provider initialization (method invoked in "map" one):
protected function mapWebApiRoutes() {
Route::prefix('web_api')
->middleware('web')
->as('web_api.')
->namespace($this->namespace."\\API")
->group(base_path('routes/web_api.php'));
}
Routes declaration:
Route::group(['prefix' => 'v1', 'middleware' => ["auth"]], function () {
// routes....
});
So, if i run "php artisan route:list", it outputs routes like:
GET|HEAD | web_api/v1/controller | web_api. | ...\API\Controller#index | web,auth
POST | web_api/v1/controller/lists | web_api. | ...\API\Controller#lists | web,auth
I've added routes to VerifyCsrfToken except array:
protected $except = [
"web_api/*"
];
The routes with GET method works as well as they can when the user is logged on our platform (through auth middleware) but the POST routes returns an unauthorized error with this body:
{message: "Unauthenticated."}
Question:
Considering that I have excluded those routes from CSRF verification, somebody could explain to me what that error is caused by?
To create a Role/permission bases laravel app I'm using Zizaco/entrust package.
Now I want to use an approach that no need to assign defined perms to routes as different middlewares in web.php and that is:
First fetches all defined routes (via Route::getRoutes()->getRoutes() ) and store each of them in permissions table.
We can get all routes by this code:
$routes = collect(Route::getRoutes()->getRoutes())->reduce(function ($carry = [], $route) {
$carry[] = $route->uri();
return $carry;
});
On the other hand we can define roles that have those permissions and attach those to user in normal way.
Now when a user want to access a page , first we get route path name and then by can method defined in entrust we check that user can access to that route or not. this can done via a simple middleware named checkAccess for example that is added to all routes as a route group. like this:
class checkAccess
{
public function handle($request, Closure $next)
{
if (Auth::check()) {
$currentName = Route::getCurrentRoute()->getPath();
if (Auth::user()->can($currentName)) {
return $next($request);
}else{
return response()->view('errors.403', ['prevPage'=> URL::previous()]);
}*/
return $next($request);
}
return Redirect::to('/admin/login');
}
}
Route::middleware(['checkAccess'])->group(function () {
//Other routes
});
But a problem is that some resource routes have same route path but different method access. like:
+-----------+-----------------+---------+----------------+
| METHOD | URL | Action | Route Name |
+-----------+-----------------+---------+----------------+
| GET | /photos/{photo} | show | photos.show |
| PUT/PATCH | /photos/{photo} | update | photos.update |
| DELETE | /photos/{photo} | destroy | photos.destroy |
+-----------+-----------------+---------+----------------+
And this is cause duplicate permission name Although they are really different in action.
I want to know are there any relative way to create dynamically permission. or what can I do that to solve this problem in this case?
I am not sure if that is the thing that you need, but maybe it will help you. I have modular application structure and for each module one route.php file. In that file my routes depend on permission:
Route::get('/edit/{param?}', [
'as' => 'get.users.edit',
'uses' => 'UsersController#getEdit',
'middleware' => ['permission:admin']
]);
I have been using RESTful controllers in my Laravel project. By including:
Route::controller('things', 'ThingController')
in my routes.php, I can define functions in the ThingController like:
public function getDisplay($id) {
$thing = Thing::find($id)
...
}
so that GETting the URL "...things/display/1" would automatically be directed to the controller function. This seems pretty handy and has been working great for me so far.
I noticed many of my controller functions start with getting a model by id from the url, and I thought it would be nice to be able to use route model binding to do this for me instead. So I updated my routes.php to
Route::model('thing', 'Thing');
Route::controller('things', 'ThingController')
and changed the ThingController functions to
public function getDisplay($thing) {
...
}
I assumed this would magically work the way I wanted it to (like everything else I've tried so far in Laravel has) but unfortunately I get "Trying to get property of non-object" when I attempt to use $thing in the function. Is this something that should be able to work and I have just done it wrong, or can route model binding only work with routes explicitly named in routes.php?
If you don't mind with URI path, method name and just work only show, edit and update method, you can use Resource Controller to generate URI string which can define model binding.
In routes.php change to
Route::model('things', 'Thing');
Route::resource('things', 'ThingController');
You can use php artisan routes command to see all URIs
$ artisan routes | grep ThingController
GET|HEAD things | things.index | ThingController#index
GET|HEAD things/create | things.create | ThingController#create
POST things | things.store | ThingController#store
GET|HEAD things/{things} | things.show | ThingController#show
GET|HEAD things/{things}/edit | things.edit | ThingController#edit
PUT things/{things} | things.update | ThingController#update
PATCH things/{things} | | ThingController#update
After that you can threat parameter as Thing object without explicitly name route.
/**
* Display the specified thing.
*
* #param Thing $thing
* #return mixed
*/
public function show(Thing $thing)
{
return $thing->toJson();
}
If you want to access ThingController#show, pass your model ID and Laravel will retrieve it automatically.
http://example.com/things/1
{"id":1,"type":"Yo!"}
You can use Route:resource and still provide other methods. Place the route you need just before that particular Route::resource line.
Eg:
Route::model('things', 'Thing');
Route::get('things/{things}/owner', 'ThingController#getOwner');
Route::resource('things', 'ThingController');
Then create the corresponding method in your controller.
public function getOwner($things) {
return Response::json($things->owner()->get());
}
Here is the official documentation from the Laravel 4.2 docs:
Source: http://laravel.com/docs/controllers#resource-controllers
Adding Additional Routes To Resource Controllers
If it becomes necessary for you to add additional routes to a resource controller beyond the default resource routes, you should define those routes before your call to Route::resource:
Route::get('photos/popular');
Route::resource('photos', 'PhotoController');