Last active
September 22, 2018 05:38
-
-
Save anotherhale/e02da8e48b2827b5139d5bacbfc2ab53 to your computer and use it in GitHub Desktop.
Attempt to create Sangria API without derived types to experiment with interfacing with POJOs instead of Scala case classes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Author.java | |
class Author { | |
private String name; | |
private int publishedBooks; | |
Author(String _name , int _publishedBooks) { | |
name = _name | |
publishedBooks = _publishedBooks | |
} | |
String getName() {return name;} | |
void setName(String _name){ this.name = _name; } | |
int getPublishedBooks() {return publishedBooks;} | |
void setPublishedBooks(int _publishedBooks) {this.publishedBooks = _publishedBooks;} | |
} | |
// Book.java | |
class Book { | |
private String title; | |
private java.util.List<Author> authors; | |
Book(String _title , java.util.List<Author> _authors) { | |
title = _title | |
authors = _authors | |
} | |
String getTitle() {return title;} | |
void setTitle(String _title){ this.title = _title; } | |
java.util.List<Author> getAuthors() {return authors;} | |
void setAuthors(java.util.List<Author> _authors) {this.authors = _authors;} | |
} | |
// Schema.scala | |
import sangria.schema._ | |
import sangria.execution._ | |
import sangria.macros._ | |
import sangria.macros.derive._ | |
import sangria.marshalling.circe._ | |
import enumeratum._ | |
import io.circe.generic.auto._ | |
import io.circe.Json | |
import io.circe.syntax._ | |
import scala.collection.JavaConverters | |
import scala.concurrent.ExecutionContext.Implicits.global | |
object SchemaDefinition { | |
class Repo { | |
private var storedBook: Option[Book] = None | |
def saveBook(book: Book): Unit = { | |
storedBook = Some(book) | |
} | |
def loadBook(): Option[Book] = storedBook | |
} | |
implicit val decodeAuthor: Decoder[Author] = new Decoder[Author] { | |
final def apply(c: HCursor): Decoder.Result[Author] = | |
for { | |
name <- c.downField("name").as[String] | |
publishedBooks <- c.downField("publishedBooks").as[Int] | |
} yield { | |
new Author(name, publishedBooks) | |
} | |
} | |
implicit val encodeBook: Encoder[Book] = new Encoder[Book] { | |
final def apply(b: Book): Json = Json.obj( | |
("title", Json.fromString(b.getTitle)), | |
("authors", Json.fromValues(JavaConverters.asScalaIteratorConverter(b.getAuthors.iterator()).asScala.toSeq.map(a=>encodeAuthor(a)))) | |
) | |
} | |
implicit val decodeBook: Decoder[Book] = new Decoder[Book] { | |
final def apply(c: HCursor): Decoder.Result[Book] = | |
for { | |
title <- c.downField("title").as[String] | |
authors <- c.downField("authors").as[Seq[Author]] | |
} yield { | |
new Book(title, JavaConverters.seqAsJavaList(authors)) | |
} | |
} | |
implicit val AuthorInputType = InputObjectType[Author]("AuthorInput", List( | |
InputField("name", StringType), | |
InputField("publishedBooks", IntType, defaultValue = 0))) | |
implicit lazy val BookInputType = InputObjectType[Book]("BookInput", List( | |
InputField("title", StringType), | |
InputField("authors", ListInputType(AuthorInputType)) | |
)) | |
// Output objects | |
implicit lazy val BookType = ObjectType("Book", fields[Repo, Book]( | |
Field("title", StringType, | |
resolve = _.value.getTitle), | |
Field("authors", ListType(AuthorType), | |
resolve = book => JavaConverters.asScalaIteratorConverter(book.value.getAuthors.iterator()).asScala.toSeq | |
))) | |
implicit val AuthorType = ObjectType("Author", fields[Repo, Author]( | |
Field("name", StringType, | |
resolve = _.value.getName), | |
Field("publishedBooks", IntType, | |
resolve = _.value.getPublishedBooks) | |
)) | |
// Schema definition | |
val BookArg = Argument("book", BookInputType) | |
val QueryType = ObjectType("Query", fields[Repo, Unit]( | |
Field("book", OptionType(BookType), resolve = _.ctx.loadBook()))) | |
val MutationType = ObjectType("Mutation", fields[Repo, Unit]( | |
Field("saveBook", OptionType(BookType), | |
arguments = BookArg :: Nil, | |
resolve = c ⇒ { | |
val book = c arg BookArg | |
c.ctx.saveBook(book) | |
book | |
}))) | |
val schema = Schema(QueryType, Some(MutationType)) | |
// Test query | |
val query = | |
gql""" | |
mutation { | |
saveBook(book: {title: "Sapiens", authors: [{name: "Yuval Noah Harari", publishedBooks: 6}]}) { | |
title | |
authors { | |
name | |
publishedBooks | |
} | |
} | |
} | |
""" | |
val context = new Repo | |
val result = Executor.execute(schema, query, context) | |
result.foreach(res ⇒ println(res.spaces2)) | |
// [info] Compiling 4 Scala sources and 2 Java sources to target\scala-2.12\classes ... | |
// [error] src\main\scala\SchemaDefinition.scala:32:34: type mismatch; | |
// [error] found : sangria.schema.InputObjectType[Author] | |
// [error] required: sangria.schema.OutputType[?] | |
// [error] Note: implicit lazy value BookInputType is not applicable here because it comes after the application point and it lacks an explicit result type | |
// [error] InputField("authors", ListType(AuthorInputType)))) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment