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