scala-pet-store icon indicating copy to clipboard operation
scala-pet-store copied to clipboard

Break up the repository into multiple traits

Open monksy opened this issue 5 years ago • 5 comments

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]

monksy avatar Nov 14 '18 20:11 monksy

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

zakpatterson avatar Nov 14 '18 20:11 zakpatterson

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?

monksy avatar Nov 14 '18 21:11 monksy

Hm perhaps by an interesting choice of F it could be done? I think working an example of such a thing would be good.

zakpatterson avatar Nov 14 '18 21:11 zakpatterson

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.

pauljamescleary avatar Nov 15 '18 02:11 pauljamescleary

I like that because the CRUD operations vary from service to service. Some services don't have deletes, some have getById, etc.

monksy avatar Nov 19 '18 23:11 monksy