In Parts 1 and 2 of this tutorial we have built an application which displays upcoming obstacle course races and the participants that will be running them.  We have addressed some common cloud native app challenges list cross domain requests and service discovery by using projects from Spring Cloud and Netflix, namely Eureka and Zuul.  In part 3 we will finish implementing the web UI of our application.

First lets make sure that we can fix the cross domain issue we were having when we started.

Implementing The Races View

Open main.js in the src/main/resources/static/controllers folder of your web service.  Change the url property of the $http call to /races.

angular.module('ocrApp')
  .controller('MainCtrl', function ($scope, $http) {
	  $http({
          method: 'GET',
          url: '/races'
      }).then(function(response) {
    	  $scope.races = response.data;
      }, function(response) {
    	  console.error('Error requesting races');
      });
  });

Make sure all the services are running and registered with Eureka and go to http://localhost:8080.  If you open the console of your browser you should no longer see any cross domain errors and your request to http://localhost:8080/races should complete successfully.

Now lets leverage the data we are getting back from the request in the view for the main controller.  Open main.html in the src/main/resouces/static/views folder of the web service and change to code to be

<h3>Races</h3>
<ul>
	<li ng-repeat="race in races"><a ng-href="/#/participants/{{race.id}}">{{race.name}}</a></li>
</ul>

After saving this file, go to http://localhost:8080 and you should see a list of races

Screen Shot 2015-09-10 at 3.55.59 PM

Clicking the links won’t work yet because we have not added the views or controllers to render the page, lets do that now.

Adding A Participants View

Create a new file called participants.js in src/main/resources/static/scripts/controllers and add the following code

angular.module('ocrApp')
  .controller('ParticipantsCtrl', function ($scope, $http, $routeParams) {
	  $http({
          method: 'GET',
          url: '/participants/races/' + $routeParams.raceId
      }).then(function (response) {
    	  $scope.participants = response.data;
      }, function(response) {
    	  console.error('Error requesting participants.')
      });
  });

This code just makes a request to our participants service (through Zuul) to get the list of participants for the race we clicked on.  Now we need a view to render the participants names.  Create a file called participants.html in src/main/resources/static/views and add the following code

<h3>Participants</h3>
<ul>
	<li ng-repeat="participant in participants">{{participant.firstName}} {{participant.lastName}}</li>
</ul>

Finally we need to tell Angular about the new participants view and controller.  Open app.js in src/main/resources/static/scripts and modify it so it looks like the following code

angular
  .module('ocrApp', [
    'ngAnimate',
    'ngCookies',
    'ngResource',
    'ngRoute',
    'ngSanitize',
    'ngTouch'
  ])
  .config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'views/main.html',
        controller: 'MainCtrl'
      })
      .when('/participants/:raceId', {
    	  templateUrl: 'views/participants.html',
    	  controller: 'ParticipantsCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });
  });

Last but not least we need to include participants.js in our index.html page so the new JavaScript gets loaded.  Open i_ndex.html_ in src/main/resources/static and at the bottom, right after all the other script tags, add the following script tag to the file

<script src="scripts/controllers/participants.js"></script>

Thats it!  Refresh the page and try clicking on the links, they should all work now and you should be able to see every participant in each race.

Congratulations you have built your first microservice app with Spring Boot and Spring Cloud!  Granted it is very simple and only works on your local machine, but it didn’t take much effort to do because Spring Boot and Spring Cloud make it easy to do what otherwise would be very complex tasks.


Ryan J Baxter

Husband, Father, Software Engineer