kindleit / gkit

GKit is a set of combinator libraries which can ultimately be turned into powerful, composable REST servers.

Website GitHub


Join the chat at

GKit is a set of combinator libraries which can ultimately be turned into powerful, composable REST servers.


The gkit packages should make there way into and eventually maven central. But you can always download them manually, or be notified of version updates on bintray:


It's written on top of shapeless & scalaz

The point of GKit is to eliminate as much boilerplate as possible while at the same time allowing for powerful extension and composition points in the handling of stateless http requests.

You can quickly write a RESTful resource with a find query with the following code:

import gkit.mongo._
import play.api.Play.current
import play.api.libs.concurrent.Execution.Implicits.defaultContext
import play.api.libs.json._
import play.api.mvc.Result
import play.modules.gjson._
import play.modules.gresource.Http
import play.modules.gresource.Http._
import play.modules.gresource.mongo._
import reactivemongo.bson.{BSONObjectID, BSONDocument}
import scala.concurrent.Future
import scalaz.Scalaz._
import scalaz._

case class Todo
    _id             : BSONObjectID
  , description     : String
  , completed       : Boolean

case class FindParams
    sortby          : Option[String]
  , asc             : Option[Boolean]

object Todos extends TodoFunctions {
  lazy val httpApi = Http.get(Prefix)(httpFind)

trait TodoFunctions extends QueryFunctions {

  val cname = "todos"

  def httpFind: Kleisli[EFE, AReq, Result] =
    paramsFromReq[FindParams].apply >>>
    liftK(mkFindQry _ >>> find[Todo](cname)) >>>

  def mkFindQry(fp: FindParams) =
      query    = EmptyQ,
      proj     = EmptyQ,
      defaults = fp)

trait QueryFunctions extends JSONPicklerInstances {

  case class FindQuery[A, B](query: A, proj: B, defaults: FindParams)

  class Find[A] {
    def apply[B, C](cname: String)(fq: FindQuery[B, C])
      (implicit BP1: BSONPickler[A], BP2: BSONPickler[B], BP3: BSONPickler[C]): Future[Error \/ List[A]] = {
      val sortby = fq.defaults.sortby | "_id"
      val asc = fq.defaults.asc | true
      val sdoc = BSONDocument(sortby -> asc.fold(1, -1))
      val qb = dbe.collection(cname).find(fq.query, fq.proj).sort(sdoc)

  def find[A] = new Find[A]

  def dbe = GMongoPlugin.dbEnv

trait JSONPicklerInstances {

  implicit def BSONObjectIDPickler: JSONPickler[BSONObjectID] =
    new JSONPickler[BSONObjectID] {
      def pickle(boid: BSONObjectID): JsValue = JsString(boid.stringify)

      def unpickle(v: JsValue, path: List[String]): String \/ BSONObjectID = {
        def parse(s: String) =
          try { BSONObjectID(s).right } catch { case e: Throwable => e.getMessage.left }

        for {
          js <- typecheck[JsString](v, path)(identity)
          id <- parse(js.value).leftMap(e => s"""error at: `${path.mkString(".")}`: $e""")
        } yield id

Activator Plugin

We've also built an activator plugin which has a clear example of a RESTful service with Play!Framework and MongoDB

Work in progress

These libraries are still very much a work in progress and some of the API is not finalized

We definitely need some help, and here are our planned features

  • Some libraries are missing tests
  • Finishing the SQL combinators
  • Adding support for the new Akka http


  • This library was written by Carlos EncarnaciĆ³n
  • Feel free to drop us a line at