Saturday, June 27, 2015

Marrying Angular GUIs and Spring Web Services

Using Angular for your application GUI with Spring Web Services behind it combines the power of Spring and dependency injection with the single-page GUI framework of Angular. Using Angular with AJAX eliminates the page routing that a Spring MVC application forces on the application, but we can still use the Spring MVC application framework to provide a REST web service for that AJAX application.

The obstacle during development is the "same-origin" policy that restricts the Angular application to communicate with the same server it was loaded from. The solution is to put the projects side-by-side in the Spring Tool Suite (STS) and run them side-by-side in the Pivotal TC server.

First of all I have to make a strong recommendation that you do not put your project folders in the STS workspace folder. Read my post about Eclipse Team Projects & Best Practices. The bottom line: manage all of your projects in one hierarchy, not spread out inside of workspaces. Especially if you have more project types than just those in Eclipse.

Make it Work

  1. Create a new Eclipse workspace for your projects.
  2. Add your Spring MVC project to the workspace. This will provide the web services, we just won't build or use any views. The application context name and everything are configured as normal. I prefer to set the context name to "service."
  3. Add a static web project to the workspace. Name the project however you choose, I prefer "angular-gui" when I make mine. This builds a folder that contains only a "webcontent" folder. The webcontent folder is the root of your static site.
  4. Add an index.html with "Hello World!" or some such message in the webcontent folder.
  5. Locate the "base" folder for the Pivotal TC server. Start with the "root" folder is listed on the home page of the server. You get there with http://localhost:8080 when the server is started. Unfortunately the official path is $TC_RUNTIME_INSTANCE. So where is $TC_RUNTIME_INSTANCE? The server should be installed next to STS as "pivotal-tc-server-developer-X.X.X.RELEASE" (the Xs are your release number). The base folder will at this location will be "/base-instance/webapps."
  6. Add a soft link with your "application context" name that links back to the webcontent folder in your static web project. I prefer to use the name "gui." Yes, you can make a symbolic link in windows, here is a link to an article that will help you. If you make the application context for the Spring application "service" and the Angular application "gui" the URLs will be http://localhost:8080/service/ and http://localhost:8080/gui/.
  7. Browse to the URL for your static website and make sure the index page we created in step 4 is displayed.
Because the server is getting the pages right out of your static project any changes will immediately show up while you are browsing, and because the two application context names are hosted from the same server the same-origin policy is no longer an issue.

Working with the Angular Project

The problem with working on an Angular application within Eclipse is always serving the files, so many people like to use Node and tools like WebStorm or Brackets. Buthe JavaScript syntax abilities in Eclipse are fine, and we just solved the problem of having a web server host the files. In fact, we needed to go this route to obtain same-origin.

So it turns out that you can use WebStorm or Brackets if you like on the static web project, STS will not get upset about it. But there is no reason that you cannot use STS either, it will work perfectly well. You will be working in the same tool for both Angular and the Spring project. And you can load the application in the browser of your choice, even the internal browser in Eclipse.

Wrap-up

I described this configuration using STS, but the same thing can be accomplished with any version of Eclipse and a Tomcat server. Just change the location of the link to $CATALINA_HOME/webapps where $CATALINA_HOME is the root of the Tomcat installation.

No comments:

Post a Comment