option<T (Optional Fields)
option<T> (Optional Fields)
Level 4 — Schema Definition & Constraints The type wrapper in SurrealDB used inside field definitions to mark a property as optional, allowing it to be omitted (evaluating to
NONE) without triggering schema validation errors inSCHEMAFULLtables.
1. Prerequisites
DEFINE FIELD— The field declaration context.nullvsNONE— The absent data states.
2. Term Category
Data Type (optional field type wrapper): - Database Structure / Paradigm
3. Explanation
(1) Design Motivation — "Why did we design this?"
In standard SQL databases (PostgreSQL), all columns exist on every row:
- If you want a column to be optional, you mark it as
NULL. - The column space is still reserved, and it defaults to
NULL.
In schema-full NoSQL collections, you need a way to declare that a field can be completely absent from the JSON record on disk (evaluating to NONE):
- If you define a field simply as
TYPE stringin aSCHEMAFULLtable, SurrealDB expects that field to be provided on every write. - If you omit it, the validation parser blocks the transaction, treating it as a missing required parameter.
We designed the option<T> type wrapper to define optional schema properties.
By wrapping a type (e.g. option<string> or option<int>), you instruct SurrealDB that the field is optional.
If the application inserts a record and omits this field, SurrealDB accepts the write, and the property is stored as absent (NONE) on disk, optimizing storage space.
(2) Required vs. Optional Syntax
- Required Field:
DEFINE FIELD email ON user TYPE string;- Rule: Must be provided on inserts. Cannot be
NONE.
- Rule: Must be provided on inserts. Cannot be
- Optional Field:
DEFINE FIELD phone ON user TYPE option<string>;- Rule: Can be omitted on inserts. Defaults to
NONE.
- Rule: Can be omitted on inserts. Defaults to
(3) Reality Metaphor (Questionnaire Boxes)
Imagine filling out a customer profile paper form:
- Required Field (No Option Wrapper): A box labeled "First Name (Required)".
- If you leave the box blank, the clerk flags the application, rejects the form, and halts the line.
- Optional Field (
option<T>): A box labeled "Middle Name (Optional)".- You can leave the box completely blank.
- The clerk accepts the form anyway, and the box contains no data.
(4) Code Examples
Creating Optional Fields in SurrealQL
Let's model a member settings schema:
DEFINE TABLE member SCHEMAFULL;
-- 1. Required fields (must be provided on insert)
DEFINE FIELD username ON member TYPE string;
DEFINE FIELD email ON member TYPE string;
-- 2. Optional fields (wrapped in option<T>)
DEFINE FIELD middle_name ON member TYPE option<string>;
DEFINE FIELD referral_code ON member TYPE option<string>;
-- This write SUCCEEDS (middle_name and referral_code are omitted):
CREATE member:alice SET
username = "alice_dev",
email = "alice@example.com";
-- This write FAILS (email is required but missing!):
CREATE member:bob SET
username = "bob_dev";
-- Error: "Database validation error: Field 'email' is required..."
4. Common Mistakes & Pitfalls
Mistake 1: Defining fields that users frequently skip (like 'avatar_url' or 'bio') as standard types without the 'option' wrapper, blocking account creation
The mistake: Running DEFINE FIELD bio ON user TYPE string; in a SCHEMAFULL signup table, and noticing that registrations fail when users leave the biography field blank.
Why it's wrong: Without option<T>, the type string is strictly required.
If a signup query does not include bio, SurrealDB blocks the write, breaking your user onboarding flow.
Fix: Always wrap profile fields that users can skip in option<T> to make them optional:
-- CORRECT
DEFINE FIELD bio ON user TYPE option<string>;
Mistake 2: Defining Mandatory Non-Null Fields as TYPE option<T>
The mistake: Defining DEFINE FIELD email ON TABLE user TYPE option<string>; when email is required.
Why it's wrong: option<T> explicitly permits the field to be NONE (absent). If the field is mandatory, use TYPE string.
Incorrect:
DEFINE FIELD required_email ON TABLE user TYPE option<string>; // Allows NONE!
Fix:
DEFINE FIELD required_email ON TABLE user TYPE string; // Strictly required string
Mistake 3: Expecting option<T> to Accept Incompatible Types
The mistake: Inserting number 123 into TYPE option<string> field.
Why it's wrong: option<T> accepts NONE OR type T (string). It rejects other incompatible data types.
Incorrect:
DEFINE FIELD bio ON TABLE user TYPE option<string>;
CREATE user SET bio = 123; // ❌ Type error: Expected option<string>, got number
Fix:
CREATE user SET bio = "Dev bio"; // Valid string or omit field for NONE
5. Practice Exercises
Exercise 1: Defining Optional Fields with option<T>
Scenario:
A user profile schema requires a mandatory username string and an optional middle_name string (option<string>).
Requirements:
- Define table
userasSCHEMAFULL. - Define field
usernameasstring. - Define field
middle_nameasoption<string>.
Answer
Implementation
DEFINE TABLE user SCHEMAFULL;
DEFINE FIELD username ON TABLE user TYPE string;
DEFINE FIELD middle_name ON TABLE user TYPE option<string>;
CREATE user:u1 SET username = "jdoe";
Technical Explanation
option<T>designates a field as optional, permittingNONEorNULLvalues.- In
SCHEMAFULLmode, non-option fields require explicit values during creation. - Replaces SQL
NULLABLEcolumn designations.
Exercise 2: Optional Record Link Pointers
Scenario:
Define an optional manager link pointer option<record<user>> on table employee.
Requirements:
- Define field
manageron tableemployeeasoption<record<user>>.
Answer
Implementation
DEFINE TABLE employee SCHEMAFULL;
DEFINE FIELD manager ON TABLE employee TYPE option<record<user>>;
CREATE employee:e1 SET name = "CEO"; -- Manager is NONE
Technical Explanation
option<record<table>>allows optional foreign record link pointers.- Permits top-level entities (like a CEO) to omit manager pointers cleanly.
- Enables flexible relational modeling.
Exercise 3: Querying Optional Fields with NONE Checks
Scenario:
Query employees who do not have an assigned manager (manager = NONE).
Requirements:
- Write a
SELECTquery filteringWHERE manager = NONE.
Answer
6. Related Terms
DEFINE FIELD— The field declaration context.nullvsNONE— The absent data states.SCHEMAFULLValidation Assertion Patterns — Related concept:SCHEMAFULLValidation Assertion Patterns.
7. Key Takeaways
option<T>marks a field as optional inSCHEMAFULLtables.- Equivalent to setting a column as nullable in SQL.
- Allows fields to be omitted from write payloads, evaluating to
NONE. - Required fields (not wrapped in
option<T>) throw errors if missing on write. - Prevents database signup crashes on skipped user profile fields.
- Optimizes storage by omitting absent keys from binary blocks on disk.
- Wrap nested types inside options (e.g.
option<array<string>>).