user-icon Nikita Kolytschew
29. June 2017
timer-icon 8 min

How to: Web application with Spring Boot, Kotlin and MongoDB

In my previous post (Why I chose MongoDB) I described, why I have chosen MongoDB for the further development of my prototype.

In this post, I would like to give a brief tutorial on how to create a web application using MongoDB and the Spring Framework.

For the tutorial I am going to use:

  • Spring Boot V. 1.5.3
  • Kotlin V. 1.1.2-2
  • Gradle

Why Spring Boot?

Spring Boot is an excellent and simple way to create Spring applications. On the one hand, Spring Boot takes care of the dependency management, ensures that compatible versions are used and provides the dependencies, which are typically required for a particular use case. On the other hand, Spring Boot automates and simplifies the configuration of standard components of an application. Instead of repeatedly writing the same or almost identical XML and Java configurations, you delegate this to Spring Boot and if necessary you can customize some configuration via application.properties. Thanks to Spring Boot it possible to create a fully functional application quickly and with little effort.

And why choose Kotlin?

Kotlin is like Java on steroids. Especially the points

  • reduction of (Java) boilerplate,
  • simple syntax and
  • null-safety

speak for the language. Detailed information can be found in the post Kotlin – The next generation of Java.

There is nothing wrong with the use of Java, but especially the following examples benefit from the simpler syntax.

Spring Boot in 5 Minutes

The easiest way to get a Spring Boot application is by using the website Spring Initializr. On the website you choose

  1. the build tool (Gradle or Maven),
  2. the desired programming language (Java, Groovy or Kotlin),
  3. the Spring Boot Version,
  4. a Group,
  5. an arbitrary name for the artifact,
  6. the dependencies

It finally generates a runnable application, which can be downloaded.

For our example, we are going to use the dependencies:

  • Rest Repositories
  • MongoDB
Spring Initializr Steps; Spring Boot by Example

Figure 1 – Spring Initializr

What is Group or Artifact?

The group and artifact are used to distinguish application from each other. The Group is used to identify, group and separate its own projects from others. The artifact is the name of a project and will be used to name the WAR/JAR. To set the Group you typically use the top level domain, followed by the host name and a possible sub domain of the site, for example de.novatec-gmbh.blog or de.novatec.gmbh.blog. If you do not have your own website you can of course also use the domain to your repository. My repository can be found under https://github.com/nkolytschew therefore I can use com.github.nkolytschew as Group.

In short: if you do not intend to publish your application, Group and Artifact can be left at their default values.

After downloading the zip file, it can be unpacked and the project can be imported in the IDE of choice (Eclipse, NetBeans, IntelliJ IDEA). In order for our application to be able to perform an initial interaction and display a message, we create a controller, which prints the text Hello Universe.


The @RestController annotation combines the @Controller and @ResponseBody annotations. On the one hand, the class is recognized as a controller component and on the other hand the return value is rendered as a String, JSON or XML.

To start the application, you can use the Windows Command Prompt (Ctrl R -> cmd) and execute the Gradle task bootRun:


If everything was successful you get the message:


Afterwards you can access the application via http://localhost:8080/ and see the output Hello Universe.

MongoDB in 5 minutes

After we made sure our Spring application runs, we take care of our database. There are several ways to access a database:

  • Run and access your own database from your local machine
  • Access an embedded database within the spring application, as an in-memory solution or
  • Access the database as an external service from a server.

For this example, we install a MongoDB Community Server on our own Computer (Download-URL: MongoDB Community Server). This has the advantage that we can access and modify the documents independently of the application and do not have to rely on any server or service.

After downloading and installing of the MongoDB Community Server (follow the instruction of the installer), you are ready to create, access and modify the documents. To determine if the installation was successful, you can start the MongoDB Server (mongod) and the shell (mongo) and enter a first command. The shell and server can be found in <installationsdir>/Server/3.4/bin/ (for example on Windows: C:\Program Files\MongoDB\Server\3.4\bin\mongo for the shell). After the server is started and the shell is connected, we create a database with the command use example. If a database with the name already exists, it will only switch to this database.

With the command db.test.insertOne({name: “test”}) one can create a document in the collection test. If there is no collection with this name, a new collection will be created. In addition to the field name an _id field will also be created and initialized with an automatically generated value.

After you have created a document, you can use db.test.find({}) to output the result.

Figure 2 shows the expected in- and outputs.

MongoDB Shell - I/O

Figure 2 – MongoDB Shell I/O

User Interface

The community version of MongoDB comes without a GUI. Most of the tasks can also be solved comfortable on the MongoDB shell. For those users who prefer to work with an UI there are tools available, e.g. you can use the Open Source Tool Robomongo.

MongoDB and Spring Boot in 5 minutes

Override auto-configuration

For our example we will create a separate database, a collection and finally a first document. In section MongoDB, you see how this can be done via the MongoDB Shell. Of course you can do the whole process through our Spring application. In the following we are going to

  1. define the database,
  2. create a plain Kotlin class, which represents a Document and
  3. create a Spring-Data repository for Create, Read, Update, Delete (CRUD) operations.

