DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports Events Over 2 million developers have joined DZone. Join Today! Thanks for visiting DZone today,
Edit Profile Manage Email Subscriptions Moderation Admin Console How to Post to DZone Article Submission Guidelines
View Profile
Sign Out
Refcards
Trend Reports
Events
Zones
Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
  1. DZone
  2. Data Engineering
  3. Databases
  4. Kotlin Spring Boot Web-Service Integration With Database

Kotlin Spring Boot Web-Service Integration With Database

The purpose of the article: analysis of the structure of a web service on Kotlin, consideration of ways to integrate with a database using the example of a CRUD service.

Viacheslav Aksenov user avatar by
Viacheslav Aksenov
·
Jun. 08, 22 · Analysis
Like (7)
Save
Tweet
Share
5.19K Views

Join the DZone community and get the full member experience.

Join For Free

The purpose of the article: analysis of the structure of a web service on Kotlin, consideration of ways to integrate with a database using the example of a CRUD service.

Currently, services in the form of a web application are especially common. And it's hard to imagine some kind of web application that does not store data in any way. Databases are the most common way to store data today.

From the service side, any database looks like an external integration. And if the service is covered by tests, it means that this integration needs to be tested. There are many ways to test this integration; below; we will analyze the most popular ones.

Description of Infrastructure

For example, a basic CRUD Kotlin service based on Spring Boot is used.

A CRUD web service is a service that provides functionality for creating (C), reading (R), updating (U), deleting (D) entities from a database via HTTP requests.

For example, we will consider a service without delete and update functionality - only creation and reading remain. Since, in principle, we will cover everything that is needed with these two methods.

H2 is used as a database, but any relational one can be used. Since we are only looking at integration testing, the general intent of this article will be relevant for any other popular relational database.

Description of the Web Service Functionality

The area of responsibility of the service from the example is integration with pokeApi to get information about the weight of a pokemon by its name. As well as saving this information to a database and providing the opportunity to get all the saved records.

The following dependencies are used for the main functionality of the service:

 
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.module</groupId>
    <artifactId>jackson-module-kotlin</artifactId>
</dependency>
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-reflect</artifactId>
</dependency>
<dependency>
    <groupId>org.jetbrains.kotlin</groupId>
    <artifactId>kotlin-stdlib-jdk8</artifactId>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>


Database Structure

The table for storing information about the weight of a Pokémon in the application's database looks like this:

 
create table pokemon (
    id     integer primary key auto_increment,
    name   varchar(25),
    weight integer
);


id - identifier field
name - a field for storing information about the name of the pokemon
weight - a field with information about the weight of the Pokémon.

Description of Functional Endpoints

The web service has two endpoints with functionality that needs to be covered by tests.

POST /pokemon - saving the model to the database.

The model has 2 required fields - name (String) and weight (Integer).

Call example:

 
###
POST http://localhost:8080/pokemon
Content-Type: application/json

{
  "name": "bulbasaur",
  "weight": 69
}


GET /pokemon is an endpoint that is responsible for providing all records from the database.

In response, the method returns an array of models with 3 fields - id (Long), name (String), weight (Integer).

Call example:

 
###
GET http://localhost:8080/pokemon

response:

[
  {
    "id": 1,
    "name": "bulbasaur",
    "weight": 69
  },
  {
    "id": 2,
    "name": "ditto",
    "weight": 40
  }
]


Controller code:

@RestController
@RequestMapping("/pokemon")
class PokemonController(private val pokemonDao: PokemonDao) {

    @PostMapping
    fun savePokemon(@RequestBody pokemon: Pokemon) {
        pokemonDao.save(pokemon)
    }

    @GetMapping
    fun getAll(): List<Pokemon> = pokemonDao.getAll()

    @ExceptionHandler
    fun handleException(exception: Exception): ResponseEntity<*> {
        return ResponseEntity(exception.message, HttpStatus.BAD_REQUEST)
    }
}


Description of the DAO Layer

The DAO (Data Access Object) layer is solely responsible for integration with the repository. The jdbcTemplate is used to describe database integrations. JdbcTemplate is a Spring library that allows you to write queries in native SQL.

For ease of mapping entities, a regular objectMapper is used. In a heavy load, such a mapping can be changed to a more optimal one.

DAO layer looks like this:

 
@Service
class PokemonDao(private val jdbcTemplate: JdbcTemplate, private val objectMapper: ObjectMapper) {

    fun save(pokemon: Pokemon) {
        jdbcTemplate.update(SAVE_POKEMON, pokemon.name, pokemon.weight)
    }

    fun getAll(): List<Pokemon> =
        jdbcTemplate.queryForList(SELECT_ALL_POKEMONS)
            .map { objectMapper.readValue(objectMapper.writeValueAsString(it), Pokemon::class.java) }
}

@Language("Sql")
private const val SAVE_POKEMON = "insert into pokemon values(default, ?, ?)"

@Language("Sql")
private const val SELECT_ALL_POKEMONS = "select * from pokemon"


Database Configuration

Database parameters can be configured outside web service and in application.properties. There is an example:

 
spring.datasource.url=jdbc:h2:mem:testdb;DATABASE_TO_LOWER=TRUE;CASE_INSENSITIVE_IDENTIFIERS=TRUE;
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect


DDL can be contained in schema.sql 

In total, we have considered the basic way to implement the integration of a web service with a database using the example of H2 + Spring Boot.

How do you test database integrations? I will be glad to hear your thoughts about your ways to integrate web-services with databases in the comments.

Sources can be found in my GitHub repository: pokemon-app

Database Relational database Kotlin (programming language) Spring Boot Integration Web Service

Opinions expressed by DZone contributors are their own.

Popular on DZone

  • Kotlin Is More Fun Than Java And This Is a Big Deal
  • Fraud Detection With Apache Kafka, KSQL, and Apache Flink
  • How Do the Docker Client and Docker Servers Work?
  • Real-Time Stream Processing With Hazelcast and StreamNative

Comments

Partner Resources

X

ABOUT US

  • About DZone
  • Send feedback
  • Careers
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 600 Park Offices Drive
  • Suite 300
  • Durham, NC 27709
  • support@dzone.com
  • +1 (919) 678-0300

Let's be friends: