In my front end I have a collection of models. Each collection can communicate with the back end and each model can also communicate with the back end.
I am trying to devise the proper url routes for it here is what I am thinking
create [POST] /mycollection
update [PATCH] /mycollection/22
delete [DELETE] /mycollection/22
and for the models
create [POST] /mycollection/22
update [PATCH] /mycollection/22/3
delete [DELETE] /mycollection/22/3
How should I create my routes in Laravel?
I'm looking into route groups but it's still quite a bit of boiler plate it seems.
Route::group(array('prefix' => 'mycollection'), function()
{
Route::get('{id}', function($id){});
Route::post('/', function(){});
Route::patch('{id}', function($id){});
Route::destroy('{id}', function($id){});
Route::get('{id}/{child_id}', function($id, $child_id){});
Route::post('{id}', function($id){});
Route::patch('{id}/{child_id}', function($id, $child_id){});
Route::destroy('{id}/{child_id}', function($id, $child_id){});
});
What you are looking for is RESTful resource routes with Laravel. You can read more here
Route::group(array('prefix' => 'mycollection'), function()
{
Route::resource('/', 'CollectionController#index');
});
Related
location #laravelapi {
rewrite /api/(.*)?$ /api/index.php?$is_args$args last;
}
When we try access to api/routeexample, laravel gets only routeexample part, and throws 404 error. How we can send full url including 'api' part?
I m adding an example of how we define route for API request:
In routes/api.php
Route::group(['prefix' => 'v1'], function () {
Route::post('api_request', [App\Http\Controllers\YourController::class, 'targeted_function_name'])->name('api_request');
});
So I'm just added
include "api.php";
into my routes/web.php as hotfix, but i will search for better solution
I have https://tenancyforlaravel.com/ installed in laravel to make multi-tenant and it works fine for the web routes.
My problem is that when I access my APIs then I get a 404 error in tenant domains.
tenancyforlaravel documentation: https://tenancyforlaravel.com/docs/v3/routes
It says that I must put all my APIs inside api.php file and wrap them in a Route group with this middleware so I put all my APIs inside api.php file and all my APIs as below:
Route::middleware('tenancy')->group(function () {
Route::name('api.')->namespace('Api')->group(function () {
Route::post('/login', 'AuthController#login')->name('login');
...
});
and when I access it using sub.local.test/api/login then I get 404 error.
Tested for tenancyforlaravel.com V3 and it works OK.
Route::middleware([
InitializeTenancyByDomain::class,
PreventAccessFromCentralDomains::class
])->prefix('api')->group(function () {
//
Route::name('api.')->namespace('App\Http\Controllers\Api')->group(function () {
Route::post('/login', 'AuthController#login')->name('login');
...
});
Put all your API routes inside api.php as below
use App\Http\Controllers\AuthController;
Route::group(['prefix' => '/{tenant}',
'middleware' => [InitializeTenancyByPath::class],],
function () {
Route::post('/login', [AuthController::class, 'login'])->name('login');
...
});
As you haven't mentioned your tenant identifier, I am using path as identifier, so using InitializeTenancyByPath middleware. Use whatever identifier middleware you want in place of that.
Access your API routes normally as you used to do, with your identifier. As this example uses path as identifier, the endpoint will look like:
sub.local.test/api/{tenant}/login
I'm trying to populate "position" dropdown based on "department". The Ajax call is triggered on change event of the "department" dropdown.
The problem is that the Ajax call can't reach the correct route:
with url: 'ajax/get-position' - the url is: localhost/public/join/ajax/get-position?dept_id=5
with url: '/ajax/get-position' - the url is: localhost/ajax/get-position?dept_id=5
Both of the URLs are wrong and I have no idea why. Especially this /join/ in the first point is a mystery to me. The correct URL should be localhost/public/ajax/get-position?dept_id=5. I believe there's some kind of a conflict in the routing, however I'm not sure where.
The Ajax call is made on localhost/public/join/editor page.
JS:
...
...
$.ajax({
url: 'ajax/get-position',
data: {
dept_id: value
},
type: 'GET',
dataType : 'json',
success: function(json) {
//
},
error: function(xhr, status, errorThrown) {
//
}
});
...
...
Routes:
Route::get('join/editor',
array(
'uses' => 'DefaultController#showEditorRegistration',
'as' => 'editorRegistration'
)
);
Route::post('join/editor',
array(
'uses' => 'DefaultController#createEditor',
'as' => 'createEditor'
)
);
// ROUTE FOR AJAX CALL
Route::get('ajax/get-position',
array(
'uses' => 'DefaultController#getPositionsByDepartment',
)
);
Any ideas?
EDIT:
The JavaScript is in an external file. If I put the JS directly in blade.php view and use URL::route('routename') as Ajax url value - all works fine. However, simply using url: ajax/get-position - does not. Crazy world.
I'm not completely sure, but based on our conversation about the details of your project I think the issue has to do with the location of your document root. the public directory should never show up in any of your laravel project's urls.
I created a demo project to demonstrate a simple interaction with Laravel and Ajax. It's a vanilla laravel project with slight alterations to the hello view.
Checkout the project, navigate into the public folder, and use the following command to spin up an ad-hoc phpserver:
php -S localhost:8002
You can then go to the url http://localhost:8002 to get to the homepage.
If you inspect the link on the home page and look at the url that is generated with the URL facade for the route tester. The URL doesn't include the public directory:
http://localhost:8003/tester
You can also look at the ajax setup and see that you can use the tester route as well.
$('#getbutton').click( function (){
$.ajax({
url: 'tester'
}).complete(function (a){
alert(a.responseText);
}).error(function (a){
console.log(a);
});
});
Using either the link or the ajax call on button click will hit the tester route in the routes file:
Route::get('tester',[ 'as' => 'tester', 'uses' => function (){
return 'worked';
}]);
The link can hit the route via the route name tester assigned in the routes file, and the ajax request can hit the route from the query string.
The routes in your project look ok and using ajax/get-position as your url in the ajax call shouldn't be an issue.
Give this project a try. Even if the issue isn't a webroot one, hopefully it will help you figure out where your issue is coming from.
Here's my route:
Route::controller('/site-manager-gateway', 'SiteManagerGatewayController');
How can I apply a CSRF filter and Auth filter, I've tried adding them like:
Route::controller('/site-manager-gateway', 'SiteManagerGatewayController', array('before' => 'auth' | 'csrf'));
But no luck.
You can wrap multiple controllers/actions in a group, and apply filter for whole group. I think this is best practice, as you don't have to repeat yourself on each route.
Also, you have to specify filters in string
'filterA|filterB'
not
'filterA' | 'filterB'
So the router looks like:
Route::group(array('before' => 'auth|csrf'), function()
{
Route::controller('/site-manager-gateway', 'SiteManagerGatewayController');
});
Check out http://laravel.com/docs/routing#route-filters and check out "Attaching multiple routes to a filter"
Route::get('user', array('before' => 'auth|old', function()
{
return 'You are authenticated and over 200 years old!';
}));
By looking at your code you separated the auth and csrf with single quotes when they should be placed together so instead of 'auth' | 'csrf' you need 'auth | csrf'.
I have the following code:
Route::get('/', function()
{
return 'non secure page';
});
Route::get('/', array('https' => true, function()
{
return 'secure page';
}));
What I expected to happen is that these two routes would be treated differently. The first is for http://example.com requests and the second for https://example.com. Respectively, these pages should show the text 'non secure page' and 'secure page'. What actually happens is that both show the text 'secure page'. This must mean that both routes are treated the same i.e. it doesn't matter if the request was over https or http - the same route is triggered.
I know I can resolve my issue by using if (Request::secure()){ //routes }; but that then leads me to the question what use are the HTTPS secure routes in laravel? What do they achieve and when should they be used?
I've looked at the docs, but it's not clear to me what is supposed to happen.
The documentation says:
When defining routes, you may use the "https" attribute to indicate that the HTTPS protocol should be used when generating a URL or Redirect to that route.
"https" and ::secure() are only used when generating URLs to routes, they're not used to provide https-only routes. You could write a filter to protect against non-HTTPS routes (example below). Or if you want to prevent any non-HTTPS access to your entire domain then you should reconfigure your server, rather than do this in PHP.
Route::filter('https', function() {
if (!Request::secure()) return Response::error(404);
});
Alternative filter response:
Route::filter('https', function() {
if (!Request::secure()) return Redirect::to_secure(URI::current());
});
References:
http://laravel.com/docs/routing#https-routes
http://laravel.com/docs/routing#filters
The problem is not related to HTTPS.
The documentation says,
Note: Routes are evaluated in the order that they are registered, so register any "catch-all" routes at the bottom of your routes.php file.
It means that your
Route::get('/', array('https' => true, function()
{
return 'secure page';
}));
is over-writing
Route::get('/', function()
{
return 'non secure page';
});
I was actually lead here by Spark from laravel.io and I thought I would clarify the doubt anyhow.
Regards