Spring Boot makes developing RESTful services ridiculously easy. And using Swagger makes documenting your RESTful services easy.

Building a back-end API layer introduces a whole new area of challenges that goes beyond implementing just endpoints. You now have clients which will now be using your API. Your clients will need to know how to interact with your API. In SOAP based web services, you had a WSDL to work with. This gave API developers a XML based contract, which defined the API. However, with RESTFul web services, there is no WSDL. Thus your API documentation becomes more critical.

API documentation should be structured so that it’s informative, succinct, and easy to read. But best practices on, how you document your API, its structure, what to include and what not to is altogether a different subject that I won’t be covering here. For best practices on documentation, I suggest going through this presentation of Andy Wikinson.

In this post I’ll cover how to use Swagger 2 to generate REST API documentation for a Spring Boot project.

Swagger 2 in Spring Boot

Swagger 2 is an open source project used to describe and document RESTful APIs. Swagger 2 is language-agnostic and is extensible into new technologies and protocols beyond HTTP. The current version defines a set HTML, JavaScript, and CSS assets to dynamically generate documentation from a Swagger-compliant API. These files are bundled by the Swagger UI project to display the API on browser. Besides rendering documentation, Swagger UI allows other API developers or consumers to interact with the API’s resources without having any of the implementation logic in place.

The Swagger 2 specification, which is known as OpenAPI specification has several implementations. Currently, Springfox that has replaced Swagger-SpringMVC (Swagger 1.2 and older) is popular for Spring Boot applications. Springfox supports both Swagger 1.2 and 2.0.

We will be using Springfox in our project.

To bring it in, we need the following dependency declaration in our Maven POM.

In addition to Sprinfox, we also require Swagger UI. The code to include Swagger UI is this.

The Spring Boot RESTful Application

Our application implements a set of REST endpoints to manage products. We have a Product JPA entity and a repository named ProductRepository that extends CrudRepository to perform CRUD operations on products against an in-memory H2 database.

The service layer is composed of a ProductService interface and a ProductServiceImpl implementation class.

The Maven POM of the application is this.

pom.xml

The controller of the application , ProductController defines the REST API endpoints. The code of ProductController is this.

In this controller, the @RestController annotation introduced in Spring 4.0 marks ProductController as a REST API controller. Under the hood, @RestController works as a convenient annotation to annotate the class with the @Controller and @ResponseBody.

The @RequestMapping class-level annotation maps requests to /product onto the ProductController class. The method-level @RequestMapping annotations maps web requests to the handler methods of the controller.

Configuring Swagger 2 in the Application

For our application, we will create a Docket bean in a Spring Boot configuration to configure Swagger 2 for the application. A Springfox Docket instance provides the primary API configuration with sensible defaults and convenience methods for configuration. Our Spring Boot configuration class, SwaggerConfig is this.

In this configuration class, the @EnableSwagger2 annotation enables Swagger support in the class. The select() method called on the Docket bean instance returns an ApiSelectorBuilder, which provides the apis() and paths() methods to filter the controllers and methods being documented using String predicates. In the code, the RequestHandlerSelectors.basePackage predicate matches the guru.springframework.controllers base package to filter the API. The regex parameter passed to paths() acts as an additional filter to generate documentation only for the path starting with /product.

At this point, you should be able to test the configuration by starting the app and pointing your browser to http://localhost:8080/v2/api-docs
Swagger JSON Output
Obviously, the above JSON dump that Swagger 2 generates for our endpoints is not something we want.

What we want is some nice human readable structured documentation, and this is where Swagger UI takes over.

On pointing your browser to http://localhost:8080/swagger-ui.html, you will see the generated documentation rendered by Swagger UI, like this.

Swagger default documentation

As you can see, Swagger 2 used sensible defaults to generate documentation of our ProductController .

Then Swagger UI wrapped everything up to provide us an intuitive UI. This was all done automatically. We did not write any code or other documentation to support Swagger.

Customizing Swagger

So far, we’ve been looking at Swagger documentation, as it comes out of the box. But Swagger 2 has some great customization options.

