123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293 |
- /*
- * Copyright (C) 2020 Prasoon Joshi
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <https://www.gnu.org/licenses/>.
- */
- package graphql
- import repository.{DataRepository, UserRepository}
- import play.api.libs.json.{JsObject, JsString, JsValue, Json}
- import play.api.mvc.Results._
- import play.api.mvc._
- import sangria.execution.{ErrorWithResolver, Executor, QueryAnalysisError}
- import sangria.parser.QueryParser
- import scala.concurrent.{ExecutionContext, Future}
- import scala.util.{Failure, Success}
- import sangria.marshalling.playJson._
- import sangria.schema.Schema
- import sangria.execution.ExceptionHandler
- case class GraphqlServer(dataRepo: DataRepository,
- userRepo: UserRepository) {
- import scala.concurrent.ExecutionContext.Implicits.global
- val errorHandler = ABagOfGoodies.errorHandler
- def fetchQueryResult(userToken: Option[String],
- requestJson: JsValue)(implicit ec: ExecutionContext): Future[Result] = {
- val JsObject(fields) = requestJson
- val JsString(query) = fields("query")
- QueryParser.parse(query) match {
- case Success(queryAst) =>
- val operation = fields.get("operationName") collect {
- case JsString(op) => op
- }
- val variables = fields.get("variables") match {
- case Some(obj: JsObject) => obj
- case _ => JsObject.empty
- }
- val vars = (requestJson \ "variables").toOption.flatMap {
- case JsString(xs) => Some(parseVariables(xs))
- case obj: JsObject => Some(obj)
- case _ => None //Json.obj()
- }
- executeGraphQLQuery(query = queryAst,
- userToken = userToken,
- errorHandler = errorHandler,
- op = operation,
- vars = {vars getOrElse Json.obj()})
- case Failure(error) =>
- Future.successful(BadRequest(Json.obj("error" -> error.getMessage)))
- }
- }
- def parseVariables(vars: String) =
- if (vars.trim == "" || vars.trim == "null") Json.obj() else Json.parse(vars).as[JsObject]
- def executeGraphQLQuery(query: sangria.ast.Document,
- userToken: Option[String],
- errorHandler: ExceptionHandler,
- op: Option[String],
- vars: JsObject): Future[Result] =
- Executor.execute(
- schema = SchemaDefinition.schema,
- query,
- userContext =
- new SecureGraphqlContext(userToken, userRepo, dataRepo),
- exceptionHandler = errorHandler,
- operationName = op,
- variables = vars)
- .map(Ok(_))
- .recover {
- case error: QueryAnalysisError => BadRequest(error.resolveError)
- case error: ErrorWithResolver => InternalServerError(error.resolveError)
- }
- }
|