There aren't any that I know of but since Scalatra uses json4s you would use sangria's json4s marshaller .
Otherwise, if sangria could be clearer to you, here's a scala worksheet with a very simplistic example based off play + sangria - in this case you would just need to swap the json library.
The db is mocked (perhaps you use Slick?) and the http server as well but it's a simple case of swapping in the function definitions.
import sangria.ast.Document import sangria.execution.{ErrorWithResolver, Executor, QueryAnalysisError} import sangria.macros.derive.{ObjectTypeDescription, ObjectTypeName, deriveObjectType} import sangria.parser.{QueryParser, SyntaxError} import sangria.renderer.SchemaRenderer import sangria.schema.{Argument, Field, IntType, ListType, ObjectType, OptionInputType, Schema, fields} import scala.concurrent.Await import scala.concurrent.duration._ import scala.concurrent.ExecutionContext.Implicits.global import scala.concurrent.Future import scala.util.{Failure, Success} // replace with another json lib // eg https://github.com/sangria-graphql/sangria-json4s-jackson import play.api.libs.json._ import sangria.marshalling.playJson._ case class User(name: String, age: Int, phone: Option[String]) class FakeDb { class UsersTable { def getUsers(limit: Int): List[User] = { // this would come from the db List( User("john smith", 23, None), User("Anne Schwazenbach", 45, Some("2134556")) ) } } val usersRepo = new UsersTable } object MySchema { val limitArg: Argument[Int] = Argument("first", OptionInputType(IntType), description = s"Returns the first n elements from the list.", defaultValue = 10) implicit val UsersType: ObjectType[FakeDb, User] = { deriveObjectType[FakeDb, User]( ObjectTypeName("Users"), ObjectTypeDescription("Users in the system") ) } private val Query: ObjectType[FakeDb, Unit] = ObjectType[FakeDb, Unit]( "Query", fields[FakeDb, Unit]( Field("users", ListType(UsersType), arguments = limitArg :: Nil, resolve = c => c.ctx.usersRepo.getUsers(c.arg(limitArg)) ) )) val theSchema: Schema[FakeDb, Unit] = Schema(Query) } object HttpServer { def get(): String = { // Http GET SchemaRenderer.renderSchema(MySchema.theSchema) } def post(query: String): Future[JsValue] = { // Http POST val variables = None val operation = None QueryParser.parse(query) match { case Success(q) => executeQuery(q, variables, operation) case Failure(error: SyntaxError) => Future.successful(Json.obj("error" -> error.getMessage)) case Failure(error: Throwable) => Future.successful(Json.obj("error" -> error.getMessage)) } } private def executeQuery(queryAst: Document, vars: Option[JsValue], operation: Option[String]): Future[JsValue] = { val schema: Schema[FakeDb, Unit] = MySchema.theSchema Executor.execute[FakeDb, Unit, JsValue](schema, queryAst, new FakeDb, operationName = operation, variables=vars.getOrElse(Json.obj())) .map((d: JsValue) => d) .recover { case error: QueryAnalysisError ⇒ Json.obj("error" -> error.getMessage) case error: ErrorWithResolver ⇒ Json.obj("error" -> error.getMessage) } } } HttpServer.get() val myquery = """ { users { name } } """ val res: JsValue = Await.result(HttpServer.post(myquery), 10.seconds)