1
0

API-first with openapiprocessor and modelmapper

This commit is contained in:
Michael Hoennig
2022-08-08 16:54:35 +02:00
parent 80f342eeae
commit eeab68d63a
14 changed files with 602 additions and 62 deletions

View File

@ -0,0 +1,39 @@
# TITLE
**Status:**
- [ ] proposed by (Proposer)
- [ ] accepted by (Participants)
- [ ] rejected by (Participants)
- [ ] superseded by (superseding ADR)
## Context and Problem Statement
A short description, why and under which circumstances this decision had to be made.
### Technical Background
Some details about the technical challenge.
## Considered Options
* OPTION-1
* OPTION-...
### OPTION-n
A short overview about the option.
#### Advantages
A list of advantages.
#### Disadvantages
A list of disadvantages.
## Decision Outcome
Which option was chose and why.

View File

@ -0,0 +1,108 @@
# Object Mapping
**Status:**
- [x] proposed by Michael Hönnig
- [ ] accepted by (Participants)
- [ ] rejected by (Participants)
- [ ] superseded by (superseding ADR)
## Context and Problem Statement
Since we are using the *API first*-approach,
thus generating Java interfaces and model classes from an OpenAPI specification,
we cannot use the JPA-entities anymore at the API level,
not even if the data fields are 100% identical.
Therefore, we need some kind of mapping strategy.
### Technical Background
Java does not support duck-typing and therefore, objects of different classes have to be converted to each other, even if all data fields are identical.
In our case, the database query is usually the slowest part of handling a request.
Therefore, for the mapper, ease of use is more important than performance,
at least as long as the mapping part does not take more than 10% of the total request.
## Considered Options
* specific programmatic conversion
* using the *MapStruct* library
* using the *ModelMapper* library
* Dozer, last update from 2014 + vulnerabilities => skipped
* Orika, last update from 2019 + vulnerabilities => skipped
* JMapper
### specific programmatic conversion
In this solution, we would write own code to convert the objects.
This usually means 3 converters for each entity/resource pair:
- entity -> resource
- resource -> entity
- list of entities -> list of resources
#### Advantages
Very flexible and fast.
#### Disadvantages
Huge amounts of bloat code.
### using the *MapStruct* library
See https://mapstruct.org/.
#### Advantages
- Most popular mapping library in the Java-world.
- Actively maintained, last release 1.5.2 from Jun 18, 2022.
- very fast (see [^1])
#### Disadvantages
- Needs interface declarations with annotations.
- Looks like it causes still too much bloat code for our purposes.
### using the *ModelMapper* library
See http://modelmapper.org/.
#### Advantages
- 1:1 mappings just need a simple method call without any bloat-code.
- Actively maintained, last release 3.1.0 from Mar 08, 2022.
#### Disadvantages
- could not find any, will give it a try
### using the *JMapper* library
See https://jmapper-framework.github.io/jmapper-core/.
#### Advantages
- Supports annotation-based and programmatic mapping exceptions.
- Actively maintained, last release 1.6.3 from May 27, 2022.
- very fast (see [^1])
#### Disadvantages
- needs a separate mapper instance for each mapping pair
- cannot map collections (needs `stream().map(...).collect(toList())` or similar)
## Decision Outcome
We chose the option **"using the *ModelMapper* library"** because it has an acceptable performance without any bloat code.
If it turns out to be too slow after all, "using the *JMapper* library" seems to be a good alternative.
[^1]: https://www.baeldung.com/java-performance-mapping-frameworks