Go Helper Conventions
Helper vs. Generated Files
Every construct’s Go package has two kinds of files:
| File | Editable? | Purpose |
|---|---|---|
<construct>.go |
No — auto-generated | Struct definitions from schema |
<construct>_helper.go |
Yes — manual | SQL drivers, interfaces, table names |
Helper files must include this comment at the top:
// This is not autogenerated.
What Goes in a Helper File
1. TableName() Method
Returns the database table name for GORM/Pop:
func (c *Connection) TableName() string {
return "connections"
}
2. SQL Driver Methods (Scan/Value)
For types stored as JSON blobs in a single DB column, implement sql.Scanner and driver.Valuer.
Value() — always marshal, never return SQL NULL:
// CORRECT — matches core.Map pattern
func (m MetadataMap) Value() (driver.Value, error) {
b, err := json.Marshal(m)
if err != nil {
return nil, err
}
return string(b), nil
}
core.Map behavior. Always marshal — even a nil value produces the JSON string "null".
Scan() — zero the receiver on nil src:
func (m *MetadataMap) Scan(src interface{}) error {
switch v := src.(type) {
case []byte:
return json.Unmarshal(v, m)
case string:
return json.Unmarshal([]byte(v), m)
case nil:
*m = nil // ← Zero the receiver to avoid stale data
return nil
default:
return fmt.Errorf("unsupported type: %T", src)
}
}
3. Entity Interface Implementation
If the construct participates in Meshery’s entity system:
func (c *Connection) GetID() core.Uuid {
return c.Id
}
func (c *Connection) GetEntityType() string {
return "connection"
}
x-generate-db-helpers: true
For types stored as JSON blobs that have a dedicated schema definition, use the x-generate-db-helpers annotation at the schema component level (not per-property):
# In api.yml
components:
schemas:
ConnectionMetadata:
x-generate-db-helpers: true
type: object
properties:
version:
type: string
This auto-generates Scan()/Value() methods, so you don’t need to write them manually.
- Types mapped to full DB tables (they use ORM, not JSON blob storage)
- Amorphous types without a fixed schema — use
x-go-type: "core.Map"instead - On individual properties — annotation must be at the component level
x-go-type and x-go-type-import
Override the generated Go type for a schema property:
metadata:
x-go-type: "core.Map"
x-go-type-import:
path: "github.com/meshery/schemas/models/core"
alias: core
All core type imports must use models/core with alias core. Do not reference models/v1alpha1/core.
Checklist for New Helpers
- File starts with
// This is not autogenerated. TableName()returns the correct plural snake_case table nameValue()always marshals — never returns(nil, nil)Scan()zeros the receiver (*m = nil) whensrcis nil- No hand-editing of the companion generated
.gofile