Let’s start customizing Swagger by providing information about our API in the SwaggerConfig class like this.

SwaggerConfig.java

In the SwaggerConfig class, we have added a metaData() method that returns and ApiInfo object initialized with information about our API. Line 23 initializes the Docket with the new information.

The Swagger 2 generated documentation, now look similar to this.
Swagger Generated API Information

Swagger 2 Annotations for REST Endpoints

At this point, if you click the product-controller link, Swagger-UI will display the documentation of our operation endpoints, like this.
Swagger default endpoint documentation

We can use the @Api annotation on our ProductController class to describe our API.

The Swagger-UI generated documentation will reflect the description, and now looks like this.
Customized Swagger Generated API Description
For each of our operation endpoint, we can use the @ApiOperation annotation to describe the endpoint and its response type, like this:

Swagger 2 also allows overriding the default response messages of HTTP methods. You can use the @ApiResponse annotation to document other responses, in addition to the regular HTTP 200 OK, like this.

One undocumented thing that took quite some of my time was related to the value of Response Content Type. Swagger 2 generated "*/*", while I was expecting "application/json" for Response Content Type. It was only after updating the @RequestMapping annotation with produces = "application/json" that the desired value got generated. The annotated ProductController is this.

ProductController.java

The output of the operation endpoints on the browser is this.
Swagger generated endpoint and response code documentation
If you have noticed, the current documentation is missing one thing – documentation of the Product JPA entity. We will generate documentation for our model next.

Swagger 2 Annotations for Model

You can use the @ApiModelProperty annotation to describe the properties of the Product model. With @ApiModelProperty, you can also document a property as required.

The code of our Product class is this.

Product.java

The Swagger 2 generated documentation for Product is this.
Swagger model documentation

Summary

Beside REST API documentation and presentation with Swagger Core and Swagger UI, Swagger 2 has a whole lot of other uses too that is beyond the scope of this post. One of my favorite is Swagger Editor, a tool to design new APIs or edit existing ones. The editor visually renders your Swagger definition and provides real time error-feedback. Another one is Swagger Codegen – a code generation framework for building Client SDKs, servers, and documentation from Swagger definitions.

Swagger 2 also supports Swagger definition through JSON and YAML files. It is something you should try if you want to avoid implementation-specific code in your codebase by externalizing them in JSON and YAML files – something that I will cover in a future post.

The code for this post is available for download here.

0
Share

When developing enterprise applications, Spring programmers typically prefer writing data-centric code against a lightweight in-memory database, such as H2 rather than running an enterprise database server such as Oracle, or MySQL. Out of the box, Spring Boot is very easy to use with the H2 Database.

In-memory databases are useful in the early development stages in local environments, but they have lots of restrictions. As the development progresses, you would most probably require an RDBMS to develop and test your application before deploying it to use a production database server. I have written a series of posts on integrating Spring Boot for Oracle, MySQL, and PostgreSQL.

If you are wondering about the complexities of switching between databases, it’s actually quite simple. When you’re using Spring Data JPA with an ORM technology like Hibernate, the persistence layer is fairly well decoupled, which allows you to easily run your code against multiple databases. The level of decoupling even allows you to easily switch between an RDBMS and a NoSQL database, such as MongoDB. My previous post on Integrating Spring Boot for MongoDB covers that.

In this post, I will discuss Spring Boot integration for MariaDB. MariaDB started off as an offshoot of MySQL due to concerns of Oracle’s acquisition of MySQL. Led by the original developers of MySQL, MariaDB has become one of the fastest growing open source databases.

MariaDB Configuration

For this post, I’m using MariaDB installed locally on my laptop. You’ll need to have a database defined for your use.
Use the following command to log into MariaDB:

Once you are logged in, use the following command to create a database.

MariaDB Dependencies

First, we need to add the MariaDB database driver, mariadb-java-client, as a dependency to our project. The Maven POM file is this.

pom.xml

Spring Boot Properties

We need to override the H2 database properties being set by default in Spring Boot. The nice part is, Spring Boot sets default database properties only when you don’t. So, when we configure MariaDB for use, Spring Boot won’t setup the H2 database anymore.

