Library for generation boilerplate-free code for models in compile time with Scala macro
Scala macros to generate oft-repeated models with annotations and convenient case class conversion.
Usage:
libraryDependencies += "io.github.model4s" %% "model4s" % "1.0"
Suppose you have the next model Person:
case class Person(id:Long, name:String, email:String, goodsAmount: Int)But, now you want to create well-formed models to describe something like DTO within
microservices or model for DAO, both of them contains fields subsets of initial model Person:
case class PersonDAO(id:Long, name:String, email:String)
case class PersonDTO(name:String, email:String, goodsAmount: Int)Model4s solves this in the next way:
import com.github.model4s.modelfree.Base._
import com.github.model4s.modelfree.ModelFree
@ModelFree case class Person(
@dao id : Int,
@dao @dto name : String,
@dao @dto email : String,
@dto goodsAmount: Int
)Annotation ModelFree is a marker for single point of base model configuration,
you cat treat Person class as full join of model for code generation, in this situation it's Dao and Dto.
It will generate companion object for class Person with nested case classes for models, so you can call it in
the next way: Person.Dao and Person.Dto.
After business layer/DAO/DTO moving towards to the gateway of your App - HTTP REST APIs, now you want to describe
entities for serving HTTP requests/responses:
case class PersonGet(id:Long, email:String)
case class PersonPost(name:String, email:String)
case class PersonPut(id:Long, name:String, email:String)That is a lot of boilerplate! Maintaining all of this models quickly becomes tedious for more complicated models.
With Model4s, you can easily reduce all this 6 models to the single point:
@ModelFree case class Person(
@dao @get @put id : Int,
@dao @dto @post @put name : String,
@dao @dto @get @post @put email : String,
@dto goodsAmount: Int
)If you use microservice architecture possibly you can duplicate business model in different part of services
like HTTP based entity like e.g. Gateway Service use User model for auth/registration and send it to
Registration service and further in business flow to UserStatistic service, 3 services serve same User model,
Model4s allows to get rid of this, you have the single point of configuration which can be wrapped up in reusable
submodule/jar/war file etc.
Model4s allows to make transformation between map and case classes seamlessly, it wraps macro into
twitter's Bijection type.
Let's suppose, you have the next input:
case class User(id: Int, name: String)
val samplePerson = User(13, "Steve")
val sampleMap = Map("id" -> 15, "name" -> "Bill")Model4s handles it in the next way with Mappable:
val map = Mappable.transform[User].apply(samplePerson)
val user = Mappable.transform[User].invert(sampleMap)Mappable is wrapper over twitter's Bijection, to be more precise: Bijection.build[T, CaseClassMap]
With default settings Intellij doesn't support Scala's macros, it can be enabled in settings:
Build, Execution, Deployment -> Compiler -> Scala Compiler -> Scala Compiler Server -> enable "Macros" tab
License - MIT