Scalatra (http://scalatra.org/)를 웹 프레임 워크로 사용하는 Scala 응용 프로그램이 있습니다. Sangria (http://sangria-graphql.org/) 및 Scalatra를 사용하여 GraphQL 끝점을 구현하는 방법에 대한 좋은 (또는 단지 모든) 리소스가 있는지 궁금합니다.Scala, Sangria and Scalatra
저는 스칼라를 처음 접했고 이에 대한 도움을 주셔서 감사합니다.
Scalatra (http://scalatra.org/)를 웹 프레임 워크로 사용하는 Scala 응용 프로그램이 있습니다. Sangria (http://sangria-graphql.org/) 및 Scalatra를 사용하여 GraphQL 끝점을 구현하는 방법에 대한 좋은 (또는 단지 모든) 리소스가 있는지 궁금합니다.Scala, Sangria and Scalatra
저는 스칼라를 처음 접했고 이에 대한 도움을 주셔서 감사합니다.
내가 아는 것이 없지만 Scalatra가 json4를 사용하기 때문에 sangria의 json4s marshaller을 사용하게됩니다.
그렇지 않으면 sangria가 더 명확해질 수 있다면 play + sangria를 기반으로 한 매우 단순한 예제가있는 스칼라 워크 시트가 있습니다.이 경우 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)
굉장, 고마워! :-) – KimAMartinsen