Saturday, February 25, 2017

Spring Tutorial: Creating a Hello World REST API Using Spring Framework and Spring Boot

Spring Framework was created as a result of disappointment of Java community with earlier versions of Enterprise Java. Since then it has grown into huge ecosystem that allows one to solve every problem in building a Web-based Java application and more. Spring is often criticized because it used to rely on XML for configuration purposes. As a response to that the Spring Boot framework was released, which relies on convention over configuration principle and can do without XML at all.

In this tutorial series we’ll go over how to create an application using Spring Framework and Spring Boot. While Spring Boot allows one to create an application faster, Spring is widely used today in enterprise environment and even by startups, so knowing Spring is definitely a marketable skill, and also learning it can provide one with the insight how Spring Boot works. The code for a simple Spring Framework application can be found here and the Spring Boot version here.



Creating Spring Web Application Using Maven Archetype



To create a Spring web application one can rely on maven-archetype-webapp archetype. After that, one should add Spring-related modules to the pom.xml file. One way to go is to use the so-called BOM (Bill of Materials) which allows one not to add version to dependencies. The pom.xml file for our project is shown below.


Now, while we added no code to our application, we can try to build it and deploy. The Maven archetype we used created a index.jsp file located in the webapp/ folder, which we’ll remove later but for now we’ll use to learn how to deploy an application to Tomcat 9 Web-profile application server. To build the application one can use an IDE or execute the following command from CLI.

mvn clean package

Independent of the way you built the application a war file is produced in the target/ sub-folder of the project folder.




Deploying Spring Web Application To Tomcat


The application can be deployed either using an IDE or manually, but before that it is necessary to download Tomcat if it’s not installed on your system and configure it. The installation process is simple: it’s necessary to unzip the downloaded file to some folder and add the path to the bin sub-folder to the PATH variable on your system. In addition, it is necessary to create a CATALINA_HOME environment variable and set it to the path to Tomcat installation folder.

To make possible the access to the Web interface it is necessary to add a single role and a single user to the tomcat-users.xml configuration file situated in the conf/ sub-folder as shown below.


It’s way more faster to deploy the application using an IDE, but here we’ll talk about how to manually deploy the application to Tomcat 9. To start Tomcat server one has to type
catalina.bat start on Windows and

catalina.sh start on Linux.

To check that the server has actually started, navigate to localhost:8080 and the picture shown below should appear.



To stop the server one has to type the same commands with stop instead of start.

The simplest way to manually deploy an application to Tomcat is to copy the generated war file, in our case SpringREST.war, to the webapps/ subfolder of the Tomcat installation folder. After that, just navigate to http://localhost:8080/SpringREST/, where SpringREST is the name of the application, and you should see “Hello World!” greeting in your browser. Another way to deploy an application is to use Manager App from the aforementioned Tomcat Web console.




Adding Configuration Necessary to Run Spring Web Application


Now we’ll remove index.jsp file and create a REST API that returns a greeting instead. First, we need to add a Dispatcher Servlet to web.xml file in the WEB-INF/ subfolder of webapp/ sub-folder. The web.xml file is shown below.


The name of the servlet is dispatcher and Spring will be looking for a file named dispatcher-servlet.xml in the same sub-folder for configuration settings. The file is shown below and instruct Spring to scan classpath in search of the REST controller that serves HTTP requests and returns a greeting.


Now we are ready to create a controller.




Adding Hello World Spring MVC REST Controller


The code for the controller is shown below. The controller is marked with @RestController annotation. Previously we instructed Spring to scan particular packages to look for classes marked with this and some other annotations and use those classes. The annotation tells Spring that this class will serve HTTP requests using Spring MVC.


Also, there is the @GetMapping annotation specifying the path at which the resource can be reached. In our case that means that one can obtain the greeting by localhost:8080/SpringREST/hello URL using HTTP GET method. In earlier Spring version the @RequestMapping annotation was used for specifying paths and HTTP methods used to access a resource.




Testing Spring MVC controllers


A code for a simple test for our controller is shown below. For testing purposes we use the same configuration file but named test-dispatcher-servlet.xml and placed to src/test/resources/ subfolder of our project’s folder.


The test class is decorated with @RunWith annotation that instructs JUnit to run our test with a SpringRunner. The Spring MVC Test framework allows us to test our controller without a servlet container. Inside the test method we make a GET request to our resource and check the response.




