2017-05-23 1 views

답변

1

내가 아는 것이 없지만 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) 
+0

굉장, 고마워! :-) – KimAMartinsen