Förenkla din mappning

MapStruct

Har du någon gång svurit för dig själv då det i elfte timmen uppdagats att mappningen mellan din interna POJO och den DTO som exponeras via REST-tjänsten failar? Finner du det tråkigt att skriva boilerplate mappningskod? Får ert kodgranskningsverktyg spelet när ni gör alla variabler public för att slippa getters/setters?

Då kan MapStruct vara precis rätt för dig. Det är ett bibliotek som innehåller funktioner för att automatiskt mappa fält mellan två olika Java bönor. Rent konkret räcker det att definiera ett interface med lämpliga MapStruct-annotation, sedan skapar ramverket en implementation vid compile time.

Uppsättning

Förutsatt att ni har ett Maven-projekt så handlar det i sedvanligt manér om att först och främst lägga till beroendet.

<dependencies>
...
  <dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-jdk8</artifactId>
    <version>1.2.0.Final</version>
  </dependency>
...
<dependencies>

MapStruct använder sig av annotationsbaserad syntax för att lösa mappningsuppgiften. Det innebär att man som Javautvecklare även behöver lägga till en annotationProcessorPath till sin maven-compiler-plugin.

...
<annotationProcessorPaths>
  ...
  <path>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.2.0.Final</version>
  </path>
  ...
</annotationProcessorPaths>

Komma igång

Låt oss börja med ett exempel baserat på en av våra egna applikationer. Vi har en Konsult definition i form av Consultant.java

public class Consultant {
  private String exertusId;
  private String firstName;
  private String lastName;
}

Frontend-grupperingen är dock inte intresserad av denna nivå av fingranulerad data utan har önskat ett enklare format.

public class ConsultantDTO {
  private String name;
  private String userId;
}

Mappningen

Här kommer Mapstruct in som en räddande ängel för den som inte är överdrivet sugen på att knacka transformerings-boilerplate.

...
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
...
@Mapper
public interface ConsultantMapper {
...
  @Mappings({
    @Mapping(source = "exertusId", target = "userId"),
      @Mapping(expression = "java(consultant.getFirstName() + \' \' + 
        consultant.getLastName())", target = "name")
    })
    ConsultantDTO toApi(Consultant consultant);
}

I koden ovan kan vi göra följande observationer: @Mapping(source, target) nyttjas för att mappa en variabel från källobjektet till en annan i målobjektet. @Mapping(expression, target) nyttjas för att exekvera logik för att skapa ett nytt värde som passas vidare till angivet fält i det objekt som returneras.

Notera att ingen mappning behöver anges i det fall variablerna heter samma i käll- och målklasserna. Mao den bästa mängden kod; ingen alls!

Resultatet

När Frontend-gruppen anropar vår API-backend får de nu en listning av konsulter i följande lättsmälta format:

{
  "name": "Dolph Lundgren",
  "userId": "kungen"
}

Sammanfattning

I det fall mycket av den kod ni skriver handlar om att mappa data kan MapStruct förenkla er vardag.

Om detta är något som intresserar dig så kontakta oss via formuläret nedan!

Vi har mottagit ditt meddelande och återkommer inom kort.
Hoppsan! Något gick dessvärre fel, vänligen verifiera att du inte är en robot eller ladda om sidan och försök igen.
Vi vill göra dig uppmärksam på att vi behandlar dina uppgifter i strikt enlighet med vår Integritetspolicy. Allt för att du ska känna dig trygg i att vi värnar om din integritet.