Laravel Route apiResource (difference between apiResource and resource in route) - api

I'm using apiResource in Route which is using (index, create, show, update, destroy) methods in exampleController. When I would like to use show method the route wont work. what shall I do? I think it is because of {fruits} but I do not how solve it?
Route::apiResource('/fruit/{fruits}/apples', 'exampleController');
My route in browser is:
localhost:8000/api/fruits/testFruitSlug/apples/testAppleSlug
difference between apiResource and resource in route: Route::apiResource() only creates routes for index, store, show, update and destroy while Route::resource() also adds a create and edit route which don't make sense in an API context.

Already peoples added answers, I am just adding the route differences as visually :
Normal Resource controller
Route::resource('users', 'UsersController');
Gives you these named routes:
Verb Path Action Route Name
GET /users index users.index
GET /users/create create users.create
POST /users store users.store
GET /users/{user} show users.show
GET /users/{user}/edit edit users.edit
PUT|PATCH /users/{user} update users.update
DELETE /users/{user} destroy users.destroy
Api Resource controller
Route::apiResource('users', 'UsersController');
Gives you these named routes:
Verb Path Action Route Name
GET /users index users.index
POST /users store users.store
GET /users/{user} show users.show
PUT|PATCH /users/{user} update users.update
DELETE /users/{user} destroy users.destroy

To quickly generate an API resource controller that does not include the create or edit methods, use the --api switch when executing the make:controller command:
php artisan make:controller API/PhotoController --api
Try using the command line to generate your controller. It will save you stress. You can then do this in your route
Route::apiResource('photos', 'PhotoController');

I solved my question in below way:
public function show(Fruits $fruits, Apples $apples){
}
I found that I should give all variables in my function however I did not use all of them.

Related

Matching same route / different HTTP verb to different controller method in Rails

I’ve got a Rails 3 app where instead of the default destruction mapping:
modelname DELETE /modelname/:id modelname#destroy
I would like a dedicated route with a GET ‘fallback’ so that users without Javascript are sent to a confirmation page:
delete_modelname DELETE /modelname/:id/delete modelname#destroy
delete_modelname GET /modelname/:id/delete modelname#confirm_destruction
I can get the above output in rake routes with the following declaration:
resources :modelname, except: [:destroy] do
member {
get 'delete', to: 'confirm_destruction'
delete 'destroy', as: 'delete'
}
end
However, one of the routes does not match, and it seems to be order-dependent, i.e. whichever is defined first then fails to match in testing. I notice that the default ‘overloaded’ routes Rails generates look a bit different in rake routes:
modelnames GET /modelname/:id/delete modelname#index
POST /modelname/:id/delete modelname#create
The route name is not repeated, and a link to create will become a link to index outside a form or a Javascript-enabled request.
It seems I’ve defined two entirely separate routes sharing the same name, rather than overloaded the path as I intended.
What am I missing? Is there any way to get the effect I’m looking for?
Things I’ve tried
Since it appeared to be the route name which was clashing, I tried this:
member {
get 'delete', to: 'confirm_destruction'
delete 'destroy', path: 'delete'
}
Changing as: to path: so that the route name would not be affected, but the paths would match. This works! The following routes are generated:
delete_modelname GET /modelname/:id/delete modelname#confirm_destruction
modelname DELETE /modelname/:id/delete modelname#destroy
This gives the effect I’m after, but unfortunately the modelname DELETE route masks the default modelname PUT route for updates.
Okay, so there is a way to do this, but it’s not quite as elegant as I’d hoped. I’m very open to a better answer if anyone has one.
resources :modelname, except: [:destroy] do
member {
get 'delete', to: 'confirm_destruction'
delete 'destroy', as: 'destroy', path: 'delete'
}
end
It works because these two new routes have unique names for using in views – delete_modelname_path and destroy_modelname_path – but if Javascript is disabled, the destroy_modelname path is still /modelnames/:id/delete, which comes in as a GET request and Rails matches it to the delete_modelname route (i.e. the confirmation page).

laravel 4 pattern filter using a wildcard