The following properties are required to configure MariaDB with Spring Boot. You can see these are pretty standard Java data source properties.

As we are using JPA, we need to configure Hibernate for MariaDB too. Line 4 tells Hibernate to recreate the database on startup. This is definitely not the behavior we want if this was actually a production database You can set this property to the following values: none, validate, update, create-drop. For a production database, you probably want to use validate.

JPA Entity

In our example application, we will perform CRUD operations on a user. For that, we will write a simple JPA entity, User for our application. I have written a post to use Spring Data JPA in a Spring Boot Web application, and so won’t go into JPA here.

User.java

JPA Repository

Spring Data JPA CRUD Repository is a feature of Spring Data JPA that I extensively use. Using it, you can just define an interface that extends CrudRepository to manage entities for most common operations, such as saving an entity, updating it, deleting it, or finding it by id. Spring Data JPA uses generics and reflection to generate the concrete implementation of the interface we define.

For our User domain class we can define a Spring Data JPA repository as follows.

UserRepository.java

That’s all we need to setup Spring Boot to use MariaDB. We will write some test code for this setup.

UserRepositoryTest.java

For the test, I have used JUnit. To know more about JUnit, you can refer my series on JUnit Testing.
The result of the JUnit test is this.

JUnit Test Result for MariaDB

Conclusion

As you can see, it is very easy to configure Spring Boot for MariaDB. As usual, Spring Boot will auto configure sensible defaults for you. And as needed, you can override the default Spring Boot properties for your specfic application.

0
Share
, , , ,

This is part 6 of the tutorial series for building a web application using Spring Boot. In this post we look at adding a DAO Authentication provider for Spring Security.

We started off with the first part by creating our Spring project using the Spring Initializr. In part 2, we rendered a web page using Thymeleaf and Spring MVC. This was followed by part 3 where we looked at setting up Spring Data JPA for database persistence. Part 4 was all about consolidating everything to provide a working Spring Boot MVC Web Application capable of performing CRUD operations.

In the previous part 5 of this series, we configured a basic in-memory authentication provider. It’s a good starting point to learn Spring Security, but as I mentioned there, it’s not for enterprise applications. A production-quality implementation would likely use the DAO authentication provider.

In this part of the series, I will discuss Spring Security with the DAO authentication provider to secure our Spring Boot Web application. We will implement both authentication and role-based authorization with credentials stored in the H2 database. For persistence, we will use the Spring Data JPA implementation of the repository pattern, that I covered in part 3. Although there are several Spring Data JPA implementations, Hibernate is by far the most popular.

As the Spring Data JPA dependency is included in our Maven POM, Hibernate gets pulled in and configured with sensible default properties via Spring Boot.

This post builds upon 5 previous posts. If you’re not familiar with all the content around Spring, I suggest you to go through this series from the start.

JPA Entities

Our application already has a Product JPA entity. We’ll add two more entities, User and Role. Following the SOLID design principle’sprogram to interface ” principle, we will start by writing an interface followed with an abstract class for our entities.

DomainObject.java

AbstractDomainClass.java

The entity classes are as follows.

User.java

Role.java

The User and Role JPA entities are part of the many-to-many relationship. Also, in Line 15 of the User class, notice that the password field is marked as @Transient.

That’s because we don’t want to store the password in text form.

Instead, we will store the encrypted form of the password.

JPA Repositories

Spring Data JPA provides the CRUD Repository feature. Using it, we just define the repository interfaces for our User and Role entities to extend CrudRepository.

The Spring Data JPA repositories for the User and Role entities are as follows.

UserRepository.java

RoleRepository.java

By extending CrudRepository, both the repositories inherit several methods for working with entity persistence, including methods for saving, deleting, and finding entities. Spring Data JPA uses generics and reflection to generate the concrete implementations of both the interfaces.

Spring Data JPA Services

We can now create the services, that will use Spring Data JPA to perform CRUD operations on the User and Role entities.

Of course, we will follow the Interface Segregation principle to maintain loose coupling. It’s always best to “program to interface”, especially when leveraging the benefits of Spring’s dependency injection.

