From b7e3e66b8275389d257965fc2320089b0670ddbb Mon Sep 17 00:00:00 2001 From: Nepomuk Seiler Date: Sat, 2 Jun 2018 18:49:51 +0200 Subject: [PATCH] Extend test project schema with custom scalar type #26 --- .../main/scala/example/ProductSchema.scala | 45 +++++++++++++++++-- 1 file changed, 42 insertions(+), 3 deletions(-) diff --git a/test-project/server/src/main/scala/example/ProductSchema.scala b/test-project/server/src/main/scala/example/ProductSchema.scala index 1f1dcb9..d270b5b 100644 --- a/test-project/server/src/main/scala/example/ProductSchema.scala +++ b/test-project/server/src/main/scala/example/ProductSchema.scala @@ -1,9 +1,16 @@ package example +import java.time._ +import java.time.format.DateTimeFormatter + import sangria._ +import sangria.marshalling._ +import sangria.validation._ import sangria.schema._ import sangria.macros.derive._ +import scala.util._ + // From the Sangria getting started guide // http://sangria-graphql.org/getting-started/ @@ -11,14 +18,43 @@ trait Identifiable { def id: String } -case class Picture(width: Int, height: Int, url: Option[String]) +case class Picture(width: Int, height: Int, url: Option[String], createdAt: LocalDateTime) case class Product(id: String, name: String, description: String) extends Identifiable { def picture(size: Int): Picture = - Picture(width = size, height = size, url = Some(s"//cdn.com/$size/$id.jpg")) + Picture(width = size, height = size, url = Some(s"//cdn.com/$size/$id.jpg"), createdAt = LocalDateTime.now()) +} + + +object LocalDateTimeScalar { + + case object LocalDateTimeCoercionViolation extends ValueCoercionViolation("LocalDateTime value expected") + + private def parseDate(s: String) = Try(LocalDateTime.parse(s)) match { + case Success(date) ⇒ Right(date) + case Failure(_) ⇒ Left(LocalDateTimeCoercionViolation) + } + + val LocalDateTimeType = ScalarType[LocalDateTime]("LocalDateTime", + coerceOutput = (localDateTime, caps) => + if (caps.contains(DateSupport)) localDateTime.toLocalDate + else DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(localDateTime), + coerceUserInput = { + case s: String ⇒ parseDate(s) + case _ => Left(LocalDateTimeCoercionViolation) + }, + coerceInput = { + case ast.StringValue(s, _, _) ⇒ parseDate(s) + case _ => Left(LocalDateTimeCoercionViolation) + }) + } + object ProductSchema { + import LocalDateTimeScalar._ + + implicit val PictureType = ObjectType( "Picture", "The product picture", @@ -55,7 +91,10 @@ object ProductSchema { description = Some("Returns a list of all available products."), resolve = _.ctx.products))) - val schema = Schema(QueryType) + val schema = Schema( + query = QueryType, + additionalTypes = List(LocalDateTimeType) + ) }