First we configure the Database within the application.properties. Via the prefix spring.data.mongodb you can access the properties like Host, Port, URI or Database. By default the properties URI and PORT are predefined with the values mongodb://localhost/test and 27017. This allows to access the locale installation of the MongoDB without additional configuration. If you leave the default settings, all documents will be created under the database test. For the first step, we change the database to example. This can be done via:

Kotlin No-Arg constructor

Then we have to create an Entity, or to stay in context a Document class, that defines the name of the collection and the schema of our documents. Although MongoDB is “schema-free” and makes it possible to create arbitrarily different documents via the shell, we are bound by the programming language to a certain minimal structure. This is because we are going to work with the data on the one hand and on the other we want to display some relevant data. Of course it is also possible to (read and) write empty documents. If the class does not contain any attribute, the created documents will consist only of an _id and a class field. If you read this document, you will get an empty JSON.

For our example, we are going to create documents in the collection test. Each document consists only of a field name, whose contents can be any string.


In the first line we explicitly specify the name of the collection in which the documents are stored. If the annotation is omitted, a collection is created based on the name of the class. Using Spring-Data-REST, we are going to access the individual documents via its Id.

This document class has a little bit of boilerplate code. This is because the different libraries like Jackson or JPA require a no-arg constructor to create an object and then use the setter to write the values. A possible workaround is to use an empty constructor (line 2), mark the variables with the keyword lateinit (line 3 and 4) and initialize the variables in the constructor (line 6, 7 and 8). However, with this workaround the variables will be mutable.

Another possibility shows the following listing:


The variables will be marked as optional and initialized with a default value (in this case null). This is not recommended, because you are bypassing the “null-safety” feature of Kotlin and we have to work with null-checks. In addition the variables remain mutable.

If you have the possibility to integrate further dependencies, you can add and use the Kotlin-Noarg plugin. The Kotlin-Noarg plugin creates an constructor with no arguments, which will be used from different libraries to create an object. To use the Kotlin-Noarg plugin, we have to add the corresponding dependencies to the Gradle buildscript. Following it can be added using apply plugin. In addition to the Kotlin-Noarg plugin there is also a Kotlin-jpa plugin available. The main difference between this plugin is, that you do not have to configure the kotlin-jpa plugin, because it will generate no-arg constructors for each class annotated with a specific JPA annotation. On the other hand the Kotlin-Noarg plugin is more flexible, since you can configure your custom annotation, for which the no-arg plugin should be applied.


The corresponding document can now be written without boilerplate code or optional parameters.

Spring Data REST

Finally, we create a Spring-Data-REST repository, which is responsible for the CRUD-Operations.


You do not have to add the @RepositoryRestResource annotation to access the REST interface. If the annotation is missing, Spring will use the name of the document class as request path. In our example, the path would be /configurationDocuments. But because we want to specify our own path, where the repository is accessed, we use the annotation with the request path /docs. We can than execute CRUD via HTTP methods on the URL http://localhost:8080/docs.

  • GET will return all Documents as JSON
  • POST will create a new document
  • PUT can modify an existing document
  • DELETE can delete an existing document
Overview of the Spring-Data-REST HTTP Methods with the Swagger UI

Figure 3- Spring Data REST – Overview of HTTP Methods

Example

After the classes are created, you can insert your first document. For our example, we assume that neither an entry nor a database exists. Therefore we are going to drop our existing database.

MongoDB Shell I/O

Figure 4 – MongoDB Shell – drop database

As mentioned earlier we have to execute a POST request to create a document. The easiest way to achieve this, besides CURL, is to use Postman. With Postman you have to specify the URL for the POST and the body parameters as JSON and send the request to our running application.

Postman successfull POST

Figure 5 – Postman POST Document

The same POST request using CURL:


After the POST request we should have an entry in the database. Via Spring-Data-REST we can now access this entry using the Id. In my case, this can be done via localhost – Document Id: 592803f02c2f7834a4adce14. In order to not only access documents by Id, we are going to extend the repository with a custom function, which will search for documents by name.

Since we use Spring-Data, we can write our own query using keywords such as findBy, readBy or queryBy. In our case, we want to get all the documents that have a specific name. In other words we try to find all documents by name. According to our wording, we write the following repository method:


This method gives us a list of documents that match the name of the parameter name. We call this method by GET request through the URL http://localhost:8080/docs/search/findAllByName?name=awesome

Summary

In this tutorial we have created the basis for further topics. We created a fully functional web application that can read, create, edit and delete documents via REST.

Since this example is intended as an entry point for Spring and MongoDB, it was kept simple. However, it is going to be expanded in the coming posts. In the following post we are going to replace the local installation of our MongoDB by an external Service and also we are going to extend our document to contain more than one field.

GitHub Repository

  1. MongoDB Example with Kotlin
  2. The same MongoDB Example, but with Java

Sources

  1. Spring Initializr – Homepage
  2. Spring Boot Reference – Spring Docs
  3. Spring Data MongoDB Reference – Spring Docs
  4. Kotlin No-Arg Plugin – Kotlin Homepage
  5. MongoDB Home
  6. Robomongo Home
  7. Postman Home

Comment article