Creating a Hello World REST API using Spring Boot


To create a seed Spring Boot project we’ll use Spring Initializr and then open the project using an IDE. We type Web in “Search for dependencies” input field and select “Web” as shown on the picture below and press the “Generate Project” button. The zip file is downloaded after that.



Now, we should add the same REST controller to our Spring Boot project as we created previously. The project can be built using the same command as before, but result is packaged as a jar file by default and uses an embedded Tomcat, so no deployment is necessary, but don’t forget to stop Tomcat before launching the Spring Boot version. The project is launched using the following command.

java -jar target/SpringBootREST-0.0.1-SNAPSHOT.jar

The application is accessible using the URL shown below.

localhost:8080/hello

As to testing the controller, the code of the test method is the same, but annotations on the class change; we do not use XML configuration for this project. The following snippet shows the test class for our controller.


It is seen that it takes less steps to recreate the same application using Spring Boot as a lot of things is inferred by the framework.




Summary


In this post we discussed how to create a simple Hello World REST API using both Spring Framework and Spring Boot. Also, we discussed how to test code using Spring MVC Test Framework. While it’s faster to develop applications using Spring Boot and that’s definitely a benefit for the purposes of learning that it is not necessary to do a lot of configuration, Spring framework is often found in job descriptions and it may be useful to know how a framework works under the hood.

It should be noted, that a Web application can consist of several modules, e.g. it could be a REST API that exposes all the application functionality that can be consumed by an Angular or React front end, a hybrid or native mobile application or a front-end part written in Spring, which consumes the REST API data and republishes it using HTML and some template or component-based Java framework. Creation of Maven multi-module application could be accomplished using pom-root Maven archetype.


Resources:

Monday, February 6, 2017

AngularJS Tutorial: AngularJS Controller As Syntax

Introduction to AngularJS Controller As Syntax


In the previous installment of this series we discussed scopes and what problems nested scopes can cause. There are a couple of solutions to this problem: the so-called Controller As syntax introduced by AngularJS 1.2 and .component() method introduced by AngularJS 1.5. The latter option is a recommended way to go if you are thinking about upgrading your application to newer Angular versions. In this post we’ll talk about AngularJS Controller As syntax.

As was mentioned previously, when we instruct Angular to use a controller with the ng-controller directive, a new instance of a controller and a child scope is created. Alternatively, the same directive but with a different syntax can be used to create a controller and to attached it to a newly-created scope as the snippet below shows.


The differences are that, first, in the ng-controller directive we not only pass the name of the registered controller, but also, a variable name for an instance of the controller; vm stands for ViewModel but a more meaningful name can be used and we’ll talk about it later. Second, when we use double curly braces or the ng-model directive, we use vm.myModel to access to the variable defined in the controller. The following snippet shows how a controller using Controller As syntax looks like.


It differs from the version using $scope; we don’t pass the $scope variable to our controller, so there is also no necessity to add code that copes with minification. Also, we create the vm variable and store the value of this it it to prevent future problems when working with this. The most important point here that all the variables and methods are created inside the vm object; this helps to clear scope from our data and methods. The visualization of AngularJS scopes obtained by Batarang is shown in the following picture.



The fact that we don’t pass $scope to our controller doesn’t mean that it is impossible. In fact, $scope has useful methods and if we decide to use them we can pass $scope to our controller. The idea is to store everything we create in a special vm object. To stress once again how Controller As syntax is used by AngularJS I’ll show you an example of a controller’s test that relies on it.


Now we create a new $scope using $rootScope in order to rely on JavaScript prototypal inheritance and use scope methods. Also, we obtain the aforementioned root scope inside beforeEach method and use Controller As syntax to obtain an instance of our HelloController from the $controller() function. Finally, inside the it() method, we obtain our data using scope.

A more succinct version of the controller’s test that doesn’t rely on AngularJS scope is shown below.


After we’ve refactored our code, we could make sure that we haven’t broken anything and this could be accomplished using Protractor. A single problem is that we extract some elements by their model but now it is vm.myModel, not myModel. After ironing out this wrinkle launching Protractor e2e tests should end up in success.

AngularJS Nested Scopes


