【问题标题】:Scala, Sangria and Scalatra斯卡拉、桑格利亚汽酒和斯卡拉特拉
【发布时间】:2017-10-23 08:25:19
【问题描述】:

我们有一个使用 Scalatra (http://scalatra.org/) 作为 Web 框架的 Scala 应用程序。我想知道是否有关于如何使用 Sangria (http://sangria-graphql.org/) 和 Scalatra 实现 GraphQL 端点的任何好的(或只是任何)资源?

我是 Scala 新手,如果能帮助我开始这方面的工作,我将不胜感激。

【问题讨论】:

    标签: scala graphql scalatra sangria


    【解决方案1】:

    据我所知,没有任何消息,但由于 Scalatra 使用 json4s,您将使用桑格利亚汽酒的 json4s marshaller

    否则,如果桑格利亚汽酒对您来说更清楚,这里有一个 scala 工作表,其中有一个非常简单的基于 off play + 桑格利亚汽酒的示例 - 在这种情况下,您只需要交换 json 库。

    db 是模拟的(也许你使用 Slick?)和 http 服务器也是模拟的,但这是在函数定义中交换的简单案例。

    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)
    

    【讨论】:

      猜你喜欢
      • 2011-09-16
      • 2011-06-12
      • 2011-05-16
      • 2012-03-17
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多