So, let’s start with the service interfaces.

CRUDService.java

UserService.java

RoleService.java

Both RoleService and UserService extends CRUDService that defines the basic CRUD operations on entities. UserService, with the additional findByUsername() method is a more specialized service interface for CRUD operations on User.

We have made the service interfaces generic to mask our service implementations using the Façade design pattern. The implementations can be Spring Data JPA with repository, DAO, or Map patterns, or even plain JDBC, or some external Web service. The client code does not need not to be aware of the implementation. By using interfaces, we are able to leverage multiple concrete implementations of the services.

We’ll write the service implementation classes using the Spring Data JPA repository pattern.

UserServiceImpl.java

In this class, we auto-wired in UserRepository and EncryptionService. Going ahead, we will create EncryptionService using the Jasypt library to add encryption capabilities for storing user passwords. The overridden methods of this class use the UserRepository we created to perform CRUD operations on User.

The RoleServiceImpl provides a similar implementation for RoleService.

RoleServiceImpl.java

Free Spring TutorialPassword Encryption Service

The Jasypt library provides an implementation for unidirectional encryption. We will use Jasypt to encrypt a password before storing it to the database. For authentication, we will provide Jasypt the received password. Under the hood, Jasypt will encrypt the received password and compare it to the stored one.

Let’s add the Jasypt dependency to our Maven POM.

Note: The latest available Jasypt 1.9.2 targets Spring Security 3. But even for Spring Security 4 that we are using, Jasypt doesn’t have compatibility issues.

With Jasypt pulled in, we will write a bean for StrongPasswordEncryptor of Jasypt – a utility class for easily performing high-strength password encryption and checking. The configuration class, CommonBeanConfig is this.

CommonBeanConfig.java

Our generic EncryptionService interface will define two methods to encrypt and compare passwords.

EncryptionService.java

The implementation class is this.

EncryptionServiceImpl.java

In this implementation class, we autowired the StrongPasswordEncryptor bean. In Line 18, the encryptPassword() method encrypts the password passed to it. In Line 22, the checkPassword() method returns a boolean result of the password comparison.

User Details Service Implementation

Spring Security provides a UserDetailsService interface to lookup the username, password and GrantedAuthorities for any given user. This interface provides only one method, loadUserByUsername(). This method returns an implementation of Spring Security’s UserDetails interface that provides core user information.

The UserDetails implementation of our application is this.

UserDetailsImpl.java

In this class, we have defined the fields of our data model and their corresponding setter methods. The SimpleGrantedAuthority we set on Line 16 is a Spring Security implementation of an authority that we will convert from our role. Think of an authority as being a “permission” or a “right” typically expressed as strings.

We need to provide an implementation of the loadUserByUsername() method of UserDetailsService. But the challenge is that the findByUsername() method of our UserService returns a User entity, while Spring Security expects a UserDetails object from the loadUserByUsername() method.

We will create a converter for this to convert User to UserDetails implementation.

UserToUserDetails.java

This class implements the Spring Core Coverter  interface and overrides the convert() method that accepts a User object to convert. In Line 16, the code instantiates a UserDetailsImpl object, and from Line 19 – Line 26, the code initializes the UserDetailsImpl object with data from User.

With the converter ready, it’s now easy to implement the UserDetailsService interface. The implementation class is this.

Here is our implemention.

UserDetailsServiceImpl.java

In the UserDetailsServiceImpl class, we auto wired in UserService and Converter. In Line 31, the lone overridden method loadUserByUsername() converts a User to UserDetails by calling the convert() method of Converter.

Security Configuration

The current security configuration class, SpringSecConfig extends WebSecurityConfigurerAdapter to configure two things. An authentication provider and the application routes to protect. Our route configuration will remain the same. However, we need to register the DAO authentication provider for use with Spring Security.

We will start by setting up a password encoder to encode passwords present in the UserDetails object returned by the configured UserDetailsService. We will define a new bean for Spring Security’s PasswordEncoder that takes in the StrongPassordEncryptor bean.

