Skip to the content.

“Nothing is lost, nothing is created, everything is transformed” _Lavoisier

Metamorphosis is an utility library to ease conversions of objects.
Most of development time is due to type conversions: from DTOs to entities, from entities to DTOs or from DTOs and other DTOs.
Metamorphosis helps to write converters in a lean way and places them in a better structure within your project (further details in paragraphs below).

Metamorphosis supports several languages and frameworks:

Chameleon - ph. Nandhu Kumar - pexels.com!

Conversion Service

The conversion service is a component of a general type conversion system. The system defines an SPI to implement type conversion logic and an API to perform type conversions at runtime

/* meta-syntax */

interface Converter<S, T> {

   T convert(S source);   
    
}

and

interface ConversionService {
    
    T convert(S source, Class<T> targetType);

}

The convervion service is a registry of converters and it delegates to its registered converters to carry out type conversion logic. Developer has to call conversion service for any needed conversion

/* meta-syntax */
TargetType targetObject = conversionService.convert(sourceObj, TargetType)

j-metamorphosis follows the model of type conversions provided by Spring Framework (see Spring Type Conversion). It offers an enabler (by annotations) for Spring Conversion Service and other utility classes to write lean converters.
metamorphosis-nestjs brings to NestJS the missing concept of conversion service.

Benefits of a conversion service:

Metamorphosis for Java

Import j-metamorphosis from maven repo

<dependency>
  <groupId>it.fabioformosa</groupId>
  <artifactId>metamorphosis-core</artifactId>
  <version> ... </version>
</dependency> or
<dependency>
  <groupId>it.fabioformosa</groupId>
  <artifactId>metamorphosis-jpa</artifactId>
  <version> ... </version>
</dependency>

add @EnableMetamorphosisConversions to your spring boot config class

@Configuration
@EnableMetamorphosisConversions(basePackages = { "your.package" })
public class MetamorphosisExampleConfig {

}   

To read how to create a converter and how to invoke the conversion service, go to j-metamorphosis README.

Metamorphosis for Javascript

Import metamorphosis-js from npm:

npm install --save @fabio.formosa/metamorphosis

Create a converter:

import { Convert, Converter } from '@fabio.formosa/metamorphosis';

@Convert(Car, CarDto)
export default class CarToCarDtoConverter implements Converter<Car, CarDto> {
  
public convert(source: Car): CarDto {
   const target = new CarDto();
   target.color = source.color;
   target.model = source.model;
   target.manufacturerName = source.manufacturer.name;
   return target;
}

}

The Conversion Helper is an alias for the conversion service:

import { ConversionHelper } from '@fabio.formosa/metamorphosis'
...
ConversionHelper conversionHelper = new ConversionHelper();
const carDto = <CarDto> await conversionHelper.convert(car, CarDto);    

For further details about conversions, go to metamorphosis-js README.

Metamorphosis for NestJS

Import metamorphosis-nestjs from npm:

npm install --save @fabio.formosa/metamorphosis-nest

Import the MetamorphosisModule :

import { MetamorphosisNestModule } from '@fabio.formosa/metamorphosis-nest';

@Module({
  imports: [MetamorphosisModule.register()],
  ...
}
export class MyApp{
}

Create a new converter class, implementing the interface Converter<Source, Target> and decorate the class with @Convert

import { Convert, Converter } from '@fabio.formosa/metamorphosis';

@Injectable()
@Convert(Car, CarDto)
export default class CarToCarDtoConverter implements Converter<Car, CarDto> {
  
  public convert(source: Car): CarDto {
     const target = new CarDto();
     target.color = source.color;
     target.model = source.model;
     target.manufacturerName = source.manufacturer.name;
     return target;
  }

}

Use the conversion service:

import { ConversionService } from '@fabio.formosa/metamorphosis-nest';

@Injectable()
class CarService{

  constructor(private convertionService: ConvertionService){}

  public async getCar(id: string): CarDto{
     const car: Car = await CarModel.findById(id);
     return <CarDto> await this.convertionService.convert(car, CarDto);
  }

}

For further details about conversions, go to metamorphosis-nestjs README.

Support

j-metamorphosis supports JPA in order to convert entities it DTOs and vice versa.
metamorphosis-nestjs supports Mongoose/Typegoose and Type ORM.