Testing phaseThis environment is in pre-launch testing — all data will be reset at launch.
Skip to content

Runtime ​

Runtime validation confirms whether domain and API decisions behave as expected under real query usage. It is the layer where your model goes from design to execution — and where you catch issues before your consumers do.

Runtime Purpose ​

The runtime answers practical questions early in your development process:

  • Are field shapes predictable and consistent?
  • Are relation lookups coherent and correctly nested?
  • Do pagination and sorting assumptions hold on the imported data?
  • Do filter expressions match the correct subset of records?
  • Are null values handled the way your consumers expect?

By validating these behaviors during modeling — not after implementation — you eliminate an entire category of integration bugs.

Screenshot rt-01-query-playgroundScreenshot rt-01-query-playground
rt-01-query-playgroundMissing

Runtime query panel for live behavior checks.

How the Mock Runtime Works ​

The mock runtime engine is the core of Mockomat. It accepts GraphQL queries and translates them into MongoDB operations through a four-stage pipeline:

1. GraphQL Request Parser ​

The incoming query string is parsed into an abstract syntax tree (AST). This stage validates query syntax and extracts the requested fields, arguments, and nested selections.

2. Query Planner ​

The AST is analyzed alongside your model metadata (entity definitions, attribute flags, relation configurations) to create an execution plan. The planner determines:

  • Which MongoDB collections to query
  • Which fields to project
  • What filter and sort operations to apply
  • Which relations need to be resolved

3. MongoDB Query Builder ​

The execution plan is translated into a MongoDB aggregation pipeline. Because MongoDB stores data in flat (denormalized) collections, the query builder simulates relational structure:

  • Lookup stages assemble related data across collections
  • Match stages apply filter expressions
  • Sort stages order results by the requested fields
  • Skip and limit stages handle pagination

4. Result Assembler ​

The raw MongoDB results are reshaped to match the expected GraphQL response structure. Nested relations are assembled into the correct parent-child hierarchy, and field names are mapped to their GraphQL equivalents.

This pipeline runs on every query. What you see in the preview is exactly what external consumers receive from the same endpoint.

Screenshot rt-01b-runtime-pipelineScreenshot rt-01b-runtime-pipeline
rt-01b-runtime-pipelineMissing

Four-stage runtime pipeline: parse → plan → build → assemble.

Query Examples ​

All queries go to the same endpoint, with an API key of the project (guest projects use their share token — see Integrators):

text
POST /mock/{slug}/graphql
Authorization: Bearer mck_your_api_key

The root field is the name of an operation from API design. A list query selects its records inside items and can add total, page and pageSize; a detail query selects the fields directly. The response carries every mapped attribute of the table and its relations — the selection set does not narrow it.

List Query ​

Fetch a paginated collection of records:

graphql
query {
  products(page: 1, pageSize: 20) {
    items {
      id
      name
      price
      category {
        id
        name
      }
    }
    total
    page
    pageSize
  }
}

Detail Query ​

Fetch a single record by its identifier:

graphql
query {
  product(id: "abc-123") {
    id
    name
    price
    description
    category {
      id
      name
    }
  }
}

Query with Filtering ​

Pass the parameters the operation defines in API design — here minPrice (on price, gte) and maxPrice (on price, lte):

graphql
query {
  products(minPrice: 10, maxPrice: 50, pageSize: 10) {
    items {
      id
      name
      price
    }
    total
  }
}

Query with Sorting ​

Order results with sortField (an attribute name) and sortDirection:

graphql
query {
  products(sortField: "price", sortDirection: DESC, pageSize: 10) {
    items {
      id
      name
      price
    }
    total
  }
}

Query with Nested Relations ​

Relations of the table come back nested, one level deep:

graphql
query {
  customers(pageSize: 5) {
    items {
      id
      firstName
      lastName
      orders {
        id
        totalAmount
        createdAt
      }
    }
    total
  }
}

Filtering in Detail ​

Filters belong to the operation: you define them in API design and the runtime applies them on every request. Scope filters are fixed conditions of the operation; parameters are arguments the caller sends — each bound to one attribute and one operator, optionally required or with a default value.

Available Operators ​

OperatorDescriptionWorks With
eqEqualsAll types
neqNot equalsAll types
gt / gteGreater than / greater or equalNumbers, Dates
lt / lteLess than / less or equalNumbers, Dates
inOne of a list of valuesAll types
likeContains (case-insensitive)Strings
notInNone of a list of values (scope filters only)All types
isNull / isNotNullIs null / is not null (scope filters only)All types

Combining Filters ​

All scope filters and parameters of an operation combine with AND — there is no OR and no nesting at request time. Pass parameter values inline or as GraphQL variables:

graphql
query ProductsInRange($min: Float, $max: Float) {
  products(minPrice: $min, maxPrice: $max, pageSize: 20) {
    items {
      id
      name
      price
    }
    total
  }
}

With the variables { "min": 10, "max": 50 }, this returns the products priced from 10 to 50.

Parameter Validation ​

An argument the operation does not define is refused with BAD_USER_INPUT, and so is a required parameter that is missing and has no default value. Operations without parameters ignore unknown arguments. Define parameters in the API Design view.

searchTerm matches case-insensitively in every attribute marked searchable (up to 64 characters):

graphql
query {
  products(searchTerm: "oak", pageSize: 10) {
    items {
      id
      name
    }
    total
  }
}

Pagination ​

Mockomat uses page-based pagination:

ParameterDescriptionDefault
pagePage number, starting at 11
pageSizeRecords per page, at most 100The operation's default page size (25 unless changed)

