Documentation
¶
Overview ¶
Package dsl provides a Domain Specific Language (DSL) for defining REST API designs for Go models.
The DSL allows developers to declaratively specify API configurations for their data models, including CRUD operations, endpoints, payload/result types, and various behavioral settings. It supports automatic code generation for services, controllers, and API routes based on the defined specifications.
Basic Usage:
type User struct {
Name string
Email string
model.Base // Embeds base model fields
}
func (User) Design() {
// Enable API generation (default: true)
Enabled(true)
// Set custom endpoint (default: lowercase model name)
Endpoint("users")
// Add path parameter for dynamic routing
Param("user") // Creates routes like /api/users/:user
// Enable database migration (default: false)
Migrate(true)
// Define alternative routes for different access patterns
Route("public/users", func() {
List(func() { Enabled(true); Public(true) })
Get(func() { Enabled(true); Public(true) })
})
// Configure Create operation
Create(func() {
Enabled(true)
Service(true) // Generate service code
Public(false) // Internal API only
Payload[CreateUserRequest]()
Result[*User]()
})
// Configure other operations...
Update(func() { Enabled(true) })
Delete(func() { Enabled(true) })
List(func() { Enabled(true) })
Get(func() { Enabled(true) })
}
Supported Operations:
- Create, Update, Delete, Patch: Single record operations
- CreateMany, UpdateMany, DeleteMany, PatchMany: Batch operations
- List, Get: Read operations
- Import, Export: Data transfer operations
Model Types:
- Models with model.Base: Full-featured models with database persistence
- Models with model.Empty: Lightweight models without database migration
Index ¶
- func Create(func())
- func CreateMany(func())
- func Delete(func())
- func DeleteMany(func())
- func Enabled(bool)
- func Endpoint(string)
- func Export(func())
- func FindAllModelBase(file *ast.File) []string
- func FindAllModelEmpty(file *ast.File) []string
- func Get(func())
- func Import(func())
- func IsModelBase(file *ast.File, field *ast.Field) bool
- func IsModelEmpty(file *ast.File, field *ast.Field) bool
- func List(func())
- func Migrate(bool)
- func Param(string)
- func Parse(file *ast.File, endpoint string) map[string]*Design
- func Patch(func())
- func PatchMany(func())
- func Payload[T any]()
- func Public(bool)
- func Result[T any]()
- func Route(string, func())
- func Service(bool)
- func Update(func())
- func UpdateMany(func())
- type Action
- type Design
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Create ¶
func Create(func())
Create defines the configuration for the create operation. The function parameter allows setting Enabled, Service, Public, Payload, and Result. Example: Create(func() { Enabled(true); Payload[CreateUserRequest](); Result[*User]() })
func CreateMany ¶
func CreateMany(func())
CreateMany defines the configuration for batch create operations. Allows creating multiple records in a single request.
func Delete ¶
func Delete(func())
Delete defines the configuration for the delete operation. Typically used for soft or hard deletion of single records.
func DeleteMany ¶
func DeleteMany(func())
DeleteMany defines the configuration for batch delete operations. Allows deleting multiple records in a single request.
func Enabled ¶
func Enabled(bool)
Enabled controls whether API generation is enabled. It has two usage scenarios:
- When used in Design() method, it controls whether API generation is enabled for the entire model. When set to false, no API code will be generated for this model. Default: true
- When used in action configuration functions (e.g., Create, Update, List, Get), it controls whether the specific action/route should be generated. Default: false (actions must be explicitly enabled)
func Endpoint ¶
func Endpoint(string)
Endpoint sets a custom endpoint path for the model's API routes. If not specified, defaults to the lowercase version of the model name. Leading slashes are automatically removed and forward slashes are replaced with hyphens. Example: Endpoint("users") for a User model, Endpoint("/iam/users") becomes "iam-users"
func Export ¶
func Export(func())
Export defines the configuration for data export operations. Used for bulk data extraction to external formats.
func FindAllModelBase ¶
FindAllModelBase finds all struct types that embed model.Base as an anonymous field. It searches for structs containing anonymous fields of type "model.Base" or aliased versions like "pkgmodel.Base" where pkgmodel is an import alias for the model package.
Parameters:
- file: The AST file to search in
Returns:
- []string: Names of all struct types that embed model.Base
This function is used to identify models that should have full database functionality, as opposed to lightweight models that embed model.Empty. FindAllModelBase finds all struct types that embed model.Base as an anonymous field
func FindAllModelEmpty ¶
FindAllModelEmpty finds all struct types that embed model.Empty as an anonymous field. It searches for structs containing anonymous fields of type "model.Empty" or aliased versions like "pkgmodel.Empty" where pkgmodel is an import alias for the model package.
Parameters:
- file: The AST file to search in
Returns:
- []string: Names of all struct types that embed model.Empty
This function is used to identify lightweight models that typically don't require database migration and have simplified API generation. FindAllModelEmpty finds all struct types that embed model.Empty as an anonymous field
func Get ¶
func Get(func())
Get defines the configuration for the get operation. Used for retrieving a single record by identifier.
func Import ¶
func Import(func())
Import defines the configuration for data import operations. Used for bulk data ingestion from external sources.
func IsModelBase ¶
IsModelBase checks if a struct field is an anonymous embedding of model.Base. It handles various import patterns including direct imports, aliased imports, and dot imports of the model package.
Parameters:
- file: The AST file containing import information
- field: The struct field to check
Returns:
- bool: true if the field is an anonymous model.Base embedding
Supported import patterns:
- import "github.com/forbearing/gst/model"
- import pkgmodel "github.com/forbearing/gst/model"
- import . "github.com/forbearing/gst/model"
Example field patterns that return true:
- model.Base (with standard import)
- pkgmodel.Base (with aliased import)
- Base (with dot import)
IsModelBase checks if a struct field is an anonymous embedding of model.Base
func IsModelEmpty ¶
IsModelEmpty checks if a struct field is an anonymous embedding of model.Empty. It handles various import patterns including direct imports, aliased imports, and dot imports of the model package.
Parameters:
- file: The AST file containing import information
- field: The struct field to check
Returns:
- bool: true if the field is an anonymous model.Empty embedding
Supported import patterns:
- import "github.com/forbearing/gst/model"
- import pkgmodel "github.com/forbearing/gst/model"
- import . "github.com/forbearing/gst/model"
Example field patterns that return true:
- model.Empty (with standard import)
- pkgmodel.Empty (with aliased import)
- Empty (with dot import)
IsModelEmpty checks if a struct field is an anonymous embedding of model.Empty
func List ¶
func List(func())
List defines the configuration for the list operation. Used for retrieving multiple records with optional filtering and pagination.
func Migrate ¶
func Migrate(bool)
Migrate controls whether database migration should be performed for this model. When true, the model's table structure will be created/updated in the database. Default: false
func Param ¶
func Param(string)
Param defines a path parameter for dynamic routing in RESTful APIs. It adds a URL parameter segment to the endpoint, enabling hierarchical resource access. The parameter is automatically propagated to child resources in nested structures, allowing parent resource parameters to be inherited by child endpoints.
Parameter Format:
- Simple name: Param("user") creates ":user" parameter
- Bracketed format: Param("{user}") also creates ":user" parameter
Route Generation Examples:
- Param("user") transforms /api/users to /api/users/:user
- Param("app") transforms /api/namespaces/apps to /api/namespaces/apps/:app
- Param("env") transforms /api/namespaces/apps/envs to /api/namespaces/apps/envs/:env
Parameter Propagation: When using hierarchical models (namespace -> app -> env), parent parameters are automatically propagated to child resources:
- /api/namespaces/:namespace/apps/:app/envs/:env
- Child resources inherit all parent path parameters
Common Use Cases:
- namespace: Param("namespace") or Param("ns") for multi-tenant applications
- app: Param("app") for application-scoped resources
- env: Param("env") for environment-specific configurations
The parameter creates RESTful nested resource patterns, enabling hierarchical API designs where child resources are scoped under parent resources through URL path parameters.
func Parse ¶
Parse analyzes a Go source file and extracts DSL design information from models. It looks for structs that have a Design() method and parses the DSL calls within that method.
The parser identifies models by finding structs that embed either model.Base or model.Empty, then locates their Design() method and analyzes the DSL function calls to build the Design configuration.
Parameters:
- file: The parsed AST file node to analyze
- endpoint: Optional endpoint override - if provided, will overwrite the default endpoint for enabled designs
Returns:
- map[string]*Design: A map where keys are model names and values are their parsed Design configurations
Example usage:
designs := Parse(fileNode, "custom-endpoint")
for modelName, design := range designs {
fmt.Printf("Model %s has endpoint: %s\n", modelName, design.Endpoint)
}
The parser supports various DSL patterns:
- Global settings: Enabled(), Endpoint("path"), Migrate(true)
- Action configuration: Create().Enabled(true).Payload[Type].Result[Type]
- Service and visibility: Service(true), Public(false)
func Patch ¶
func Patch(func())
Patch defines the configuration for the patch operation. Used for partial record updates, modifying only specified fields.
func PatchMany ¶
func PatchMany(func())
PatchMany defines the configuration for batch patch operations. Allows partially updating multiple records in a single request.
func Payload ¶
func Payload[T any]()
Payload specifies the request payload type for the current action. The type parameter T defines the structure of incoming request data. Example: Payload[CreateUserRequest]() or Payload[*User]()
func Public ¶
func Public(bool)
Public controls whether the current action requires authentication/authorization. When false, the action will be processed by auth middleware if registered via middleware.RegisterAuth. When true, the action is publicly accessible without authentication. Default: false (requires authentication)
func Result ¶
func Result[T any]()
Result specifies the response result type for the current action. The type parameter T defines the structure of outgoing response data. Example: Result[*User]() or Result[UserResponse]()
func Route ¶
func Route(string, func())
Route defines an alternative API route for the model beyond the default hierarchical route. This allows a resource to be accessible through multiple API endpoints, providing flexibility for different access patterns and use cases.
The function accepts two parameters:
- path: The route path string (e.g., "apps", "config/apps"). Leading slashes are automatically removed.
- config: A function that defines which operations are enabled for this route
The function can be called multiple times within a Design() method to add multiple alternative routes. Each call adds a new route to the model's API endpoints without overriding existing ones.
Route Format:
- Simple path: Route("apps", func() {...}) creates /api/apps
- Nested path: Route("config/apps", func() {...}) creates /api/config/apps
- Custom path: Route("admin/applications", func() {...}) creates /api/admin/applications
- Leading slash removed: Route("/config/apps", func() {...}) becomes "config/apps"
Configuration Function: The second parameter is a function that defines which operations are available for this route. You can configure List, Get, Create, Update, Delete, Patch operations within this function:
Route("/config/apps", func() {
List(func() {
Enabled(true)
Service(true)
})
Get(func() {
Enabled(true)
Service(true)
})
})
Route Generation: For a route path like "/config/apps" with Param("app"), the following routes are generated:
- /api/config/apps (for List operations)
- /api/config/apps/:app (for Get, Update, Delete, Patch operations)
Usage Examples:
- Route("apps", func() {...}) - Global app listing endpoint
- Route("config/apps", func() {...}) - Configuration-scoped app endpoint
- Route("public/apps", func() {...}) - Public app directory endpoint
Common Use Cases:
- Global resource access: Access resources without namespace/parent constraints
- Alternative endpoints: Provide different API paths for the same resource
- Cross-cutting concerns: Admin, public, or system-level access patterns
- API versioning: Different route structures for API evolution
Multiple Routes Example:
func (App) Design() {
Endpoint("apps")
Param("app")
Route("apps", func() {
List(func() { Enabled(true) })
Get(func() { Enabled(true) })
})
Route("config/apps", func() {
List(func() { Enabled(true); Service(true) })
Get(func() { Enabled(true); Service(true) })
})
}
This creates multiple API endpoints for the same model:
- /api/namespaces/:ns/apps (default hierarchical route)
- /api/apps and /api/apps/:app (additional global route)
- /api/config/apps and /api/config/apps/:app (additional config route)
func Service ¶
func Service(bool)
Service controls whether service layer code should be generated for the current action. This affects the generation of business logic layer code. Default: false
func Update ¶
func Update(func())
Update defines the configuration for the update operation. Used for full record updates, replacing all fields.
func UpdateMany ¶
func UpdateMany(func())
UpdateMany defines the configuration for batch update operations. Allows updating multiple records in a single request.
Types ¶
type Action ¶
type Action struct {
// Enabled indicates whether this specific action should be generated.
// Default: false (actions must be explicitly enabled)
Enabled bool
// Service indicates whether service layer code should be generated for this action.
// The service layer contains business logic and data access code.
// Default: false
Service bool
// Public indicates whether this action requires authentication/authorization.
// When false, the action will be processed by auth middleware if registered via middleware.RegisterAuth.
// When true, the action is publicly accessible without authentication.
// Default: false (requires authentication)
Public bool
// Payload specifies the type name for the request payload.
// This determines the structure of incoming request data.
// Example: "CreateUserRequest", "*User", "User"
Payload string
// Result specifies the type name for the response result.
// This determines the structure of outgoing response data.
// Example: "*User", "UserResponse", "[]User"
Result string
// The phase of the action
// not part of DSL, just used to identify the current Action.
Phase consts.Phase
}
Action represents the configuration for a specific API operation. Each operation (Create, Update, Delete, etc.) has its own Action configuration.
type Design ¶
type Design struct {
// Enabled indicates whether API generation is enabled for this model.
// Default: true
Enabled bool
// Endpoint specifies the URL path segment for this model's API routes.
// Defaults to the lowercase version of the model name.
// Used by the router to construct API endpoints.
Endpoint string
// Param contains the path parameter name for dynamic routing.
// The parameter will be inserted as ":param" in the generated route paths.
// Parameters are automatically propagated to child resources in nested structures,
// allowing parent resource parameters to be inherited by child endpoints.
//
// Usage Examples:
// - Param("user") generates routes like /api/users/:user
// - Param("app") generates routes like /api/namespaces/apps/:app
// - Param("env") generates routes like /api/namespaces/apps/envs/:env
//
// Parameter Propagation:
// In hierarchical models (namespace -> app -> env), parent parameters are
// automatically propagated: /api/namespaces/:namespace/apps/:app/envs/:env
//
// Common Use Cases:
// - "namespace" or "ns": for multi-tenant applications
// - "app": for application-scoped resources
// - "env": for environment-specific configurations
//
// Default: "" (no parameter)
Param string
// Migrate indicates whether database migration should be performed.
// When true, the model's table structure will be created/updated.
// Default: false
Migrate bool
// IsEmpty indicates if the model contains a model.Empty field.
// Models with model.Empty are lightweight and typically don't require migration.
IsEmpty bool
// Single record operations
Create *Action // Create operation configuration
Delete *Action // Delete operation configuration
Update *Action // Update operation configuration (full replacement)
Patch *Action // Patch operation configuration (partial update)
List *Action // List operation configuration (retrieve multiple)
Get *Action // Get operation configuration (retrieve single)
// Batch operations
CreateMany *Action // Batch create operation configuration
DeleteMany *Action // Batch delete operation configuration
UpdateMany *Action // Batch update operation configuration
PatchMany *Action // Batch patch operation configuration
// Data transfer operations
Import *Action // Import operation configuration
Export *Action // Export operation configuration
// contains filtered or unexported fields
}
Design represents the complete API design configuration for a model. It contains global settings and individual action configurations. This struct is populated by parsing the model's Design() method.
func (*Design) Range ¶
Range iterates over all enabled actions in the Design and calls the provided function for each one. The function receives the endpoint, action for each enabled action.
Parameters:
- fn: Callback function that receives (endpoint, action) for each enabled action
The iteration order is fixed: Create, Delete, Update, Patch, List, Import, Export, Get, CreateMany, DeleteMany, UpdateMany, PatchMany.
Example:
design.Range(func(route string, action *Action) {
fmt.Printf("Generating %s for %s\n", action.Phase.MethodName(), route)
})