scala-pet-store
scala-pet-store copied to clipboard
Break up the repository into multiple traits
A lot of the logic in the repositories looks replicated throughout all of the repositories. This may be better to break this up into reusable traits.
I.e.:
OrderService extends ... with Creatable[t] with Deleteable[T] with Updateable[T]
This makes sense to me just for standardizing across multiple types of data.
Is there a function we would write that would only rely on an instance of Creatable
or Deletable
?
Here's one I came up with that saves an object, does some operation, and then cleans it up.
trait Creatable[F[_], T]{
def create(t: T) : F[Unit]
}
trait Deletable[F[_], T] {
def delete(t : T) : F[Unit]
}
object example{
def withAThing[M[_], T, R](f : T => M[R])(implicit
G : Gen[T], // scalacheck
C : Creatable[M, T],
D : Deletable[M, T],
E : MonadError[M, Throwable]
) : M[R] = for {
example <- G.sample.liftTo[M](new AssertionError("Example not generated"))
_ <- C.create(example)
result <- f(example)
_ <- D.delete(example)
} yield result
}
There's also the issue about how to generalize/standardize across just data generated by the database. I've played with this a bit in another project:
CRUDAlgebra/CRUDService: https://github.com/clovellytech/h4sm/tree/master/db/src/main/scala/h4sm/db
Example typeclass extending CRUDAlgebra: https://github.com/clovellytech/h4sm/blob/master/auth/src/main/scala/h4sm/auth/domain/users/UserRepositoryAlgebra.scala
Example instance of the typeclass: https://github.com/clovellytech/h4sm/blob/master/auth/src/main/scala/h4sm/auth/infrastructure/repository/persistent/UserRepositoryInterpreter.scala
That's an interesting idea. However, the only thing I have a question about is how would you make those attributes stackable? I.e. if you had a caching or notification layer on each of those operations?
Hm perhaps by an interesting choice of F
it could be done? I think working an example of such a thing would be good.
It is an interesting idea. I like the idea of a CRUD algebra, because you assume you have to create/update/delete/getById on everything.
I like that because the CRUD operations vary from service to service. Some services don't have deletes, some have getById, etc.