A typical paginated request:

graphql
query {
  products(page: 3, pageSize: 20) {
    items {
      id
      name
      price
    }
    total
    page
    pageSize
  }
}

This returns records 41–60. total counts every matching record, so the last page is total / pageSize, rounded up.

Sorting ​

Sort with sortField (an attribute name) and sortDirection:

DirectionMeaning
ASCAscending (A→Z, 0→9, oldest→newest)
DESCDescending (Z→A, 9→0, newest→oldest)

Only one sort field can be applied per query. Without sortField, the operation's default sort applies; if it has none, results come in storage order.

Relation Traversal ​

One of the runtime's most powerful features is its ability to simulate relational data from flat MongoDB collections.

How It Works ​

MongoDB stores data in denormalized collections — each record is a flat document without foreign key joins. The runtime simulates relational structure by:

  1. Reading the relation definition from your model (source entity, target entity, cardinality).
  2. Building lookup stages in the MongoDB aggregation pipeline that join related collections.
  3. Assembling nested results that match the GraphQL response shape.

This means your GraphQL queries behave as if they are running against a fully relational database, even though the underlying storage is document-based.

What to Validate ​

When testing relation traversal:

  • 1:1 relations should return a single nested object (or null if no match).
  • 1:n relations should return an array of nested objects.
  • Empty relations should return an empty array [], not null.
  • Nested relations resolve one level deep: a related record carries its own attributes, not its relations (Customer → Order works; the order's items are not included). Each parent gets at most 50 related records.

Query Behavior Checklist ​

For each key entity in your model, validate:

  • List query stability — does the same query return consistent structure across repeated calls?
  • Single-item consistency — does a detail query return all expected fields?
  • Null and missing-field behavior — are optional fields correctly represented as null?
  • Relation traversal — do nested objects resolve with the correct cardinality?
  • Filter accuracy — do filter expressions match the expected subset?
  • Sort correctness — does sorting produce a predictable, stable order?
  • Pagination boundaries — do page and pageSize produce clean page slices without duplicates?
Screenshot rt-02-filter-sort-paginationScreenshot rt-02-filter-sort-pagination
rt-02-filter-sort-paginationMissing

Filter, sort, and pagination behavior validation.

Runtime Inspection and Debugging ​

When behavior looks wrong, inspect in this order. For a comprehensive diagnostic guide covering all common issues and their resolutions, see the Troubleshooting reference.

1. Check Table and Attribute Definitions ​

The most common cause of unexpected behavior is a misconfigured attribute:

  • Is the field type correct? (A price stored as string won't sort numerically.)
  • For search: is the field marked as Searchable?
  • For sorting: is sortField the name of an attribute bound to a data column?
  • Does the field have a mapping configured?

2. Check Endpoint and Query Metadata ​

Verify that the query is configured correctly in the API design view:

  • Is the query enabled?
  • Are the query name and parameters correct?
  • Is the pagination configuration appropriate?

3. Check Source Mapping State ​

If fields return null or unexpected values:

  • Is the mapping type correct (Data Source or Constant)?
  • For Data Source mappings, is the attribute bound to the right column of the imported data, and does that column hold values for these records?
  • Constant values appear on every row, on rows of imported data and on rows composed from value pools alike.
  • Computed mappings: the runtime does not evaluate expressions, so a computed field is not part of the response.

4. Check Relation Policies ​

If nested data is missing or incorrect:

  • Is the relation direction correct (source → target)?
  • Is the cardinality right (1:1 vs 1:n)?
  • Does the target entity exist and have mapped data?
  • Are the linking columns correctly specified?

Common Issues and Resolutions ​

SymptomLikely CauseResolution
Empty responseThe table is not bound to imported data (NOT_READY)Bind the table to imported data in the Mappings pane
Fields return nullNo mapping configuredBind the attribute to a column of the imported data (Data Source mapping)
Nested relation emptyRelation misconfiguredVerify direction, target entity, and linking columns
Sort not workingsortField is not the name of a mapped attributeUse the name of a mapped attribute
Filter returns everythingThe operation defines no parameter for that argumentAdd the parameter in API design
Wrong data typesMapping type mismatchCheck that mapping produces the expected type
Pagination skips itemspageSize changed between requestsKeep pageSize constant and step page by 1
Screenshot rt-03-runtime-inspectionScreenshot rt-03-runtime-inspection
rt-03-runtime-inspectionMissing

Runtime inspection flow and debug checkpoints.

Validation Before Export ​

Runtime should confirm readiness before you move to backend code generation. A model that passes runtime validation is far more likely to produce a clean, functional generated backend.

Readiness Criteria ​

Before exporting, confirm that:

  • Required fields are stable — all required attributes have consistent, non-null values.
  • Operation surface is intentional — only the queries you want to expose are enabled.
  • Relation behavior is explainable — every nested query resolves correctly and the cardinality matches your business rules.
  • Filter and sort behavior is predictable — consumers can rely on these operations working as documented.
  • No unresolved hints — the preview shows no warnings about unmapped attributes or missing configuration.

Pre-Export Validation Workflow ​

  1. Run list queries for every entity — check structure and data quality.
  2. Run detail queries for key entities — check field completeness.
  3. Test all configured filters — verify correct subsetting.
  4. Test sorting on the attributes your consumers sort by — verify ordering.
  5. Test pagination boundaries — verify clean page transitions.
  6. Test nested relation queries — verify correct assembly at every level.
Screenshot rt-04-runtime-validationScreenshot rt-04-runtime-validation
rt-04-runtime-validationMissing

Pre-export runtime validation summary view.