Grunt serve + PHP?

All we need is an easy explanation of the problem, so here it is.

I’m starting my first project with yo + grunt + angular.js.
I have a service which needs to read some data from my server; I built it using angular $http service.
I’ve also built a RESTful web service (implemented in PHP, but it could be Java, C, Perl, …, it doesn’t matter) which exposes an API to get the data.
The server from which grunt serves my ng-app is currently (and probably will ever be) the same from where the PHP web service is run (by apache).

I wonder if this is an acceptable architecture… I end up having two distinct servers (grunt and apache) on the same server… More, I always have to add an “Access-Control-Allow-Origin:127.0.0.1” to the output of my PHP service… 🙁

Is it possible to serve PHP from grunt, for example?

UPDATE: I speak about development stage… Of course at production I wouldn’t use grunt…
To better explain myself, I would like to use relative urls in $http()… With the same code at both the development and the production stages…
If at production I can expect it to work, because I will only have one server for the deployed Angular app and the PHP service, who’s supposed to interpret PHP at development, when the Angular app is served by Grunt? Grunt itself? If yes, how?

UDPATE 2, AND A POSSIBLE SOLUTION: After thinking quite a bit on this issue (and also reading this article), and not receiving satisfactory answers here, I decided I will use this approach:

  • Development
    • Use a “production-like” server (Apache, lighttpd, …) to serve real PHP pages.
      Use absolute urls with $http or $request to access that server (distinct from Grunt, which serves angular.js pages). The urls will be easily configurable, to require only a minimum work (and possible errors) to switch to production.
    • In PHP scripts, before producing (JSON) output, always output a proper “Access-Control-Allow-Origin” header; the value of the directive will also be easily configurable.

  • Production
    • Deploy angular.js app to the same server where PHP is deployed.
    • Change the urls, and make them relative, since now they share the same origin with client-side scripts.
    • Change the “Access-Control-Allow-Origin” header, to allow only local requests (or possibly remove that header at all…).

I would be very pleased if anybody would like to comment this solution, to dispute it, or to propose better ones…

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

Our solution to the problem at work was to create flat files with sample data inside the app folder and use relative URLs with $resource and $http and then deploy our code as an application at the same subdirectory level… /fx/api/fund for example.

This allows grunt to serve up something static for seeing what the design will look like of the Angular app while still providing a full experience. Then we have a development server that gets updated when we commit code (using Jenkins) that we can check for real functionality and run our test suite against.

This approach is a little clumsy but it allows us to get the benefits of the grunt approach and still have a testing server. We also have our builds use the minified version so that we can test that magnification won’t break the app.

The only problem with this approach is that the built in web server with grunt can’t handle post requests so anything calling a post will fail.

Method 2

It sounds like you are trying to do the same thing as me. ( solution for local development only)

I am using yo angular to start an angular project, but I want to connect to a php service to deliver some content.

I used grunt-connect-proxy to pass my post request to apache. This works well, except for the fact that $_POST remains empty when sending form-data e.g. $http.post('/api',{"foo":"bar"}). I posted an issue about this, but it still remains unsolved and I can not figure out how to make that work. Anyway, the other solution is to keep everything in the same folder/domain.

That was my story

Actually the story had a tail.
Finally I figured out what was causing the problem, see this post

Method 3

Not receiving a satisfactory answer, after thinking quite a bit about the issue myself, I provide hereafter my conclusions:

  • Development
    • Use a “production-like” server (Apache, lighttpd, …) to serve real PHP pages.
      Use absolute urls with $http or $request to access that server (distinct from Grunt, which serves angular.js pages). The urls will be easily configurable, to require only a minimum work (and possible errors) to switch to production.
    • In PHP scripts, before producing (JSON) output, always output a proper “Access-Control-Allow-Origin” header; the value of the directive will also be easily configurable.

  • Production
    • Deploy angular.js app to the same server where PHP is deployed.
    • Change the urls, and make them relative, since now they share the same origin with client-side scripts.
    • Change the “Access-Control-Allow-Origin” header, to allow only local requests (or possibly remove that header at all…).

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply