by Oleg Ilyenko / @easyangel
query MyProduct {
product(id: 123) {
name
description
picture {
width
height
url
}
}
}
{
"data": {
"product": {
"name": "Delicious Cake",
"description": "Just taste it!"
"picture": {
"width": 150,
"height": 150,
"url": "http://..."
}
}
}
}
query MyProduct {
products {
picture(size: 300) {
width, height, url
}
}
}
{
"data": {
"products": [
{
"picture": {
"width": 300,
"height": 300,
"url": "http://..."
}
},
...
]
}
}
query MyProduct {
products {
thumb: picture(size: 100) {
width
}
fullSize: picture(size: 500) {
width
}
}
}
{
"data": {
"products": [
{
"thumb": {
"width": 100
},
"fullSize": {
"width": 500
}
},
...
]
}
}
type Picture {
width: Int!
height: Int!
url: String
}
type Query {
product(id: Int!): Product
products: [Product]
}
interface Identifiable {
id: String!
}
type Product implements Identifiable {
id: String!
name: String!
description: String
picture(size: Int): Picture
}
mutation ChangeStaff {
changeName(productId: 123, newName: "Cheesecake") {
id, version
}
setDescription(productId: 123, description: "Delicious!") {
id, version
}
}
subscription ProductEvents {
nameChanged(productId: 123) { name }
productDeleted { id }
}
{
hero {
id
name
}
}
// Response
{
"data": {
"hero": {
"id": "2001",
"name": "R2-D2"
}
}
}
import sangria.schema._
case class Product(
name: String,
description: Option[String])
val ProductType = ObjectType(
"Product",
"Commodity available for purchase",
fields[Unit, Product](
Field("name", StringType,
resolve = _.value.name),
Field("description", OptionType(StringType),
resolve = _.value.description)
)
)
val QueryType = ObjectType("Query",
fields[ProductRepo, Unit](
Field("product", OptionType(ProductType),
arguments = Argument("id", IntType) :: Nil,
resolve = c =>
c.ctx.getProductById(c.args.arg[Int]("id")))
)
)
val AppSchema = Schema(QueryType)
import sangria.execution.Executor
import sangria.macros._
import sangria.marshalling.playJson._
val query = graphql"""
query MyProduct {
product(id: 123) {
name
description
}
}
"""
val result: Future[JsValue] =
Executor.execute(AppSchema, query, userContext = new ProductRepo)
class Application extends Controller {
def graphql = Action.async(parse.json) { request =>
val query = (request.body \ "query").as[String]
val operation = (request.body \ "operation").asOpt[String]
val variables = (request.body \ "variables").toOption.flatMap {
case obj: JsObject => Some(obj)
case _ => None
}
executeQuery(query, variables, operation)
}
}
def executeQuery(
query: String,
variables: Option[JsObject],
operation: Option[String]) = {
QueryParser.parse(query) match {
case Success(parsedQuery) =>
Executor.execute(AppSchema, parsedQuery,
userContext = new ProductRepo,
operationName = operation,
variables = variables getOrElse Json.obj()) map (Ok(_))
case Failure(error: SyntaxError) =>
// can't parse GraphQL query, return error response
}
}
Sangria Playground: http://try.sangria-graphql.org