Skip to main content

Field Types & Options

Fields define the properties of your entities. Each field has a type and optional configuration.

Field Types

String Types

string

Basic text field.

{
"title": {
"type": "string",
"required": true
}
}

url

URL with validation.

{
"website": {
"type": "url",
"optional": true
}
}

Numeric Types

int

Integer number.

{
"count": {
"type": "int",
"default": 0
}
}

float

Floating point number.

{
"rating": {
"type": "float",
"optional": true
}
}

Boolean

{
"isActive": {
"type": "boolean",
"default": true
}
}

Date & Time

isoDate

ISO 8601 date string.

{
"dueDate": {
"type": "isoDate",
"optional": true
}
}

Object ID

objectId

MongoDB ObjectId reference.

{
"authorId": {
"type": "objectId",
"ref": "User",
"required": true
}
}

Enums

Define a set of allowed values.

Simple format:

{
"status": {
"type": "enum",
"values": ["draft", "published", "archived"],
"default": "draft"
}
}

Enhanced format with labels:

{
"priority": {
"type": "enum",
"values": [
{ "key": "low", "label": "Low Priority" },
{ "key": "medium", "label": "Medium Priority" },
{ "key": "high", "label": "High Priority" }
],
"default": "medium"
}
}

Arrays

String Array

{
"tags": {
"type": "string[]",
"default": []
}
}

ObjectId Array

{
"memberIds": {
"type": "objectId[]",
"ref": "User",
"default": []
}
}

Integer Array

{
"scores": {
"type": "int[]",
"default": []
}
}

Generic Array

{
"items": {
"type": "array",
"items": {
"type": "string"
},
"default": []
}
}

Objects

object

Free-form object.

{
"metadata": {
"type": "object",
"optional": true
}
}

any

Any type (no validation).

{
"data": {
"type": "any",
"optional": true
}
}

Field Options

required / optional

{
"email": {
"type": "string",
"required": true
},
"bio": {
"type": "string",
"optional": true
}
}

default

Default value when not provided.

{
"status": {
"type": "enum",
"values": ["active", "inactive"],
"default": "active"
}
}

label

Human-readable label for UI.

{
"createdAt": {
"type": "isoDate",
"label": "Creation Date"
}
}

ref

Reference to another entity (for objectId fields).

{
"projectId": {
"type": "objectId",
"ref": "Project",
"required": true
}
}

expose

Control field visibility across surfaces.

{
"passwordHash": {
"type": "string",
"internal": true,
"expose": {
"contracts": false,
"create": false,
"update": false,
"read": false
}
}
}

Surfaces:

  • contracts - Zod schema
  • create - Create operations
  • update - Update operations
  • read - Read operations

internal

Mark field as internal (hidden by default, requires explicit expose).

{
"secretKey": {
"type": "string",
"internal": true,
"expose": {
"create": true
}
}
}

select

Control MongoDB selection (default: true).

{
"largeField": {
"type": "string",
"select": false
}
}

Include field in text search.

{
"title": {
"type": "string",
"search": true
}
}

trackChanges

Enable field-level change tracking.

{
"approvalStatus": {
"type": "enum",
"values": ["pending", "approved", "rejected"],
"trackChanges": true
}
}

Special Field Types

secretKey — One-Way Hash (Write-Only)

For passwords, API tokens, and secrets you never need to read back. The original value is bcrypt hashed and the plaintext is deleted — it can never be retrieved, only verified.

{
"apiToken": {
"type": "secretKey",
"lastChars": 4
}
}

What the service does on create/update:

  1. Hashes the value with bcrypt → stores as apiTokenHash
  2. Saves the last N characters → stores as apiTokenLastChars (for display like ••••a1b2)
  3. Deletes the original plaintext value

Storage in MongoDB:

{
"apiTokenHash": "$2b$10$rKjLv...",
"apiTokenLastChars": "a1b2"
}

Verification: Use bcrypt.compare(inputValue, storedHash) to verify. The service does not expose a verify method — implement in your route handler.

Options:

PropertyDefaultDescription
lastChars4Number of trailing chars to store for display (0 to disable)

encryptedKey — Two-Way AES-256 Encryption (Read/Write)

For API keys, webhook secrets, OAuth tokens, and credentials you need to retrieve for making API calls to external services.

{
"webhookSecret": {
"type": "encryptedKey",
"lastChars": 4
}
}

What the service does on create/update:

  1. Encrypts with AES-256-CBC → stores as webhookSecretEncrypted
  2. Saves the last N characters → stores as webhookSecretLastChars
  3. Deletes the original plaintext value

Storage in MongoDB:

{
"webhookSecretEncrypted": "a1b2c3d4e5f6:encrypted_hex_data",
"webhookSecretLastChars": "x9y0"
}

Retrieving the original value:

const decrypted = await service.getDecryptedKey(entityId, 'webhookSecret');

Encryption key: Set RADISH_ENCRYPTION_KEY in your .env. The default is a placeholder — must be changed in production.

Options:

PropertyDefaultDescription
lastChars4Number of trailing chars to store for display (0 to disable)

When to Use Which

Use CaseTypeWhy
User passwordssecretKeyNever need the original back, verify with bcrypt
API tokens (verification only)secretKeyJust compare hashes
Third-party API keysencryptedKeyNeed to send to external APIs
Webhook signing secretsencryptedKeyNeed to compute HMAC signatures
OAuth access/refresh tokensencryptedKeyNeed to make API calls
Database connection stringsencryptedKeyNeed to connect at runtime

Security Notes

  • Both field types are excluded from default select queries — they don't appear in list() or get() responses
  • The getDecryptedKey() method requires authentication (service-level access control applies)
  • In production, use a proper key management system (AWS KMS, HashiCorp Vault) and set RADISH_ENCRYPTION_KEY to a secure 32-byte value
  • The lastChars display field is stored in plaintext — set to 0 for maximum security

Example Entity with Various Field Types

{
"entities": {
"Product": {
"fields": {
"name": {
"type": "string",
"required": true,
"label": "Product Name",
"search": true
},
"sku": {
"type": "string",
"required": true,
"label": "SKU"
},
"price": {
"type": "float",
"required": true,
"label": "Price"
},
"stock": {
"type": "int",
"default": 0,
"label": "Stock Count"
},
"category": {
"type": "enum",
"values": ["electronics", "clothing", "food", "other"],
"default": "other",
"label": "Category"
},
"vendorId": {
"type": "objectId",
"ref": "Vendor",
"optional": true,
"label": "Vendor"
},
"tags": {
"type": "string[]",
"default": [],
"label": "Tags"
},
"imageUrls": {
"type": "string[]",
"default": [],
"label": "Product Images"
},
"releaseDate": {
"type": "isoDate",
"optional": true,
"label": "Release Date"
},
"specs": {
"type": "object",
"optional": true,
"label": "Specifications"
},
"isActive": {
"type": "boolean",
"default": true,
"label": "Active Status"
}
}
}
}
}

Next Steps