I started using Laravel 3 last week, and then found the new 4 release and I'm trying to convert now.
I have a dozen+ routes that I want to deliver to a specific controller method. i.e., "/api/v1/owners/3/dogs/1 or /api/v1/owners/3" to run "myresourcecontroller#processRequest"
In Laravel 3 I was able to use this: (note * wildcard)
Route::any('api/v1/owners*', 'owners#processRequest'); // Process tags resource endpoints
I found this example from the documentation but it gives me an error. I get a NotFoundHttpException.
//[Pattern Based Filters](http://laravel.com/docs/routing#route-filters)
Route::filter('admin', function()
{
//
});
Route::when('admin/*', 'admin');
Not sure what I'm doing wrong? Is there another way to do this?
I don't want to use the Laravel 4 restful controllers, cause they don't seem to conform to complete restful design. i.e., no verbs in the url.
I have all of my processing written, I just need to be able to route to it.
I need to be able to create new records by POST /api/v1/owners or /api/v1/owners/3/dogs
I cannot use /api/v1/owners/create.
I'm trying to avoid having to write a route for every endpoint, i.e.,
Route::any('api/v1/owners/{owner_id}', 'owners#processRequest');
Route::any('api/v1/owners/{owner_id}/dogs/{dog_id}', 'owners#processRequest');
Thank you for any help
You should make use of resourceful controllers as they're a great asset when building an API. The endpoints you described can be achieved using resource controllers and nested resource controllers.
Route::resource('owners', 'OwnersController');
Route::resource('owners.dogs', 'OwnersDogsController');
Would allow you to create an owner with POST localhost/owners and create a dog on an owner with POST localhost/owners/3/dogs.
You can then wrap these routes in a route group to get the api/v1 prefix.
Route::group(['prefix' => 'api/v1'], function()
{
Route::resource('owners', 'OwnersController');
Route::resource('owners.dogs', 'OwnersDogsController');
});
Haven't used Laravel myself, but try any('api/v1/owners/*', (note slash before asterisk) as in the example.

In a RESTful application, how do we differentiate between an "action" and an HTTP verb (GET, POST, PUT, DELETE)?

In a RESTful application, how do we differentiate between an "action" and an HTTP verb (GET, POST, PUT, DELETE)?
For example, as I understand it, a GET request to the resource /products should return a list of all products. A POST request to /products should create a new product. How, then, does the user request the original form which is used to create the product? My initial response would have been a GET request to the same URI, but as mentioned above, that should return a list of all products - not a blank form for creating a product.
In most frameworks I've researched, this problem is solved by making the "action" part of the URI. For example, a POST request to /products/create would create a new product, whereas a GET request to /products/create would give the blank form for creating a product. To get a list of all products would be a GET request to either /products or /products/get, /products/read, etc. depending on the framework in question. This approach resolves the ambiguity above, but it conflicts with what I've read about traditional REST design.
IMHO, the best option is to make the request method a part of controller's action.
Lets say you are accessing http://who.cares/product/42 or http://who.cares/product/42/specification . This query to webserver would translate as Product controller. The actions name should be created by combining request method and command:
DELETE "http://who.cares/product/42"
controller: "Product",
action: "deleteProduct()"
GET "http://who.cares/product/42/details"
controller: "Product",
action: "getDetails()"
POST "http://who.cares/product/42/review"
controller: "Product",
action: "postReview()"
GET "http://who.cares/products/
controller: "Products",
action: "getProducts()"
POST "http://who.cares/products/
controller: "Products",
action: "postProducts()"
here is example like it Rails does
REST request path | action name | Description
---------------------|-------------------|-------------
GET /profile/new | new | Render a form for creating the profile
POST /profile | create | Create a the profile from the received data
GET /profile | show | Render a the profile
GET /profile/edit | edit | Render a form for editing the profile
PUT /profile | update | Update the profile based on the received data
DELETE /profile | destroy | Destroy the profile
I don't see any conflict , Idea is that
urls are human readable and you can introduce new URIs to show different representations of the same resource. (like profile/1/edit and profile/1)
/profile/new - address of profile that is empty (like profile/1, profile/2 .. etc in show method)
But if you want you can suggest that profile/1/edit is some kind of different - nested resource of profile/1/ resource, but I like to thing that it's just other representation of profile/1/ resource =)
Also is good idea to use plural and singular URI when you working with many resources or with one, example
/profile/1.html - gives you 1 resource
/profiles.html - gives you list of profiles

Yii: CMenu items for different module

I'd like to make a menu in Layout which the items are linked to other different module.
e.g:
Item "Product" linked to an action in Product Module, item "Service" linked to an action in Service Module.
It won't work when I set the 'url'=>('product/<controllerID>/<actionID>') and 'url'=>('service/<controllerID>/<actionID>') because once we're in Product module and click the menu "Service", the URL become
index.php?r=product/service/<controllerID>/<actionID>
instead of
index.php?r=service/<controllerID>/<actionID>
and it will be 404 error. (for sure, because the Service Module isn't inside Product Module but the URL makes it looks like that).
Any solution for this?
Check the createUrl() documentation :
the URL route. This should be in the format of 'ControllerID/ActionID'. If the ControllerID is not present, the current controller ID will be prefixed to the route. If the route is empty, it is assumed to be the current action. If the controller belongs to a module, the module ID will be prefixed to the route. (If you do not want the module ID prefix, the route should start with a slash '/'.)
That last line tells us everything. Best thing to do for you is start all the routes with a / :
'url'=>array('/<moduleID>/<controllerID>/<actionID>')
Check this
'url'=>$this->createUrl('/<moduleId>/<controllerID>/<actionID>')

Rails 3 routes for page

I have a page_controller with a few actions (dashboard, rules, contact). Each has a corresponding view. I don't know how to route it in Rails 3.
match 'page/:action' => 'page#:action'
The above doesn't work - what I would like is named routes like: page_path(:dashboard) or page_dashboard_path.
Any ideas?
Jacob
You will have to write
get 'page/dashboard'
get 'page/rules'
get 'page/contact'
That will generate the correct named routes.
Note: you can always type rake routes to see which named routes are created.
For more info: see documentation.