Remember that we created StrongPassordEncryptor earlier in the CommonBeanConfig Spring configuration class?

Next, we will set up the DAO authentication provider, like this.

In this code, we passed the previously configured PasswordEncoder and UserDetailsService to daoAuthenticationProvider(). The PasswordEncoder is going to use the Jasypt library for encoding the password and verifying that the passwords match. The UserDetailsService will fetch the User object from the database and hand over to Spring Security as a UserDetails object. In the method, we instantiated the DaoAuthenticationProvider and initialized it with the PasswordEncoder and UserDetailsService implementations.

Next, we need to auto wire in the AuthenticationProvider as we want the Spring Context to manage it.

We will also auto wire in the AuthenticationManagerBuilder. Spring Security will use this to set up the AuthenticationProvider.

The complete SpringSecConfig class is this.

SpringSecConfig.java

Application Bootstrapping with Seed Data

For seed data of the application, we have an ApplicationListener implementation class that gets called upon the ContextRefresedEvent on startup. In this class, we will use Spring to inject the UserRepository and RoleRepository Spring Data JPA repositories for our use. We will create two User and two Role entities and save them to the database when the application starts. The code of this class is this.

SpringJpaBootstrap.java

This class in addition to loading product data, invokes the following methods to load users and roles at startup:

  • loadUsers(): Stores two User entities. One with “user” and the other with “admin” as both the user name and password.
  • loadRoles(): Stores two Role entities for the “USER” and “ADMIN” roles.
  • assignUsersToUserRole(): Assigns the User with username “user” to the “USER” role.
  • assignUsersToAdminRole(): Assigns the User with username “admin” to the “ADMIN” role.

Free Spring TutorialThymeleaf Extras module

In the previous part 5 of this series, I discussed the Thymeleaf “extras” integration module to integrate Spring Security in our Thymeleaf templates. Things will largely remain unchanged in this presentation layer, except for two instances.
Currently, both USER and ROLE are being referred from the presentation layer code as ROLE_USER and ROLE_ADMIN. This was required because we relied on Spring Security’s in-memory authentication provider for managing our users and roles, and Spring Security’s internal feature maps a configured role to the role name prefixed with ROLE_. With the DAO authentication provider, our roles are mapped to authorities as it is (We did this in in the UserToUserDetails converter), and we can refer them directly from code as USER and ADMIN.

The second change is brought in by GrantedAuthority used by the Spring Security UserDetails interface. If you recall, we mapped our Role implementation to SimpleGrantedAuthority in the UserToUserDetails converter.

Therefore, in the Thymeleaf templates, we need to change the hasRole() and hasAnyRole() authorization expressions to hasAuthority() and hasAnyAuthorities().

The affected templates are header.html and products.html.

header.html

products.html

Running the Application

Our application is configured to run the H2 database console, which I have explained here. So, when you run the application, you’ll now be able to access the H2 database console at http://localhost:8080/console. You can use it to view the initial authentication-related data loaded by the SpringJpaBootstrap class.
USER Table for Spring Security
Role Table for Spring Security

This is how the home page appears to authenticated users with USER and ADMIN roles.

Home Page View for USER Role
Home Page View for ADMIN Role

With our Security configuration, this is how the product listing page appears to users with different roles.

Home Page View for Anonymous
Home Page View for USER Role
Home Page View for ADMIN Role

Summary

Spring Security has a large scope, and what we configured is only a small part of it. Spring Security supports XML-based and annotation-based finer level security configurations. With Spring Security, we can secure websites down to specific URLs, assign roles to URL, and even roles to different HTTP actions – a security configuration typically employed in RESTful APIs.

What makes Spring Security great is that you can easily hook in another security provider. If you noticed, we hardly made any change in the presentation and business logic layers while transitioning from the earlier basic in-memory authentication provider to the DAO provider. We could also use LDAP, Single Sign-On (SSO), OpenID, and OAuth 2.0 providers. It all depends on the requirements of your application.

Get the Source!

The full source code for this example is available here on GitHub.

0
Share
,

Spring Data project provides integration for most of the popular databases around. I have already written few posts to configure Spring Boot to use Oracle, MySQL, and PostgreSQL – all RDBMS widely used in the enterprise.

