Edit Page

Getting Started with GraphQL

🔧 Configuration

Sets localhost:8080 with admin:secret
Values are saved in your browser

This guide will help you quickly set up and create your first GraphQL API with RESTHeart. We’ll cover installation, basic configuration, and creating a simple GraphQL application.

Prerequisites

Before starting, ensure you have:

  • RESTHeart v7.6.4 or later

  • MongoDB 4.2 or later

  • A REST client (like cURL, Postman, or RESTNinja)

Quick Setup

1. Start RESTHeart and MongoDB

The fastest way to get started is using Docker Compose:

$ curl https://raw.githubusercontent.com/SoftInstigate/restheart/master/docker-compose.yml --output docker-compose.yml
$ docker compose up

This starts both RESTHeart and MongoDB with default configuration.

2. Create Required Collections

Create the collection for storing GraphQL app definitions:

curl -i -X PUT "[INSTANCE-URL]/gql-apps" \
  -H "Authorization: [BASIC-AUTH]"
http PUT [INSTANCE-URL]/gql-apps \
  Authorization:[BASIC-AUTH]
fetch('[INSTANCE-URL]/gql-apps', {
  method: 'PUT',
  headers: {
    'Authorization': '[BASIC-AUTH]'
  }
})
.then(response => {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

3. Create Your First GraphQL App

Let’s create a simple book catalog API. First, create a collection for books:

curl -i -X PUT "[INSTANCE-URL]/books" \
  -H "Authorization: [BASIC-AUTH]"
http PUT [INSTANCE-URL]/books \
  Authorization:[BASIC-AUTH]
fetch('[INSTANCE-URL]/books', {
  method: 'PUT',
  headers: {
    'Authorization': '[BASIC-AUTH]'
  }
})
.then(response => {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

Add some sample data:

curl -i -X POST "[INSTANCE-URL]/books" \
  -H "Authorization: [BASIC-AUTH]" \
  -H "Content-Type: application/json" \
  -d '[
    {
        "_id": 1,
        "title": "The GraphQL Guide",
        "author": "Sarah Smith",
        "year": 2023,
        "genres": ["Technical", "Programming"]
    },
    {
        "_id": 2,
        "title": "MongoDB Basics",
        "author": "John Doe",
        "year": 2022,
        "genres": ["Database", "Technical"]
    }
]'
http POST [INSTANCE-URL]/books \
  Authorization:[BASIC-AUTH] \
  Content-Type:application/json \
  _id:=1 \
  title="The GraphQL Guide" \
  author="Sarah Smith" \
  year:=2023 \
  genres:='["Technical", "Programming"]' \
  _id:=2 \
  title="MongoDB Basics" \
  author="John Doe" \
  year:=2022 \
  genres:='["Database", "Technical"]'
const books = [
  {
    "_id": 1,
    "title": "The GraphQL Guide",
    "author": "Sarah Smith",
    "year": 2023,
    "genres": ["Technical", "Programming"]
  },
  {
    "_id": 2,
    "title": "MongoDB Basics",
    "author": "John Doe",
    "year": 2022,
    "genres": ["Database", "Technical"]
  }
];

fetch('[INSTANCE-URL]/books', {
  method: 'POST',
  headers: {
    'Authorization': '[BASIC-AUTH]',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(books)
})
.then(response => {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

Now, create your GraphQL app definition:

curl -i -X POST "[INSTANCE-URL]/gql-apps" \
  -H "Authorization: [BASIC-AUTH]" \
  -H "Content-Type: application/json" \
  -d '{
    "_id": "book-catalog",
    "descriptor": {
        "name": "Book Catalog",
        "description": "A simple book catalog API",
        "enabled": true,
        "uri": "books"
    },
    "schema": "type Book { _id: Int! title: String! author: String! year: Int genres: [String] } type Query { books(year: Int): [Book] booksByGenre(genre: String!): [Book] }",
    "mappings": {
        "Query": {
            "books": {
                "db": "restheart",
                "collection": "books",
                "find": {
                    "year": { "$arg": "year" }
                }
            },
            "booksByGenre": {
                "db": "restheart",
                "collection": "books",
                "find": {
                    "genres": { "$arg": "genre" }
                }
            }
        }
    }
}'
http POST [INSTANCE-URL]/gql-apps \
  Authorization:[BASIC-AUTH] \
  Content-Type:application/json \
  _id="book-catalog" \
  descriptor:='{
    "name": "Book Catalog",
    "description": "A simple book catalog API",
    "enabled": true,
    "uri": "books"
  }' \
  schema="type Book { _id: Int! title: String! author: String! year: Int genres: [String] } type Query { books(year: Int): [Book] booksByGenre(genre: String!): [Book] }" \
  mappings:='{
    "Query": {
      "books": {
        "db": "restheart",
        "collection": "books",
        "find": {
          "year": { "$arg": "year" }
        }
      },
      "booksByGenre": {
        "db": "restheart",
        "collection": "books",
        "find": {
          "genres": { "$arg": "genre" }
        }
      }
    }
  }'
const graphqlApp = {
  "_id": "book-catalog",
  "descriptor": {
    "name": "Book Catalog",
    "description": "A simple book catalog API",
    "enabled": true,
    "uri": "books"
  },
  "schema": "type Book { _id: Int! title: String! author: String! year: Int genres: [String] } type Query { books(year: Int): [Book] booksByGenre(genre: String!): [Book] }",
  "mappings": {
    "Query": {
      "books": {
        "db": "restheart",
        "collection": "books",
        "find": {
          "year": { "$arg": "year" }
        }
      },
      "booksByGenre": {
        "db": "restheart",
        "collection": "books",
        "find": {
          "genres": { "$arg": "genre" }
        }
      }
    }
  }
};

fetch('[INSTANCE-URL]/gql-apps', {
  method: 'POST',
  headers: {
    'Authorization': '[BASIC-AUTH]',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify(graphqlApp)
})
.then(response => {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

Testing Your GraphQL API

1. Query All Books

curl -i -X POST "[INSTANCE-URL]/graphql/books" \
  -H "Authorization: [BASIC-AUTH]" \
  -H "Content-Type: application/graphql" \
  -d '{
    books {
        title
        author
        year
    }
}'
echo '{
    books {
        title
        author
        year
    }
}' | http POST [INSTANCE-URL]/graphql/books \
  Authorization:[BASIC-AUTH] \
  Content-Type:application/graphql
const query = `{
  books {
    title
    author
    year
  }
}`;

fetch('[INSTANCE-URL]/graphql/books', {
  method: 'POST',
  headers: {
    'Authorization': '[BASIC-AUTH]',
    'Content-Type': 'application/graphql'
  },
  body: query
})
.then(response => {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

2. Query Books by Genre

curl -i -X POST "[INSTANCE-URL]/graphql/books" \
  -H "Authorization: [BASIC-AUTH]" \
  -H "Content-Type: application/graphql" \
  -d '{
    booksByGenre(genre: "Technical") {
        title
        author
    }
}'
echo '{
    booksByGenre(genre: "Technical") {
        title
        author
    }
}' | http POST [INSTANCE-URL]/graphql/books \
  Authorization:[BASIC-AUTH] \
  Content-Type:application/graphql
const query = `{
  booksByGenre(genre: "Technical") {
    title
    author
  }
}`;

fetch('[INSTANCE-URL]/graphql/books', {
  method: 'POST',
  headers: {
    'Authorization': '[BASIC-AUTH]',
    'Content-Type': 'application/graphql'
  },
  body: query
})
.then(response => {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
})
.then(data => console.log(data))
.catch(error => console.error('Error:', error));

Understanding the Components

  1. GraphQL App Definition:

    • descriptor: Metadata about your GraphQL API

    • schema: Your GraphQL schema in SDL format

    • mappings: Connects GraphQL types to MongoDB queries

  2. Schema:

    • Defines available types (Book)

    • Specifies queries (books, booksByGenre)

    • Declares field types and requirements

  3. Mappings:

    • Links queries to MongoDB collections

    • Handles query parameters using $arg

    • Supports complex MongoDB queries

Next Steps

Now that you have your first GraphQL API running, you can:

  1. Learn about Schema Design for more complex APIs

  2. Explore MongoDB Mappings for advanced queries

  3. Try the Star Wars Tutorial for a more complex example

  4. Read about Performance Optimization

Need More Examples?

Check out our Complex App Example for a full-featured GraphQL API!