Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel 4 as RESTful backend for AngularJS

I am trying to build a web application which should use Laravel as a RESTful backend API and AngularJS on client side. I read all the other post on Stackoverflow about the issue, but no one is definitely answering my doubts, at least, I did not find a definitive source example.

For instance...

Should I develop two completely distinct applications, a backend one with Laravel and another, purely client, with AngularJS? But in this case: how to handle them through a single domain (or virtual host)?

Or should I create AngularJS templates inside Laravel, in the "views" folder and from them call Laravel services? I doubt this is the best approach: in this case the backend is not completely decoupled from the frontend implementation.

Also, how to correctly handle routing? I mean: I would like to manage from AngularJS routes like menu/page navigation, calling Laravel only to retrieve data and fill my views. Moving the "public" folder as suggested in this post (Angular JS + Laravel 4: How to compile for production mode?) may help?

Thanx in advance for suggestions, examples...

like image 816
Matteo Piazza Avatar asked Nov 13 '13 22:11

Matteo Piazza


1 Answers

Finally I found a working solution, perfect in my scenario, which does not require a subdomain. In this case Laravel acts exclusively as a RESTful web service, no server side views or templates: the presentation layer is completely demanded to AngularJS.

Let's say I have two completely decoupled applications (FE e WS) inside the same root folder:

root
|__fe
|__ws

I modified virtual host settings under Apache httpd-vhosts.conf file the following way:

<VirtualHost *:80>
    ServerName myapp.com
    DocumentRoot "\www\root\fe"

    alias /ws "\www\root\ws\public"
    <Directory "\www\root\ws\public">
        Options Indexes FollowSymLinks MultiViews
        AllowOverride all
            Order allow,deny
        Allow from all
    </Directory>
</VirtualHost>

I then added "RewriteBase /ws" into my laravel/public/.htacces file:

<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On

    RewriteBase /ws

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.php [NC,L]
</IfModule>

This way I can write in the browser (for instance):

http://myapp.com             (AngularJS client side root)
http://myapp.com/ws/users    (RESTful service endpoint for "users")

And then define a client side, AngularJS routing the following way:

app.config(function($routeProvider) {
    $routeProvider
        .when('/', {controller: 'HomeController', templateUrl: 'templates/home.html'})
        .when('/users', {controller: 'UsersController', templateUrl: 'templates/users.html'})
        .otherwise({redirectTo: '/'});
});

Linking it to a RESTful resource this way:

app.factory('User', function($resource) {
    return $resource('http://myapp.com/ws/users');
});

app.controller('UsersController', function($scope, User) {
    $scope.title = "Users";
    $scope.users = User.query();
});

I enabled HTML5 history API, adding this line to configure my Angular application:

$locationProvider.html5Mode(true);

together with (inside index.html head section):

<base href="/" />
<meta name="fragment" content="!" />

So the last requirement to solve problems like browser page refresh, deep linking, or direct page bookmark, is to add a .htaccess file in the root of the folder which contains the Angular application:

<IfModule mod_rewrite.c>
    Options -MultiViews
    RewriteEngine On

    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^ index.html [NC,L]
</IfModule>

Hope it helps!

like image 73
Matteo Piazza Avatar answered Nov 02 '22 23:11

Matteo Piazza