Edit Page

GraphQL Schema Design for MongoDB

RESTHeart Cloud
Prefer not to run it yourself? RESTHeart Cloud is this, hosted, with sign-up, payments and an MCP server already on. Free to start. Get started →

This guide covers best practices and techniques for designing GraphQL schemas that work efficiently with MongoDB through RESTHeart.

Schema Basics

Your GraphQL schema defines the structure of your API, including:

  • Types and their fields

  • Relationships between types

  • Available queries and mutations

  • Custom scalars and enums

Supported GraphQL Types

RESTHeart supports all standard GraphQL types:

Type Description Example

type

Object type definition

type Book { title: String! }

interface

Shared fields between types

interface Node { id: ID! }

union

Combination of multiple types

union SearchResult = Book | Author

enum

Fixed set of values

enum Category { FICTION, NONFICTION }

input

Complex input arguments

input BookFilter { genre: String }

scalar

Custom scalar types

scalar DateTime

MongoDB Data Types

RESTHeart provides special scalar types for MongoDB:

# MongoDB specific scalars
scalar ObjectId      # MongoDB ObjectId
scalar BsonDocument # Raw BSON document
scalar DateTime     # ISODate and Date objects
scalar Decimal128   # High-precision decimals

Example Usage

type Book {
  _id: ObjectId!
  title: String!
  publishedAt: DateTime
  price: Decimal128
  metadata: BsonDocument
}

Schema Design Patterns

1. Document References

For MongoDB document references:

type Book {
  _id: ObjectId!
  title: String!
  authorId: ObjectId!
  author: Author
}

type Author {
  _id: ObjectId!
  name: String!
  books: [Book]
}

2. Embedded Documents

For MongoDB embedded documents:

type Address {
  street: String!
  city: String!
  country: String!
}

type Customer {
  _id: ObjectId!
  name: String!
  # Embedded document
  address: Address
  # Array of embedded documents
  shippingAddresses: [Address]
}

3. Interfaces for Common Fields

interface Timestamped {
  createdAt: DateTime!
  updatedAt: DateTime!
}

type Book implements Timestamped {
  _id: ObjectId!
  title: String!
  createdAt: DateTime!
  updatedAt: DateTime!
}

type Author implements Timestamped {
  _id: ObjectId!
  name: String!
  createdAt: DateTime!
  updatedAt: DateTime!
}

4. Unions for Polymorphic Queries

type Book {
  _id: ObjectId!
  title: String!
  type: String!
}

type Movie {
  _id: ObjectId!
  title: String!
  duration: Int!
  type: String!
}

union MediaItem = Book | Movie

type Query {
  searchMedia(term: String!): [MediaItem]
}

Query Design

1. Pagination Support

type BookConnection {
  edges: [BookEdge]
  pageInfo: PageInfo!
}

type BookEdge {
  node: Book!
  cursor: String!
}

type PageInfo {
  hasNextPage: Boolean!
  endCursor: String
}

type Query {
  books(first: Int, after: String): BookConnection
}

2. Filtering and Sorting

input BookFilter {
  title: String
  genre: String
  yearPublished: Int
}

enum SortOrder {
  ASC
  DESC
}

input BookSort {
  field: String!
  order: SortOrder!
}

type Query {
  books(
    filter: BookFilter
    sort: BookSort
    limit: Int
    skip: Int
  ): [Book]
}

Best Practices

  1. Use Non-Null Fields Wisely

    • Mark required fields with !

    • Consider optional fields for flexibility

  2. Consistent Naming

    • Use CamelCase for types

    • Use camelCase for fields

    • Be descriptive but concise

  3. Documentation

    • Add descriptions to types and fields

    • Document expected behavior

    • Include examples in comments

"""
Represents a book in the catalog
"""
type Book {
  """
  MongoDB ObjectId of the book
  """
  _id: ObjectId!

  """
  Title of the book
  Must not be empty
  """
  title: String!
}
  1. Schema Evolution

    • Add fields as optional

    • Use interfaces for extensibility

    • Plan for versioning

Schema Validation

RESTHeart automatically validates your schema for:

  1. Syntax Errors

    • Invalid type definitions

    • Incorrect field types

    • Missing required fields

  2. Semantic Errors

    • Invalid references

    • Type conflicts

    • Circular dependencies

  3. MongoDB Compatibility

    • Data type mismatches

    • Invalid field names

    • Unsupported operations

Common Patterns

1. Soft Deletion

interface SoftDelete {
  isDeleted: Boolean!
  deletedAt: DateTime
}

type Book implements SoftDelete {
  _id: ObjectId!
  title: String!
  isDeleted: Boolean!
  deletedAt: DateTime
}

2. Versioning

interface Versioned {
  version: Int!
}

type Book implements Versioned {
  _id: ObjectId!
  title: String!
  version: Int!
  changes: [ChangeLog]
}

type ChangeLog {
  version: Int!
  timestamp: DateTime!
  changes: [String]
}

3. Metadata Support

interface Metadata {
  metadata: BsonDocument
}

type Book implements Metadata {
  _id: ObjectId!
  title: String!
  metadata: BsonDocument
}

Next Steps