Platinum Partner
enterprise-integration,javascript,spring mvc,spring,rest api,angularjs,html5,web dev

AngularJS – Single Page App with RESTful APIs & Spring MVC

The article presents a recipe to create a single page application with AngularJS & Spring MVC where different pages are required to do transactions with the server using RESTful API.

The article presents recipe to create single page application with AngularJS & Spring MVC where different pages are required to do transactions with server using RESTful API. The demonstration is created on this page, http://hello-angularjs.appspot.com/angularjs-single-page-app-restful-apis.

Code samples and related concepts are presented for following requirements of single page app:

  • Initially one page is loaded with side navigation.
  • Clicking on side navigation loads new view (data) from server by consuming RESTful API using ngResource, $resource service with “query” action method
  • Clicking on individual items link loads the related data from server, again by consuming RESTful API using ngResource, $resource service with “get” action method
  • Submitting a set of data consumes a RESTful API and sends the data to the server for persistence. Here, $resource service with “save” action method is used.

The demo app presents a trivial app which allow users to do some of the following:

  • Create new users
  • Get all users
  • Get users by Id

In this example, one userservice is created that does the RESTful transaction. This userservice is used in multiple different controllers used to load/manage different views.

Following are keys to creating AngularJS Single Page App that consumes RESTful APIs:

  • Angular module dependencies
  • Routing code that defines routes for different links. 
  • Code to manage the transactions with RESTful APIs. I created a custom User service that provides APIs to do transactions with RESTful APIs
  • Controller code that defines how data will be retrieved/handled in each view
  • Server side code to receive RESTful API request and send appropriate response
Angular Module Dependencies

Following are two different modules that will be required to be included when creating app:

  • ngRoute
  • ngResource

Following is the code sample:

var userApp = angular.module("userApp", [ 'ngRoute', 'ngResource' ]);

You would also have to include following withinelement:

<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-route.js"></script>
<script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/angularjs/1.2.18/angular-resource.js"></script>
Routing Code

Following represents the routing code which defines how each link/path will be processed (controller, templateURL)

userApp.config(function($routeProvider) {
$routeProvider.when('/users/new', {
controller : 'NewUserCtrl',
templateUrl : 'views/newuser.html'
}).when('/users/:userId', {
controller : 'UsersByIdCtrl',
templateUrl : 'views/userbyid.html'
}).when('/users', {
controller : 'UsersCtrl',
templateUrl : 'views/users.html'
}).otherwise({
controller : 'SpaCtrl',
templateUrl: 'views/spahome.html'
    });
});
User Service – Transactions with RESTful APIs

Following code is used to userservice using AngularJS factory recipe. This userservice internally instantiates User class by passing $resource service to its constructor function. Note that $scope is passed to individual APIs/methods and that the value for model is set within each API. Once updated, the model values appear on the UI.

userApp.factory( 'userservice', [ '$resource', function( $resource ){
return new User( $resource );
}] );

function User( resource ) {

this.resource = resource; 

this.createUser = function ( user, scope ) {
// 
// Save Action Method
//
var User = resource('/users/new');
User.save(user, function(response){
scope.message = response.message;
});
}

this.getUser = function ( id, scope ) {
//
// GET Action Method
//
var User = resource('/users/:userId', {userId:'@userId'});
User.get( {userId:id}, function(user){
scope.user = user;
})
}

this.getUsers = function( scope ) {
//
// Query Action Method
//
var Users = resource('/users/all');
Users.query(function(users){
scope.users = users;
});
}
}
AngularJS Controller Code for Different Views
// Controller when the main page/view loads
userApp.controller("SpaCtrl", [ '$scope', function($scope) {
} ]);
// Controller for All Users View
userApp.controller("UsersCtrl", [ '$scope','userservice', function($scope, userservice) {
userservice.getUsers( $scope );
} ]);
// Controller for New User View
userApp.controller("NewUserCtrl", [ '$scope','userservice', function($scope, userservice) {

userservice.getUsers( $scope );

$scope.createNewUser = function(){
var newuser = { 'firstname':$scope.firstname, 'lastname': $scope.lastname, 'address':$scope.address, 'email':$scope.email };
// Call UserService to create a new user
//
userservice.createUser ( newuser, $scope );

// Push new user to existing table column
//
$scope.users.push( newuser );
// Reset fields values
//
$scope.firstname='';
$scope.lastname='';
$scope.address='';
$scope.email='';
};
} ]);
// Controller for Individual User View
userApp.controller("UsersByIdCtrl", [ '$scope','userservice', '$routeParams', function($scope, userservice, $routeParams) {
userservice.getUser($routeParams.userId, $scope);
} ]);
Spring MVC Controller Code for RESTful API

Following demonstrates the Spring MVC Controller code for three different RESTful APIs with URL written as part of RequestMapping value parameter:

All Users (/users/all)

@RequestMapping(value = "/users/all", method = RequestMethod.GET)
        public  @ResponseBody String getAllUsers( ModelMap model ) {
            String jsonData = "[{\"id\":\"3253123\",\"firstname\":\"Chris\",\"lastname\":\"Johnson\",\"address\":\"211, Geoffrey Drive\",\"city\":\"Newark\",\"phone\":\"999-888-6666\",\"email\":\"chrisj@yahoo.com\"},{\"id\":\"67643837\",\"firstname\":\"Bill\",\"lastname\":\"Derkson\",\"address\":\"201, Sleepy Hollow Drive\",\"city\":\"Newark\",\"phone\":\"999-777-2222\",\"email\":\"billd@gmail.com\"}]";
            return jsonData;
        }

New Users (/users/new)

@RequestMapping(value = "/users/new", method = RequestMethod.POST)    
        public  @ResponseBody String createNewUser( @RequestBody User user )   {        
            //
            // Code processing the input parameters
            //    
             String response = "{\"message\":\"Created New User - firstname: " + user.getFirstname() + ", lastname: " + user.getLastname() + ", address: " + user.getAddress() + ", email: " + user.getEmail()+"\"}";
            return response;
        }

User By Id (/users/{id}

@RequestMapping(value = "/users/{id}", method = RequestMethod.GET)    
        public  @ResponseBody String getUsersById( @PathVariable("id") long userId )   {        
            //
            // Code processing the input parameters
            //    
            String response = "{\"id\":\""+ userId + "\",\"firstname\":\"FirstName\",\"lastname\":\"LastName\",\"address\":\"Some Address\",\"age\":\"SomeNo\",\"email\":\"sometext@gmail.com\"}";
            return response;
        }

After having found the recipe for creating single page app that could consume RESTful APIs, I am not sure if I would be using any other way to create single page app other than the way described in this article. Please feel free to share your ideas/suggestions/thoughts.

Published at DZone with permission of {{ articles[0].authors[0].realName }}, DZone MVB. (source)

Opinions expressed by DZone contributors are their own.

{{ tag }}, {{tag}},

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}
{{ parent.authors[0].realName || parent.author}}

{{ parent.authors[0].tagline || parent.tagline }}

{{ parent.views }} ViewsClicks
Tweet

{{parent.nComments}}