A Complex GraphQL App
Before running the tutorial
This tutorial assume:
-
RESTHeart Platform running on the localhost with the default configuration: the database restheart is bound to
/
, the user admin exists with default password secret, gql-apps is the collection, withinrestheart
database, reserved to GraphQL apps definitions and the GraphQL service is reachable at/graphql
. -
The
sample-mflix
database (see Load Sample Data into MongoDB) is stored in the MongoDB instance associated to RESTHeart.
Note
|
Execute on rest ninja doesn’t work with Safari because it requires HTTPS. Since configuring HTTPS requires a valid certificate and takes some time to configure, we suggest to just use Chrome or Firefox for this tutorial. |
Create the GraphQL app
To create the gql-apps collection, run the following:
PUT /gql-apps HTTP/1.1
To upload the example GraphQL app definition, run the following:
POST /gql-apps HTTP/1.1
Request body
{
"_id": "mflix-gql-def",
"descriptor": {
"name":"MFlix",
"description":"GraphQL App example using MongoDB sample_mflix dataset",
"enabled": true,
"uri":"mflix"
},
"schema": "type Stats { year: Int moviesNum: Int } type Comment{ _id: ObjectId user: User movie: Movie text: String date: DateTime}type Movie{ _id: ObjectId title: String year: Int runtime: Int released: DateTime poster: String plot: String fullPlot: String lastUpdate: String filmType: String directors: [String] imdbRate: Float imdbVotes: Int countries: [String] genres: [String] tomatoesRate: Float tomatoesReviewsNum: Int comments(startDate: DateTime = \"-9223372036854775808\", endDate: DateTime = \"9223372036854775807\", sort: Int = 1, skip: Int = 0, limit: Int = 0): [Comment] relatedMovies: [Movie]}type Session{ _id: ObjectId user: User jwt: String} type Theater{ theaterId: Int location: BsonDocument} type User{ _id: ObjectId name: String email: String comments(startDate: DateTime = \"-9223372036854775808\", endDate: DateTime = \"9223372036854775807\", sort: Int = 1, skip: Int = 0, limit: Int = 0): [Comment]}type Query{ MoviesByTitle(title: String!): [Movie] MoviesByYear(year: Int!, sort: Int = 1, skip: Int = 0, limit: Int = 0): [Movie] UserByEmail(email: String!): [User] StatsByTomatoesRateRange(min: Float max: Float = 10): [Stats] MoviesByTomatoesRateRange(min: Float, max: Float, sort: Int = 1, skip: Int = 0, limit: Int = 0):[Movie] TheatersByCity(city: String!, sort: Int = 1, skip: Int = 0, limit: Int = 0): [Theater] AllMovies(limit: Int = 10, skip: Int = 0): [Movie]}",
"mappings": {
"Comment": {
"user": {
"db":"sample_mflix",
"collection":"users",
"find": { "email": { "$fk":"email" } },
"dataLoader": { "batching": true, "caching": true }
},
"movie": {
"db":"sample_mflix",
"collection":"movies",
"find": { "_id": { "$fk":"movie_id" } },
"dataLoader": { "batching": true, "caching": false, "maxBatchSize": 30 }
}
},
"Movie": {
"imdbRate":"imdb.rating",
"imdbVotes":"imdb.votes",
"tomatoesRate":"tomatoes.viewer.rating",
"tomatoesReviewsNum":"tomatoes.viewer.numReviews",
"lastUpdate":"lastupdated",
"fullPlot":"fullplot",
"filmType":"type",
"comments": {
"db":"sample_mflix",
"collection":"comments",
"find": { "$and": [{ "movie_id": { "$fk":"_id" } }, { "date": { "$gte": { "$arg":"startDate" }, "$lt": { "$arg":"endDate" } } }] },
"sort": { "date": { "$arg":"sort" } },
"skip": { "$arg":"skip" },
"limit": { "$arg":"limit" }
}
},
"Session": {
"user": {
"db":"sample_mflix",
"collection":"user",
"find": { "email": { "$fk":"user_id" } }
}
},
"User": {
"comments": {
"db":"sample_mflix",
"collection":"comments",
"find": { "email": { "$fk":"email" } },
"sort": { "_id": { "$arg":"sort" } },
"skip": { "$arg":"skip" },
"limit": { "$arg":"limit" }
}
},
"Query": {
"StatsByTomatoesRateRange": {
"db": "sample_mflix",
"collection": "movies",
"stages": [
{ "$match": { "imdb.rating": { "$gte": { "$arg":"min" }, "$lte": { "$arg":"max" } }, "year": { "$type": "int" } } },
{ "$group": { "_id": "$year", "moviesNum": { "$count": {} } } },
{ "$project": { "_id": 0, "year": "$_id", "moviesNum": 1} },
{ "$sort": { "year": 1 } }
]
},
"MoviesByTitle": {
"db":"sample_mflix",
"collection":"movies",
"find": { "title": { "$arg":"title" } }
},
"MoviesByYear": {
"db":"sample_mflix",
"collection":"movies",
"find": { "year": { "$arg":"year" } },
"sort": { "_id": { "$arg":"sort" } },
"skip": { "$arg":"skip" },
"limit": { "$arg":"limit" }
},
"UserByEmail": {
"db":"sample_mflix",
"collection":"users",
"find": { "email": { "$arg":"email" } }
},
"MoviesByTomatoesRateRange": {
"db":"sample_mflix",
"collection":"movies",
"find": { "tomatoes.viewer.rating": { "$gte": { "$arg":"min" }, "$lt": { "$arg":"max" } } },
"sort": { "tomatoes.viewer.rating": { "$arg":"sort" }, "_id": 1 },
"skip": { "$arg":"skip" },
"limit": { "$arg":"limit" }
},
"TheatersByCity": {
"db":"sample_mflix",
"collection":"theaters",
"find": { "location.address.city": { "$arg":"city" } },
"sort": { "location.address.city": { "$arg":"sort" } },
"skip": { "$arg":"skip" },
"limit": { "$arg":"limit" }
},
"AllMovies": {
"db":"sample_mflix",
"collection":"movies",
"find": { },
"sort": { "_id_": -1 },
"skip": { "$arg":"skip" },
"limit": { "$arg":"limit" }
}
}
}
}
query with application/json
To execute a GraphQL request to Mflix app with Content-Type application/json
, run the following:
POST /graphql/mflix HTTP/1.1
Request body
{
"query":"query exampleOperation($year: Int!, $limit: Int = 0){MoviesByYear(year: $year, limit: $limit){ title comments{ text user{name} date} tomatoesRate}}",
"variables":{
"year":2008,
"limit":2
}
}
{
"data": {
"MoviesByYear": [
{
"title": "The Bank Job",
"comments": [
{
"text": "Pariatur voluptatibus placeat quo architecto soluta non...",
"user": {
"name": "Shireen Baratheon"
},
"date": {
"$date": 954044557000
}
},
{
"text": "Facilis ea voluptatem et velit rerum animi corrupti...",
"user": {
"name": "Lisa Russo"
},
"date": {
"$date": 976465077000
}
}
],
"tomatoesRate": 3.5
},
{
"title": "The Flyboys",
"comments": [],
"tomatoesRate": 3.6
}
]
}
}
query with application/graphql
To execute a GraphQL request to Mflix app with Content-Type application/graphql
, run the following:
POST /graphql/mflix HTTP/1.1
Request body
{
MoviesByTomatoesRateRange(min: 3.8, max: 4.5, limit: 3, skip: 20, sort: -1){
title
comments {
text
user { name }
}
tomatoesRate
}
}
{
"data": {
"MoviesByTomatoesRateRange": [
{
"title": "The Wages of Fear",
"comments": [
{
"text": "Commodi accusamus totam eaque sunt. Nihil reiciendis commodi molestiae esse...",
"user": {
"name": "Doreah"
}
}
],
"tomatoesRate": 4.4
},
{
"title": "Chicago Deadline",
"comments": [
{
"text": "Nihil itaque a architecto. Illo veritatis totam at quibusdam. Doloremque...",
"user": {
"name": "Patricia Good"
}
}
],
"tomatoesRate": 4.4
},
{
"title": "The Passion of Joan of Arc",
"comments": [],
"tomatoesRate": 4.4
}
]
}
}