@El_Matella I’m not a fan of API-driven, single-page web applications as they’re always janky, but if you’re going to go down this route and not use any of Laravel’s views etc then use Lumen: it’s made to be blazing-fast for API-like applications.
Angular - Laravel API - How to organize URLs
Hello!
I would like to train me to make an e-commerce website using Laravel for Back-end and Angular JS for Front-end.
For the moment, my goal is to build a Laravel API communicating with an Angular JS front-end (I am not going to use Laravel views, I want the two technologies completely separate.)
But I don't know really how to organize URLs.
For example, I want my products URLs to follow this rule: my-ecommerce.com/category/product-slug .
But should my Laravel API follow the same rules as the front-end? In other words, should this front-end URL communication with api.mybackend.com/category/product-slug or api.mybackend.com/products/{id} ?
And if it is the second solution, how should I retrieve my product ID? This solution would imply a second Ajax request to retrieve the ID, am I wrong?
If someone knows about that or articles talking about the subject, I would love to see that :)
Have a good night, and thank you for your answers and advices!
@El_Matella you can probably do a structure that is similar to the below. I am going to give you some file structure and some code as well so you can see the benefit of this structure. Inspired by this package
// route.php
// add patterns to validate URL parameter. Ex. id
Route::pattern('id', '[0-9]+');
// Angular partials routes
Route::get('/partials/index', function () {
return view('partials.index');
});
Route::get('/partials/{category}/{action?}', function ($category, $action = 'index') {
return view(join('.', ['partials', $category, $action]));
});
Route::get('/partials/{category}/{action}/{id}', function ($category, $action = 'index', $id) {
return view(join('.', ['partials', $category, $action]));
});
// This will attempt to catch all urls
Route::group(['middleware' => 'api'], function()
{
Route::get('/{page}/{subpage?}', function ($page, $subpage) {
return view(join('.', [$page, $subpage]));
});
});
//
//Catch all undefined routes. Always gotta stay at the bottom since order of routes matters.
Route::any('{undefinedRoute}', function ($undefinedRoute) {
return view('layout');
})->where('undefinedRoute', '([A-z\d-\/_.]+)?');
Now you can put the partials folder inside the public folder, ignore the top Angular partials routes and keep all files in .html. Otherwise keep the partials folder inside the views folder and save all files as someTemplateName.blade.php or someTemplateName.php
// public
partials/angularViews
// or views -
partials/angularViews
// everything else
.....
This api.mybackend.com/category/product-slug is fine to use. If in the future you want to use Blade views then you can simply check on the requested data type and return a view if it is not JSON.
// Example angular code to save the token provided by API middleware and intercept http requests made to the backend to bind that token to request headers
angular.module('appRoutes', []).config(['$routeProvider', '$locationProvider', '$httpProvider',
function ($routeProvider, $locationProvider, $httpProvider) {
$routeProvider
.when('/', {
templateUrl: '/partials/index',
controller: 'MainController'
})
.when('/:category/:action?/:id?', {
templateUrl: function (params) {
var allowedParams = ['category', 'action', 'id'];
var paramVals = [];
for (var key in params) {
if (allowedParams.indexOf(key) !== -1) {
paramVals.push(params[key]);
}
}
return '/partials/' + paramVals.join('/');
}
})
.otherwise({
redirectTo: '/'
});
$locationProvider.html5Mode(true);
$httpProvider.interceptors.push(['$rootScope', '$q', '$localStorage',
function ($rootScope, $q, $localStorage) {
return {
request: function (config) {
config.headers = config.headers || {};
if ($localStorage.token) {
config.headers.Authorization = 'Bearer ' + $localStorage.token;
}
return config;
},
response: function (res) {
if (res.status === 401) {
// Handle unauthenticated user.
}
return res || $q.when(res);
}
};
}
]);
}
]);
Please or to participate in this conversation.