Building Web Applications With Spring, Cucumber, and Swagger
In this post, I will be showing how to build a production ready Java web application that provides some services (REST APIs).
Join the DZone community and get the full member experience.
Join For FreeWhy?
Because a lot of software developers spend a lot of time building production ready Java-based web applications (with APIs) that include an automated test suite.
My intention is to build a reference application using a proven/robust application stack which can then be used to build applications from the scratch, fast. Maybe 10X faster.
TL;DR
In this post, I will be showing how to build a production ready Java web application that provides some services (REST APIs). The best part is that I will be including a test suite that with one Maven command will test all the APIs. This lays the foundation of how software should be developed from the start using proper unit tests, which allows developers to spend less time wiring the frameworks and spend more time on the actual code and business logic.
We will be using the Spring Boot framework, Cucumber, and Apache Maven.
The entire application code can be downloaded from here. Please give me a *STAR* if you like it.
Part 1: The Puzzle
The Example Application
We will build a sample Weather Tracker application that takes in some parameters, and computes the values (generate statistics). Don’t worry about the calculations. The main point is to the setup and overall application development and build.
Pieces of the Puzzle
We will need all the above tech to build a complete web application. Let us see how we can wire all of them together.
Part 2 : Fixing the Puzzle
Let's build the application progressively.
- Build a Java web application (and include the code for services — APIs).
- Add test cases to verify each of the services.
- Add Swagger for API documentation.
Build — Test — Documentation—(Repeat) — Ship it

Part 3 : Getting to Work
Folder Structure
We'll use Spring Boot to create, build, and launch a sample project. Then add the APIs (per our business requirements) and Cucumber tests. Then, we'll use Swagger to generate the API docs. Finally, we'll build the application using Apache Maven.
Below is the folder structure of the sample application.

Part 3.1. Java Code
The main part of the app will be built woth Spring Boot under thesrc/WeatherTrackerApplication.java
file — this is the main file that wires the Java code.
Part 3.2. Add Tests using Cucumber/Gherkins
All tests are under the features
folder. Each test file has an extension of .feature
Feature: Add a measurement
In order to have source information to examine later
I want to be able to capture a measurement of several metrics at a specific time
Scenario: Add a measurement with valid (numeric) values
# POST /measurements
When I submit a new measurement as follows:
| timestamp | temperature | dewPoint | precipitation |
| "2015-09-01T16:00:00.000Z" | 27.1 | 16.7 | 0 |
Then the response has a status code of 201
And the Location header has the path "/measurements/2015-09-01T16:00:00.000Z"
Scenario: Cannot add a measurement with invalid values
# POST /measurements
When I submit a new measurement as follows:
| timestamp | temperature | dewPoint | precipitation |
| "2015-09-01T16:00:00.000Z" | "not a number" | 16.7 | 0 |
Then the response has a status code of 400
1: Include the test jar in the project in theassets
folder. I included the c1-code-test-take-home-tester-1.1.0.tgz
file.
2: Add test tasks in pom.xml (as shown below).
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>install-tester</id>
<phase>generate-sources</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<executable>npm</executable>
<arguments>
<argument>install</argument>
<argument>--no-save</argument>
<argument>./assets/c1-code-test-take-home-tester-${takeHomeTester.version}.tgz</argument>
<argument>--prefix</argument>
<argument>.</argument>
</arguments>
</configuration>
</execution>
...
...
3: When you run the command mvn clean verify
the below task from pom.xml
is called.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.6.0</version>
<executions>
<execution>
<id>integration-test</id>
<phase>verify</phase>
<goals>
<goal>exec</goal>
</goals>
<configuration>
<skip>${skipTests}</skip>
<executable>node</executable>
<arguments>
<argument>--no-warnings</argument>
<argument>${npm.binDirectory}/take-home-integration-test</argument>
<argument>features</argument>
<argument>--check-new</argument>
<argument>--command</argument>
<argument>java -jar ${project.build.directory}/${project.build.finalName}.jar</argument>
<argument>--port</argument>
<argument>${takeHomeTester.port}</argument>
<argument>--out-file</argument>
<argument>${takeHomeTester.logFile}</argument>
<argument>--</argument>
<argument>--tags</argument>
<argument>not @skip</argument>
</arguments>
</configuration>
</execution>
</executions>
4: The test scenarios defined in the .feature
files test each API using the application URLhttp:\\localhost:8000\
and show the result.
Part 3.3. Adding Swagger
Swagger is a great open-source package that generates documentation for APIs in our code. The best part is that it also creates the web UI for us. A URL like this, http://localhost:8000/swagger-ui.html#, will load the API docs.
We have to add some details around our classes, methods, and params for the docs to look more detailed, though.
1: Add dependencies to pom.xml
:
<!-- Swagger -->
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger2</artifactId>
<version>2.9.2</version>
</dependency>
<dependency>
<groupId>io.springfox</groupId>
<artifactId>springfox-swagger-ui</artifactId>
<version>2.9.2</version>
</dependency>
2: Add the primary config class.
The file can be anywhere under your src
folder. The best option is to place it at the same level as your main @SpringBootApplication
config class.
package com.weathertracker;
import static springfox.documentation.builders.PathSelectors.regex;
import java.util.Collections;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Contact;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
/**
* Swagger configuration file to generate API documentation
*/
@Configuration
@EnableSwagger2
public class Swagger2Config {
@Bean
public Docket api() {
return new Docket(DocumentationType.SWAGGER_2).select()
.apis(RequestHandlerSelectors
.basePackage("com.capitalone.weathertracker"))
.paths(PathSelectors.regex("/.*"))
.build()
.apiInfo(apiEndPointsInfo());
}
private ApiInfo apiEndPointsInfo() {
return new ApiInfoBuilder()
.title("Weather Tracker API Documentation")
.description("Weather Tracker REST API")
.license("Apache 2.0")
.licenseUrl("http://www.apache.org/licenses/LICENSE-2.0.html")
.version("1.0.0")
.build();
}
}
The file can be anywhere under your src
folder. The best option is to place it at the same level as your main @SpringBootApplication
config class.
3: Test. Visit the URL http://localhost:8000/swagger-ui.html#/. This should load the documentation page as

Part 4: Wiring it All Together , the Final Test
Run this command and you should see all tests passed and application running at localhost:8000.
<project-root>$ mvn spring-boot:run -e
Resources
- Source files for the example project are here
- Behaviour-Driven Development
- Using Spring boot
- Using Swagger with Spring Boot
Published at DZone with permission of Suren Konathala. See the original article here.
Opinions expressed by DZone contributors are their own.
Trending
-
Which Is Better for IoT: Azure RTOS or FreeRTOS?
-
RAML vs. OAS: Which Is the Best API Specification for Your Project?
-
What to Pay Attention to as Automation Upends the Developer Experience
-
How Agile Works at Tesla [Video]
Comments