Tables & Attributes
Tables and attributes are the foundational building blocks of every Mockomat project. A table represents a domain entity — a discrete business concept such as Customer, Order, or Product. Each table contains a set of attributes that define the fields exposed through the generated GraphQL API. Every decision you make at the table and attribute level propagates directly into schema generation, query behavior, and runtime data resolution.
This page covers table creation and configuration, attribute properties and their effects on the API, naming conventions, data source mapping, and the causal chain from attribute flags to runtime query behavior.


Modelling board showing multiple table cards with attributes listed inside each card.
Tables as Domain Entities
A table in Mockomat is not a database table in the traditional sense. It is a domain entity declaration — a statement that a concept exists in your data model and should be queryable through the API. When you create a table called Customer, you are telling Mockomat that your mock API should be able to serve customer data, accept queries filtered by customer attributes, and resolve relations from customers to other entities.
Tables are displayed as cards on the modelling board. Each card shows the table name, its icon and color, and a compact list of its attributes. Relations between tables appear as visual lines connecting the cards.
What a Table Contains
Every table has two layers of configuration:
- Table-level properties — metadata about the entity itself (name, description, visual identifiers).
- Attribute list — the fields that belong to this entity, each with its own type, flags, and data mapping.
Both layers work together to define how the entity appears in the GraphQL schema and how queries against it behave at runtime.
Table Properties
| Property | Description | Notes |
|---|---|---|
| Name | The entity identifier | Use singular PascalCase nouns that match business language |
| Description | Optional free-text explanation | Valuable for team communication and onboarding |
| Icon | Visual identifier on the board | Choose icons that reflect the domain concept |
| Color | Visual grouping indicator | Use color to group related entities visually |
| Slug | Auto-generated internal identifier | Derived from the name; used internally by the platform |
Naming Tables
Table names should be singular PascalCase nouns that match the language your business domain uses. A table representing customers should be named Customer, not customers, customers_table, or tbl_customer. This convention ensures that generated GraphQL query names are natural and predictable — a table named Customer produces queries like customers (list) and customer (detail).
Avoid generic names like Data, Item, or Record. Prefer specific domain terms: Invoice, ShippingAddress, ProductCategory. When an entity represents a join concept, use a compound name that conveys meaning: OrderItem rather than OrderProduct or OrderProductLink.
Description
The description field is optional but strongly recommended. It serves as inline documentation for anyone reviewing the model. A good description answers the question: What does this entity represent in the business domain, and what role does it play in the data model?
Creating and Managing Tables
Creating a Table
Tables can be created from two locations:
- The modelling board — use the add button on the board toolbar to create a new table card. The card appears on the canvas and can be positioned immediately.
- The records page — use the create action to add a new table entry. The table appears in the list and becomes available on the board.
In both cases, you provide a name and optionally a description. Attributes can be added immediately or configured later.


Creating a new table from the modelling board toolbar.
Table Operations
| Operation | Description |
|---|---|
| Rename | Change the table name. The slug updates accordingly. Query names derived from the table name also update. |
| Duplicate | Create a copy of the table with all its attributes. The copy receives a new name and slug. Relations are not duplicated. |
| Delete | Remove the table and all its attributes. Relations referencing this table are also removed. This action is irreversible. |
Table Limits
There is no limit on the number of tables within a single project. You can model as many entities as your domain requires. Plan restrictions apply at the project level (how many projects you can create), not at the table level.
Attribute Configuration
Attributes define the fields of a table. Each attribute corresponds to a field in the generated GraphQL type and determines what data consumers can query, sort, filter, and search.
Attribute Properties
| Property | Description | Impact on API |
|---|---|---|
| Name | Field identifier (camelCase) | Becomes the GraphQL field name |
| Type | string, number, boolean, date, json | Determines filter operators and validation rules |
| Required | Whether the field must have a value | Affects GraphQL nullability (! suffix on the type) |
| Sortable | Whether the field supports sort operations | Enables the sort parameter for this field in queries |
| Searchable | Whether the field participates in search | Field is included when search queries are resolved |
| Filterable | Whether the field supports filter expressions | Enables the filter parameter for this field in queries |
| Mapping | Data source: OFF_FIELD, FAKE, or CONST | Determines what data values the field returns at runtime |


