Newer
Older
miracle-tv-backend / src / main / scala / graphql / GraphQL.scala
package tv.miracle.backend.graphql

import scala.util.{ Failure, Success }
import sangria.execution.deferred.DeferredResolver
import sangria.execution.{ ErrorWithResolver, Executor, QueryAnalysisError }
import sangria.slowlog.SlowLog
import org.apache.pekko.actor.ActorSystem
import org.apache.pekko.http.scaladsl.Http
import org.apache.pekko.http.scaladsl.model.StatusCodes._
import org.apache.pekko.http.scaladsl.server.Directives._
import org.apache.pekko.http.scaladsl.server._
import sangria.marshalling.circe._

// This is the trait that makes `graphQLPlayground and prepareGraphQLRequest` available
import sangria.http.circe.CirceHttpSupport

import tv.miracle.backend.db.DB
import scala.concurrent.ExecutionContext
import org.apache.pekko.http.scaladsl.marshalling.ToResponseMarshallable
import io.getquill.PostgresJdbcContext
import io.getquill.SnakeCase
import io.getquill._

case class Test(name: String, sexy: Option[Boolean])
case class RejectionError(message: String)

object GraphQL extends App with CirceHttpSupport with CorsSupport {
  def main = () => {}
  def handleGraphQL()(implicit ec: ExecutionContext, ctx: PostgresJdbcContext[SnakeCase]): Route = {
    optionalHeaderValueByName { "X-Apollo-Tracing" } { (tracing) =>
      graphQLPlayground ~
        prepareGraphQLRequest {
          case Success(req) =>
            import ctx._
            val users = run(query[Test])
            println(users)
            val middleware = if (tracing.isDefined) SlowLog.apolloTracing :: Nil else Nil
            val deferredResolver = DeferredResolver.fetchers(SchemaDefinition.characters)
            val res = Executor.execute(
              schema = SchemaDefinition.StarWarsSchema,
              queryAst = req.query,
              userContext = new CharacterRepo,
              variables = req.variables,
              operationName = req.operationName,
              middleware = middleware,
              deferredResolver = deferredResolver)
              .map(OK -> _)
              .recover {
                case error: QueryAnalysisError => BadRequest -> {
                  println(error.resolveError)
                  error.resolveError
                }
                case error: ErrorWithResolver => InternalServerError -> {
                  println(error.resolveError)
                  error.resolveError
                }
              }
            complete(res)
          case Failure(preparationError) => complete(BadRequest, formatError(preparationError))
        }
    }
  }
}