Getting Started with GraphQL
🔧 Configuration
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
-
GraphQL App Definition:
-
descriptor
: Metadata about your GraphQL API -
schema
: Your GraphQL schema in SDL format -
mappings
: Connects GraphQL types to MongoDB queries
-
-
Schema:
-
Defines available types (
Book
) -
Specifies queries (
books
,booksByGenre
) -
Declares field types and requirements
-
-
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:
-
Learn about Schema Design for more complex APIs
-
Explore MongoDB Mappings for advanced queries
-
Try the Star Wars Tutorial for a more complex example
-
Read about Performance Optimization