Edit Page

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, within restheart 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
   }
}
Response
{
  "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
    }
}
Response
{
  "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
      }
    ]
  }
}