Update 2014/01/13: The interface of
grunt-contrib-connect has slightly changed. Please check my article on how to add middleware. The proxy middleware is still the same, tough.
With any application that communicates with some sort of backend interface exchanging JSON data, you're often in the need to use proxies in your own server configuration to overcome CORS restrictions (either that, or use jsonp, which always seems like a workaround to me). Previously --- in the times we worked with our local Apache servers -- it was always a bit tedious and also caused a lot of time running into the project setup for every team member. Now with our yeoman-grunt-bower setup, it mostly takes no longer than a minute. Cause guess what, there's a already Grunt-task for that.
Why do we need proxies? Well, I assume your app uses JSON for data transfer, so by calling an URL like
Proxies help with that. They stand in for the server you want to reach, get the required data, while letting your browser think that you're all in the right domain. So instead by calling
http://someserver.com/API you can call
Creating a proxy with Grunt
Task-runner Grunt has quickly become my most favorite tool when it comes to front-end development. It builds up on Node.js, which allows me to easily create new tasks, plus there are already a lot of great tasks out there which help me with my everyday development. Also for proxies, like the one created by Drewzboto.
Recently we switched our scaffolding process from a GitHub clone clusterf**k to a more streamlined process with Bower and Yeoman, and Yeoman heavily uses Grunt. So this short tutorial will show you how to add a proxy to your already existing Yeoman-like Gruntfile (with
livereload already set in place.
Coulnd't be easier. Just type
npm install --save-dev grunt-connect-proxy
With the parameter
--save-dev the module gets added to your
package.json, the one file you have to make available in your code repository for your co-developers.
Setting up a proxy
connect task in your Gruntfile and add this little snippet:
This snippet tells us, that any call which can't be answered by your machine will be forwared to
someserver.com. There are a lot more options, you might also need
port parameters for instance. Check out the GitHub repo for more information on that.
Add this part to the top of your
Gruntfile.js, right before
and call the
proxySnippet middleware in your
Now you're all set up. The last thing you've to do is to call
configureProxies before using
connect in your task, and everything's ready to go:
It's as easy as that. We added this to our main Gruntfile we use for scaffolding our projects, so everytime we need a proxy, it's just peace of cake instead of endless subdomain and subserver configuration in the old
Directing to more than one server
This was actually a part which required a lot more thinking and understanding of proxies to get this done right. We had the -- at least for us -- rather specific use case to retrieve our data from more than one server at the same time. Mainly because there was one server handling the content, and one server which took care of all the user data. As you can see, the
proxies option in the default task is actually an array, which means we can easily define more than one proxy configuration.
Creating the new context
user which should allow me to use
http://localhost:9000/user to get to
http://userserver.com. I put that one before the other on purpose, cause at the moment this will actually do nothing at all.
Reason is that the proxy can't decide why to redirect all the
user calls to the other service. We need to define a redirection for the original proxy to make this happen:
This rewrite rule tells the proxy that ever call which starts with
user gets redirected to the
user context we defined earlier. It won't work the other way round, since the context has to be defined beforehand, but that shouldn't matter actually. Feel free to include as many proxies and rewrites. Using this structure everything should work fine.
I've to admit that I've grown on Grunt. Not only that everything just seams so easy to create, it's also one definition that works on every workstation in our department. No need for petty set up phases, just everything is on the go and ready if another team member joins a project. Proxies have been the crux for each project, often leading us to switch to JSONP files just for convenience, and because the Backend guys could actually implement that much, much quicker. No need for that anymore.
UpdateIn the meantime Grunt's interfaces have changed and Yeoman's generators use the new
grunt-contrib-connect package instead of the deprecated
grunt-connect one that has been used before. This package includes livereload as a default, though it's not that easy anymore to add middleware than it was before. I addressed this topic in my recent article on The magic behind grunt-contrib-connect. Check it out and add your proxySnippet where it belongs!