The aim of the article: evaluation of the construction of an online service on Kotlin, consideration of how to combine with a database utilizing the instance of a CRUD service.
At present, providers within the type of an online utility are particularly frequent. And it is arduous to think about some form of net utility that doesn’t retailer information in any manner. Databases are the commonest technique to retailer information at the moment.
From the service facet, any database appears like an exterior integration. And if the service is roofed by checks, it signifies that this integration must be examined. There are numerous methods to check this integration; under; we are going to analyze the most well-liked ones.
Description of Infrastructure
For instance, a fundamental CRUD Kotlin service based mostly on Spring Boot is used.
A CRUD net service is a service that gives performance for creating (C), studying (R), updating (U), deleting (D) entities from a database by way of HTTP requests.
For instance, we are going to contemplate a service with out delete and replace performance – solely creation and studying stay. Since, in precept, we are going to cowl all the pieces that’s wanted with these two strategies.
H2 is used as a database, however any relational one can be utilized. Since we’re solely taking a look at integration testing, the final intent of this text will probably be related for every other standard relational database.
Description of the Internet Service Performance
The world of duty of the service from the instance is integration with pokeApi to get details about the burden of a pokemon by its title. In addition to saving this info to a database and offering the chance to get all of the saved information.
The next dependencies are used for the principle performance 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 Construction
The desk for storing details about the burden of a Pokémon within the utility’s database appears like this:
create desk pokemon (
id integer major key auto_increment,
title varchar(25),
weight integer
);
id – identifier subject
title – a subject for storing details about the title of the pokemon
weight – a subject with details about the burden of the Pokémon.
Description of Useful Endpoints
The online service has two endpoints with performance that must be coated by checks.
POST /pokemon
– saving the mannequin to the database.
The mannequin has 2 required fields – title (String) and weight (Integer).
Name instance:
###
POST http://localhost:8080/pokemon
Content material-Sort: utility/json
{
"title": "bulbasaur",
"weight": 69
}
GET /pokemon
is an endpoint that’s chargeable for offering all information from the database.
In response, the tactic returns an array of fashions with 3 fields – id (Lengthy), title (String), weight (Integer).
Name instance:
###
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(personal val pokemonDao: PokemonDao) { @PostMapping enjoyable savePokemon(@RequestBody pokemon: Pokemon) { pokemonDao.save(pokemon) } @GetMapping enjoyable getAll(): Checklist<Pokemon> = pokemonDao.getAll() @ExceptionHandler enjoyable handleException(exception: Exception): ResponseEntity<*> { return ResponseEntity(exception.message, HttpStatus.BAD_REQUEST) } }
Description of the DAO Layer
The DAO (Information Entry Object) layer is solely chargeable for integration with the repository. The jdbcTemplate
is used to explain database integrations. JdbcTemplate
is a Spring library that lets you write queries in native SQL.
For ease of mapping entities, a daily objectMapper
is used. In a heavy load, such a mapping will be modified to a extra optimum one.
DAO layer appears like this:
@Service
class PokemonDao(personal val jdbcTemplate: JdbcTemplate, personal val objectMapper: ObjectMapper) {
enjoyable save(pokemon: Pokemon) {
jdbcTemplate.replace(SAVE_POKEMON, pokemon.title, pokemon.weight)
}
enjoyable getAll(): Checklist<Pokemon> =
jdbcTemplate.queryForList(SELECT_ALL_POKEMONS)
.map { objectMapper.readValue(objectMapper.writeValueAsString(it), Pokemon::class.java) }
}
@Language("Sql")
personal const val SAVE_POKEMON = "insert into pokemon values(default, ?, ?)"
@Language("Sql")
personal const val SELECT_ALL_POKEMONS = "choose * from pokemon"
Database Configuration
Database parameters will be configured outdoors net service and in utility.properties
. There’s an instance:
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 will be contained in schema.sql
In whole, we have now thought-about the fundamental technique to implement the mixing of an online service with a database utilizing the instance of H2 + Spring Boot.
How do you take a look at database integrations? I will probably be glad to listen to your ideas about your methods to combine web-services with databases within the feedback.
Sources will be present in my GitHub repository: pokemon-app