After we’ve introduced AngularJS Controller As syntax, it’s high time to see how it helps solve the nested scope problem. The HTML snippet below shows how to use the syntax in this case. While it’s possible to name each controller as vm because each of the controllers attached to a different scope, we use more clear names for controllers to prevent name collisions.


The code for controllers is similar to the above one for HelloController and can be found here. The scopes look like in the pictures below. The first is for the parent scope.



And the second one is for the child scope.



Testing is done in the similar way to the HelloController and test examples can be found here. Also, is we talk about end-to-end testing using Protractor, it is easier to extract elements by their model because the latter contains the name of the controller, so we don’t need to manipulate arrays of elements with the same model name.

Summary


In this tutorial we learned how to use AngularJS Controller As syntax. In the next post we’ll talk about AngularJS components introduced by version 1.5.


Resources

Sunday, February 5, 2017

AngularJS Tutorial: Introduction to AngularJS Scopes

Introduction to AngularJS Scopes



In the previous tutorial of this series we learned how to test controllers using Jasmine and Karma. In this post we discussed how data is passed from controller to view using $scope, which is the glue that links model and view. In this tutorial we’ll talk more about scopes, what are some possible pitfalls in using them, and later we’ll talk about the ways to overcome possible problems, as well as get over Batarang, a Chrome extension from AngularJS team, which can be used to analyze scopes inside an AngularJS application.


By adding the ng-app directive to some HTML tag we specify that an AngularJS will be created and in the process of application creation Angular creates the so-called root scope. Some other directives such as ng-controller create a child scope. To visualize scopes one can use a Google Chrome extension called Batarang. The picture below shows the root scope for the AngularJS application and the child scope created by HelloController, which contains a single variable myModel.





What if we created another controller, say to work not with greetings but farewells and that controller would contain a variable with the same name as in HelloController? It is possible to have  variables with the same name that belong to different scopes. The snippet below shows the code for our GoodbyeController. While variables have the same name, the content is different.




Now we should add another section to our index.html file and attach a controller to it as shown below.




It should be noted that it’s necessary to add the link to the controller’s code to the HTML file. The source code for this tutorial can be found here. Now we have two scopes inside the root scope, each of which was created by one of the two controllers, which is depicted in the following images.





The myModel variable in the scope of the first controller has the value ‘World’ and the value ‘Everyone’ in the scope of the second controller.





When we write tests for our second controller, the code is pretty much the same as in the first case, but things are different with e2e tests because we extracted elements by their model and now we have two models with the same name. To solve this problem one should replace a piece of code that finds a single element


element(by.model('myModel'))


by the code that extracts the list of elements with the same model name and then specify the position of the desired element in the list.


element.all(by.model('myModel')).get(1)


Nested AngularJS Scopes



A more complex case is shown by the following snippet of code when we have an article nested in a section and each of them has its own controller.




In each of the controllers we have variables with the same name, myModel. The code for the parent controller is shown below.




Also, each controller has a variable specific to it. The following snippet show the code for a child or nested controller.




Now we can use Batarang to explore scopes. We see that the myModel variable in the parent scope has the value different than in the child scope as shown by the screenshots below.





Also, we have access to the variable created in the parent scope inside the child scope as can be seen from the web page.





The explanation of the fact that we have access to a variable created in the parent scope from inside the child scope is that parent and child scope are linked with JavaScript Prototypal Inheritance relationship, which means that when the onlyParent variable is not found in the child scope, JavaScript looks for it in the parent, parent of a parent, etc. scopes.


The question is whether we can access the value of the myModel variable defined in the parent scope from the child scope. The answer is yes and this can be accomplished by the snippet of code shown below.


<p>{{$parent.myModel}}</p>


The takeaway from this post is that AngularJS scopes are difficult to work with because AngularJS directives may create their own scopes and variables defined in a parent scope can be hidden by the ones defined in child scopes. This can be error prone but there are some best practices that help one to avoid this kind of problems.


Summary


In this tutorial we talked about scope creation and how to visualize scopes using a Chrome extension called Batarang. Also, we talked about nested scopes and to what problems that could lead as well as how to do end-to-end testing in this case. In the next tutorial we’ll talk about the best practices that allow to avoid problems with AngularJS nested scopes.


Resources

  1. JavaScript Inheritance and the Prototype Chain