Skip to content

Instantly share code, notes, and snippets.

@DanielaSfregola
Created October 19, 2017 10:53
Show Gist options
  • Save DanielaSfregola/54f6236a817914667e26b86e9bfafd85 to your computer and use it in GitHub Desktop.
Save DanielaSfregola/54f6236a817914667e26b86e9bfafd85 to your computer and use it in GitHub Desktop.
package io.paytouch.ordering.graphql
import org.json4s.JsonAST.JObject
/**
* Created by danielasfregola on 19/10/2017.
*/
case class GraphQLRequest(query: String, operationName: Option[String], variables: JObject = JObject())
package io.paytouch.ordering.graphql
import akka.http.scaladsl.model.StatusCodes.{BadRequest, InternalServerError, OK}
import akka.http.scaladsl.server.{Directives, Route}
import io.paytouch.ordering.serializers.JsonSupport
import sangria.ast.Document
import sangria.execution.{ErrorWithResolver, Executor, QueryAnalysisError}
import sangria.marshalling.json4s.native._
import sangria.parser.QueryParser
import scala.concurrent.{ExecutionContext, Future}
trait GraphQLResource extends Directives with JsonSupport {
implicit def ec: ExecutionContext
val graphQLRoutes: Route =
get {
getFromResource("graphql/graphiql.html")
} ~
path("graphql") {
post {
entity(as[GraphQLRequest]) { graphQLRequest =>
val result = for {
queryAst <- Future.fromTry(QueryParser.parse(graphQLRequest.query))
resultWithStatus <- execute(graphQLRequest, queryAst)
} yield resultWithStatus
onSuccess(result) { case (r) => complete(r) }
}
}
}
private def execute(graphQLRequest: GraphQLRequest, queryAst: Document) =
Executor
.execute(
schema = GraphQLSchema.MySchema,
queryAst = queryAst,
userContext = new GraphQLService,
operationName = graphQLRequest.operationName,
variables = graphQLRequest.variables
)
.map(OK -> _)
.recover {
case error: QueryAnalysisError ⇒ BadRequest -> error.resolveError
case error: ErrorWithResolver ⇒ InternalServerError -> error.resolveError
}
}
package io.paytouch.ordering.graphql
import sangria.schema._
object GraphQLSchema {
lazy val Location = ObjectType(
"Location",
"A representation for location",
fields[GraphQLService, Location](
Field("id", StringType, Some("The id of the location."), resolve = _.value.id),
Field("name", OptionType(StringType), Some("The name of the location."), resolve = _.value.name)
)
)
lazy val ID = Argument("id", StringType, description = "id of the location")
lazy val Query: ObjectType[GraphQLService, Unit] = ObjectType(
"Query",
fields[GraphQLService, Unit](
Field("locations", ListType(Location), resolve = ctx => ctx.ctx.getLocations)
)
)
lazy val MySchema = Schema(Query)
}
package io.paytouch.ordering.graphql
import scala.concurrent.{ExecutionContext, Future}
class GraphQLService(implicit ec: ExecutionContext) {
private val locations = List(
Location("1", "Rome"),
Location("2", "London"),
Location("3", "San Francisco"),
Location("4", "New York")
)
def getLocation(id: String): Future[Option[Location]] =
Future.successful(locations.find(_.id == id))
def getLocations: Future[List[Location]] = Future.successful(locations)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment