Dynorm uses struct tags to configure entity behavior, indexing, and relationships.
Primary Key Tag Description Example pk Partition key dynorm:"pk" sk Sort key dynorm:"sk"
type Entity struct {
ID string `dynorm:"pk"` // Partition key
}
type CompositeKeyEntity struct {
PK string `dynorm:"pk"` // Partition key
SK string `dynorm:"sk"` // Sort key
}
Global Secondary Indexes (GSI) Tag Description Example gsi:IndexName GSI partition key dynorm:"gsi:ByEmail" gsi:IndexName:sk GSI sort key dynorm:"gsi:ByEmail:sk"
type User struct {
dynorm . Entity
Email string `dynorm:"gsi:ByEmail"` // GSI partition key
Username string `dynorm:"gsi:ByUsername"` // Another GSI
Status string `dynorm:"gsi:ByStatusDate"` // GSI PK
Date string `dynorm:"gsi:ByStatusDate:sk"` // GSI SK
}
Local Secondary Indexes (LSI) Tag Description Example lsi:IndexName LSI sort key dynorm:"lsi:ByDate"
type Order struct {
dynorm . Entity
UserID string `dynorm:"pk"` // Same PK as table
OrderDate time . Time `dynorm:"lsi:ByDate"` // LSI sort key
}
Special Attributes Tag Description Example version Optimistic locking version dynorm:"version" ttl Time-to-live attribute dynorm:"ttl" createdAt Creation timestamp dynorm:"createdAt" updatedAt Update timestamp dynorm:"updatedAt" deletedAt Soft delete timestamp dynorm:"deletedAt"
type Document struct {
dynorm . Entity
Content string
Version int `dynorm:"version"` // Optimistic locking
ExpiresAt time . Time `dynorm:"ttl"` // Auto-expire after this time
}
Soft Deletes Tag Description Example soft_deletes:"true" Enable soft deletes On embedded Entity
type Post struct {
dynorm . Entity `soft_deletes:"true"` // Enable soft deletes
Title string
Content string
}
Table Name Tag Description Example table:"name" Custom table name table:"custom_users"
// Auto-derived table name: User → users
type UserRepository struct {
dynorm . Repository [ User ]
}
// Custom table name
type StaffRepository struct {
dynorm . Repository [ User ] `table:"staff_members"`
}
HasOne type User struct {
dynorm . Entity
// Format: hasOne:RelatedEntity,ForeignKeyField
Profile HasOne [ * ProfileRepository ] `dynorm:"hasOne:Profile,UserID"`
}
HasMany type User struct {
dynorm . Entity
// Format: hasMany:RelatedEntity,ForeignKeyField
Posts HasMany [ * PostRepository ] `dynorm:"hasMany:Post,AuthorID"`
}
BelongsTo type Post struct {
dynorm . Entity
AuthorID string
// Format: belongsTo:RelatedEntity,ForeignKeyField
Author BelongsTo [ * UserRepository ] `dynorm:"belongsTo:User,AuthorID"`
}
BelongsToMany type User struct {
dynorm . Entity
// Format: belongsToMany:RelatedEntity
Roles BelongsToMany [ * RoleRepository ] `dynorm:"belongsToMany:Role"`
}
HasManyThrough type Country struct {
dynorm . Entity
// Format: hasManyThrough:FinalEntity,ThroughEntity,FirstFK,SecondFK
Posts HasManyThrough [ * PostRepository , * UserRepository ] `dynorm:"hasManyThrough:Post,User,CountryID,AuthorID"`
}
MorphOne type User struct {
dynorm . Entity
// Format: morphOne:RelatedEntity,MorphName
Avatar MorphOne [ * ImageRepository ] `dynorm:"morphOne:Image,imageable"`
}
MorphMany type Post struct {
dynorm . Entity
// Format: morphMany:RelatedEntity,MorphName
Comments MorphMany [ * CommentRepository ] `dynorm:"morphMany:Comment,commentable"`
}
MorphToMany type Post struct {
dynorm . Entity
// Format: morphToMany:RelatedEntity,MorphName
Tags MorphToMany [ * TagRepository ] `dynorm:"morphToMany:Tag,taggable"`
}
MorphedByMany type Tag struct {
dynorm . Entity
// Format: morphedByMany:MorphName
Taggables MorphedByMany [ any ] `dynorm:"morphedByMany:taggable"`
}
Tag Reference Table Category Tag Format Description Keys pk dynorm:"pk" Partition key sk dynorm:"sk" Sort key GSI gsi:Name dynorm:"gsi:ByEmail" GSI partition key gsi:Name:sk dynorm:"gsi:ByEmail:sk" GSI sort key LSI lsi:Name dynorm:"lsi:ByDate" LSI sort key Special version dynorm:"version" Optimistic locking ttl dynorm:"ttl" Time-to-live createdAt dynorm:"createdAt" Creation timestamp updatedAt dynorm:"updatedAt" Update timestamp deletedAt dynorm:"deletedAt" Soft delete timestamp Entity soft_deletes soft_deletes:"true" Enable soft deletes Repository table table:"name" Custom table name Relationships hasOne hasOne:Entity,FK One-to-one hasMany hasMany:Entity,FK One-to-many belongsTo belongsTo:Entity,FK Inverse relationship belongsToMany belongsToMany:Entity Many-to-many hasManyThrough hasManyThrough:E,T,FK1,FK2 Through relationship morphOne morphOne:Entity,name Polymorphic one morphMany morphMany:Entity,name Polymorphic many morphToMany morphToMany:Entity,name Polymorphic M:M morphedByMany morphedByMany:name Inverse polymorphic
Complete Example type User struct {
dynorm . Entity `soft_deletes:"true"`
// Indexed fields
Email string `dynorm:"gsi:ByEmail"`
Username string `dynorm:"gsi:ByUsername"`
Status string `dynorm:"gsi:ByStatusCreated"`
// CreatedAt from Entity is GSI sort key
// Profile fields
FirstName string
LastName string
// Optimistic locking
Version int `dynorm:"version"`
// Relationships
Profile HasOne [ * ProfileRepository ] `dynorm:"hasOne:Profile,UserID"`
Posts HasMany [ * PostRepository ] `dynorm:"hasMany:Post,AuthorID"`
Roles BelongsToMany [ * RoleRepository ] `dynorm:"belongsToMany:Role"`
Tags MorphToMany [ * TagRepository ] `dynorm:"morphToMany:Tag,taggable"`
}
type UserRepository struct {
dynorm . Repository [ User ] // Table: users
}
Next Steps