Attribute configuration panel showing all property fields for a selected attribute.
Adding and Ordering Attributes
Attributes are added through the table editor panel. Each new attribute requires at minimum a name and a type. The remaining properties default to sensible values (not required, not sortable, not searchable, not filterable, mapping set to OFF_FIELD).
You can reorder attributes within a table. The order determines the default column sequence in views and the field order in the generated GraphQL type.
Attribute Types in Detail
The attribute type determines which filter operators are valid, how values are validated, and how the field behaves in queries.
string
Text values of arbitrary length. Supports the following filter operators:
EQ— exact matchNEQ— not equalLIKE— pattern match (contains)IN— value in list
Use for names, descriptions, codes, identifiers, and any free-text content.
number
Numeric values (integers and decimals). Supports range and equality filters:
EQ,NEQ— equalityGT,GE— greater than, greater than or equalLT,LE— less than, less than or equalIN— value in list
Use for prices, quantities, scores, counts, and any measurable value.
boolean
True/false values. Supports:
EQ— exact match
Use for flags and toggles: isActive, isVerified, hasDiscount.
date
ISO 8601 date or datetime values. Supports the same range operators as number:
EQ,NEQ— equalityGT,GE— after, on or afterLT,LE— before, on or before
Use for timestamps, deadlines, creation dates, and scheduling fields.
json
Structured JSON data stored as a nested object or array. Filter support is limited — JSON fields are primarily useful for returning complex nested structures that do not need to be individually filtered or sorted.
Use for metadata blobs, configuration objects, or nested structures that you want to return as-is.
Naming Conventions
Consistent naming across tables and attributes makes your model readable and ensures that generated code is predictable.
| Element | Convention | Examples |
|---|---|---|
| Table names | PascalCase, singular | Customer, OrderItem, ProductCategory |
| Attribute names | camelCase | firstName, totalAmount, isActive, createdAt |
| Boolean attributes | Prefix with is, has, or can | isActive, hasDiscount, canEdit |
| Date attributes | Suffix with At, Date, or On | createdAt, expiryDate, shippedOn |
| Foreign key hints | Suffix with Id | customerId, categoryId |
Avoid abbreviations. Write description instead of desc, quantity instead of qty, address instead of addr. Abbreviations save a few characters but cost clarity for every person who reads the model afterward.
Data Source Mapping
Every attribute needs a data source — the mechanism that determines what values the field returns at runtime. Mockomat supports three mapping types.
OFF_FIELD — Real Dataset Mapping
Maps the attribute to a field from an imported data object. This is the primary mapping type for producing realistic mock data. When you select OFF_FIELD, a side panel opens where you can search and select a data object.
The data object selector provides:
- Search by name or tag — find relevant data objects quickly
- Tag filters — narrow results by category (e.g., personal, financial, geographic)
- Sample preview — inspect example values before committing to a mapping
This preview step is important. It lets you verify that the data object produces values consistent with what the attribute represents. A firstName attribute should map to a data object that returns realistic first names, not random strings.


Data object selection panel with search, tag filters, and sample value preview.
For a comprehensive guide to data sources, see Data Sources.
FAKE — Generated Fake Data
Produces procedurally generated values based on the attribute type. Useful when no suitable real dataset exists or when placeholder data is sufficient. The generated values respect the attribute type (strings produce text, numbers produce numeric values, dates produce valid timestamps).
CONST — Constant Value
Returns a fixed value for every record. Useful for default fields, status codes, or any attribute that should have the same value across all records in the table.
Causality: Attribute Flags to Schema to Query Behavior
Understanding the causal chain from attribute configuration to runtime behavior is essential for effective modelling. Each attribute flag you set has a direct, predictable consequence in the generated GraphQL schema and the query capabilities available to API consumers.
Flag Effects
| Flag | Schema Effect | Query Behavior |
|---|---|---|
required: true | Field type gets non-null modifier (String!) | Every record is guaranteed to have this value |
sortable: true | Field is registered in the sort parameter enum | Consumers can sort results by this field |
filterable: true | Field is registered in the filter input type | Consumers can apply filter expressions to this field |
searchable: true | Field is included in the search resolution set | Consumers' search queries match against this field |
Type and Operator Mapping
The attribute type determines which filter operators are valid when the field is marked as filterable:
| Type | Available Operators |
|---|---|
string | EQ, NEQ, LIKE, IN |
number | EQ, NEQ, GT, GE, LT, LE, IN |
boolean | EQ |
date | EQ, NEQ, GT, GE, LT, LE |
json | Limited (structural queries not supported) |
A field marked as filterable: true with type string accepts LIKE filters but not GT filters. A number field accepts GT but not LIKE. These constraints are enforced at the schema level — invalid filter combinations are rejected before reaching the query engine.
The Full Chain
The complete causality chain works as follows:
- You define a table and its attributes in the workspace.
- Each attribute's type, flags, and mapping are recorded.
- Mockomat generates a GraphQL schema from the table and attribute definitions.
- The schema determines what queries, sorts, filters, and searches are valid.
- At runtime, the query engine resolves requests against the schema, fetches data according to the mapping, and returns results.
Every attribute decision propagates through this chain. Marking a field as sortable does not merely set a flag — it adds a sort capability to every query that touches this table. Changing a type from string to number alters which filter operators consumers can use. This is why getting attribute configuration right matters: the API your consumers interact with is a direct projection of your model.


Diagram showing the chain from attribute flags through schema generation to query behavior.
Practical Workflow
A productive table and attribute workflow follows this pattern:
- Create the table with a clear, domain-aligned name.
- Add attributes for every field the entity should expose.
- Set types carefully — the type determines filter capabilities and validation.
- Configure flags — enable sortable, filterable, and searchable only where needed. Not every field requires every flag.
- Map data sources — assign
OFF_FIELD,FAKE, orCONSTmappings to each attribute. - Preview the result — use the runtime preview to verify that queries return expected data.
- Iterate — adjust attributes, flags, and mappings based on preview feedback and hints.
This cycle should be fast. The workspace is designed to support rapid iteration between modelling and preview. Use the play button on any table card to open the runtime preview directly from the modelling board.
Related Pages
- Modelling Board — the visual canvas where tables are positioned and connected
- Relations — how to define connections between tables
- Data Sources — detailed guide to data object mapping and the
OFF_FIELD,FAKE, andCONSTstrategies - API Design — controlling how tables are exposed as GraphQL queries
- Preview & Hints — validating your model with live queries and actionable readiness hints