Skip to main content
Entity is a core component of Sonamu projects, defining both database tables and TypeScript types together.

What is an Entity?

An Entity is a data model definition that includes:
  • Database Schema - Table structure, columns, indexes
  • TypeScript Types - Type definitions for type safety
  • Relations - Connections with other Entities
  • Subsets - Field combinations for API responses
  • Enums - Enumeration types and labels

How to Define an Entity

It’s recommended to visually define Entities in Sonamu UI (http://localhost:34900/sonamu-ui). Sonamu UI provides auto-completion, validation, and real-time preview features.

entity.json File Structure

Entities are saved as entity.json files with the following structure:
{
  "id": "User",
  "table": "users",
  "title": "User",
  "props": [...],
  "indexes": [...],
  "subsets": {...},
  "enums": {...}
}
File Location: api/src/application/{entity}/{entity}.entity.json

Required Fields

id

The unique identifier for the Entity. Written in PascalCase.
{
  "id": "User"
}
  • Used for Entity class names and type names - Example: UserModel, User, UserBaseSchema

table

The database table name. Written in snake_case.
{
  "table": "users"
}
If the table name is omitted, it’s auto-generated based on the Entity ID: - Userusers - BlogPostblog_posts

title

The display name for the Entity.
{
  "title": "User"
}

props

An array of Entity properties (columns). Each property defines its type and options.
{
  "props": [
    { "name": "id", "type": "integer", "desc": "ID" },
    { "name": "email", "type": "string", "length": 255, "desc": "Email" },
    { "name": "created_at", "type": "date", "dbDefault": "CURRENT_TIMESTAMP" }
  ]
}
Basic Property Options:
OptionTypeDescriptionDefault
namestringProperty name (snake_case)required
typestringData typerequired
descstringDescription-
nullablebooleanAllow NULLfalse
dbDefaultstringDB default value-
Learn More - Field Types - All available data types - Relations - Defining Entity relationships

Optional Fields

parentId

Used when inheriting from another Entity.
{
  "id": "Admin",
  "parentId": "User",
  "title": "Administrator"
}
Using parentId inherits all props from the parent Entity. Use carefully.

indexes

Defines database indexes.
{
  "indexes": [
    {
      "type": "unique",
      "name": "users_email_unique",
      "columns": [{ "name": "email" }]
    },
    {
      "type": "index",
      "name": "users_created_at_idx",
      "columns": [{ "name": "created_at" }]
    }
  ]
}
Index Types:
  • index - Regular index (improves search performance)
  • unique - Unique index (prevents duplicates)
  • hnsw - HNSW index for Vector search
  • ivfflat - IVFFlat index for Vector search

subsets

Defines field combinations for API responses.
{
  "subsets": {
    "A": ["id", "email", "username", "created_at"],
    "P": ["id", "email", "username", "role"],
    "SS": ["id", "email"]
  }
}
Subset Usage:
async findAll(): Promise<UserSubsetA[]> {
  return this.puri()
    .select<UserSubsetA>("A")
    .many();
}
Including Relation Fields:
{
  "subsets": {
    "P": ["id", "username", "employee.id", "employee.department.name"]
  }
}
Using dot notation in Subsets, you can include fields from related Entities. Sonamu automatically generates JOINs.

enums

Defines enumeration types and labels.
{
  "enums": {
    "UserRole": {
      "normal": "Normal",
      "admin": "Administrator"
    },
    "UserOrderBy": {
      "id-desc": "ID Newest First",
      "created_at-desc": "Created At Newest First"
    },
    "UserSearchField": {
      "email": "Email",
      "username": "Name"
    }
  }
}
Enum Usage:
// Auto-generated Zod schema and TypeScript type
import { UserRole } from "./user.types";

// "normal" | "admin"
type Role = z.infer<typeof UserRole>;

// Usage in API
async updateRole(userId: number, role: Role) {
  // ...
}

Practical Examples

Basic Entity Example

user.entity.json
{
  "id": "User",
  "table": "users",
  "title": "User",
  "props": [
    { "name": "id", "type": "integer", "desc": "ID" },
    {
      "name": "created_at",
      "type": "date",
      "desc": "Created At",
      "dbDefault": "CURRENT_TIMESTAMP"
    },
    { "name": "email", "type": "string", "length": 255, "desc": "Email" },
    { "name": "username", "type": "string", "length": 255, "desc": "Name" },
    { "name": "password", "type": "string", "length": 255, "desc": "Password" },
    { "name": "birth_date", "type": "date", "nullable": true, "desc": "Birth Date" },
    { "name": "role", "type": "enum", "id": "UserRole", "desc": "Role" },
    { "name": "is_verified", "type": "boolean", "desc": "Verified", "dbDefault": "false" },
    { "name": "deleted_at", "type": "date", "nullable": true, "desc": "Deleted At" }
  ],
  "indexes": [{ "type": "unique", "name": "users_email_unique", "columns": [{ "name": "email" }] }],
  "subsets": {
    "A": ["id", "email", "username", "role", "created_at"],
    "P": ["id", "email", "username", "role"]
  },
  "enums": {
    "UserRole": { "normal": "Normal", "admin": "Administrator" },
    "UserOrderBy": { "id-desc": "ID Newest First" }
  }
}

Example with Relations

employee.entity.json
{
  "id": "Employee",
  "table": "employees",
  "title": "Employee",
  "props": [
    { "name": "id", "type": "integer", "desc": "ID" },
    {
      "name": "created_at",
      "type": "date",
      "desc": "Created At",
      "dbDefault": "CURRENT_TIMESTAMP"
    },
    {
      "type": "relation",
      "name": "user",
      "with": "User",
      "desc": "User",
      "relationType": "OneToOne",
      "hasJoinColumn": true,
      "onDelete": "CASCADE"
    },
    {
      "type": "relation",
      "name": "department",
      "with": "Department",
      "nullable": true,
      "desc": "Department",
      "relationType": "BelongsToOne",
      "onDelete": "SET NULL"
    },
    { "name": "employee_number", "type": "string", "length": 32, "desc": "Employee Number" },
    {
      "name": "salary",
      "type": "numeric",
      "precision": 10,
      "scale": 2,
      "nullable": true,
      "desc": "Salary"
    },
    { "name": "hire_date", "type": "date", "nullable": true, "desc": "Hire Date" }
  ],
  "indexes": [
    {
      "type": "unique",
      "name": "employees_user_id_unique",
      "columns": [{ "name": "user_id" }]
    }
  ],
  "subsets": {
    "A": [
      "id",
      "created_at",
      "user.username",
      "department.name",
      "employee_number",
      "salary",
      "hire_date"
    ]
  },
  "enums": {
    "EmployeeOrderBy": { "id-desc": "ID Newest First" }
  }
}

Defining Entities in Sonamu UI

  1. Access Sonamu UI
    # After running API server
    http://localhost:34900/sonamu-ui
    
  2. Create Entity
    • Click “Entities” tab
    • Click “Create Entity” button
    • Enter Entity ID, table name, Title
  3. Add Properties (Props)
    • Click “Add Property” button to add new properties
    • Select type and configure options
    • Change order with drag and drop
  4. Define Subsets
    • Add subset keys in “Subsets” tab
    • Select fields to include with checkboxes
    • Relation fields expand as a tree structure
  5. Save and Generate
    • Click “Save” button
    • Entity file auto-generated
    • Migration auto-generated
Learn More - Using Sonamu UI - Detailed UI guide

What Gets Auto-Generated After Entity Definition

When you define and save an Entity, Sonamu automatically generates the following:

TypeScript Types

Types and Zod schemas generated in {entity}.types.ts file

Database Migration

Migration file generated with table creation SQL

Base Schemas

Base schemas and Enums added to sonamu.generated.ts

Model Scaffold

{entity}.model.ts template generated (when selected)

Cautions

Be Careful When Modifying Entity Definitions - Be cautious when deleting columns or changing types on deployed tables - Recommend making changes gradually through migrations - Consider referential integrity when changing Relations
Entity Design Tips - Always start IDs with integer type - Include created_at, updated_at fields - Explicitly specify indexes for fields requiring unique constraints - Add indexes to frequently searched fields

Next Steps

After completing Entity definition, learn the following topics:

Using Sonamu UI

Learn all Sonamu UI features and shortcuts

Field Types

Learn all available field types and options

Relations

Learn how to define Entity relationships

Enums

Learn how to define and use Enum types