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