Recently we’ve seen a rise in popularity of NoSQL databases.  MongoDB has rapidly gained popularity in the enterprise and the Spring community.

In this post, I’ll discuss how to use MongoDB with a Spring Boot application.

NoSQL and MongoDB

NoSQL storage is a vast domain with a plethora of solutions and patterns. Even the term NoSQL have multiple meanings. Originally it stood for “Non SQL”, but gradually with the adoption of Polyglot Persistence which Martin Flower beautifully describes here,

NoSQL is now commonly referred as “Not Only SQL”.

MongoDB is a leading document-based NoSQL database. MongoDB uses JSON documents to store records. Internally, MongoDB represents JSON documents in binary-encoded format called BSON. One feature worth mentioning about MongoDB is it’s dynamic schema. You can insert data without a pre-defined schema – a thing not possible with traditional relational databases.

In today’s competitive business environment where Agile practices are embraced, having a dynamic schema gives you a high degree of flexibility. A great place to learn more about MongoDB is here.

For this post, I’m using MongoDB installed locally on my laptop. You have several options for running MongoDB.

You have several options for running MongoDB. Refer to the MongoDB guide for an explanation on how to install and start up a MongoDB instance.

MongoDB Dependencies

Spring Data for MongoDB is part of the umbrella Spring Data project. With Spring Data for MongoDB, you get a familiar and consistent Spring-based programming model to work with for MongoDB while retaining MongoDB store-specific features and capabilities.

To use MongoDB in a Spring Boot project, we need to add the Spring Data MongoDB starter dependency, spring-boot-starter-data-mongodb . The Maven POM is this.

pom.xml

Notice that we haven’t included Spring data JPA – The Spring Data MongoDB starter dependency brings in the required infrastructure, the MongoDB driver, and few other dependencies to the project.

MongoDB Dependencies with Spring Boot starter

Data Class

Both Spring Data JPA and Spring Data MongoDB share the same common infrastructure. I have already written a post to use Spring Data JPA in a Spring Boot Web application.

Here we need to write a Mongo data class rather than a JPA @Entity. A Mongo data class instance maps to a document stored in a collection.

Note: You can relate a collection of MongoDB to an RDBMS table, and a document to a table row.

Let’s write a User data class.

User.java

We have created User as a plain Java object. The @Document annotation in Line 6 specifies a users collection. This tells Spring Data MongoDB to store a User document to the users collection. This collection will be created if it doesn’t exist. The @Document annotation is optional, and if we don’t use one, the collection will be named with the class name.

All documents in MongDB have an _id field as the primary key. The id field annotated with @Id in Line 8 maps to the MongoDB document’s _id. It’s not mandatory to use the @Id annotation if the primary key field is named id . However, many still use the annotation for readability. Some consider it a best practice to use the Id annotation, even when its not required.

The remaining name and age field will be treated as properties of the MongoDB document.

Mongo Repository

Spring Data Mongo provides Mongo Repository, similar to CRUD Repository of Spring Data JPA. In fact, the MongoRepository interface extends CrudRepository to manage data objects for most common operations, such as saving a document, updating it, deleting it, or finding it by id.

You only need to define the repository interface. Spring Data MongoDB will automatically provide the required implementations.

Here is the Mongo repository:

UserMongoRepository.java

That’s all we need to set to use MongoDB with Spring Boot.

Unit Testing

Lets write some test code for our setup.

UserMongoRepositoryTest.java

For the test, I have used JUnit. To learn more about JUnit, refer my series on JUnit Testing.

Here is the result of the JUnit test.
JUnit Test Result for MongoDB

Configuration Properties

If you are wondering about MongoDB configurations, for this simple application we relied on the defaults. Spring Data MongoDB intelligently picks up the defaults, such as localhost for the host, 27017 for the default MongoDB port, and test for the default MongoDB database to connect. For other values or for advance configurations, you can use the application.properties or application.yml configuration files.

The MongoDB configurations that Spring Boot supports are as follows:

Conclusion

Spring Boot