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 schemacreate- Create operationsupdate- Update operationsread- 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
}
}
search
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:
- Hashes the value with bcrypt → stores as
apiTokenHash - Saves the last N characters → stores as
apiTokenLastChars(for display like••••a1b2) - 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:
| Property | Default | Description |
|---|---|---|
lastChars | 4 | Number 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:
- Encrypts with AES-256-CBC → stores as
webhookSecretEncrypted - Saves the last N characters → stores as
webhookSecretLastChars - 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:
| Property | Default | Description |
|---|---|---|
lastChars | 4 | Number of trailing chars to store for display (0 to disable) |
When to Use Which
| Use Case | Type | Why |
|---|---|---|
| User passwords | secretKey | Never need the original back, verify with bcrypt |
| API tokens (verification only) | secretKey | Just compare hashes |
| Third-party API keys | encryptedKey | Need to send to external APIs |
| Webhook signing secrets | encryptedKey | Need to compute HMAC signatures |
| OAuth access/refresh tokens | encryptedKey | Need to make API calls |
| Database connection strings | encryptedKey | Need to connect at runtime |
Security Notes
- Both field types are excluded from default select queries — they don't appear in
list()orget()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_KEYto a secure 32-byte value - The
lastCharsdisplay 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"
}
}
}
}
}