You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This proposal suggests the development of a tool within the CUE ecosystem to generate Go code from CUE schema definitions. This tool aims to bridge the gap between declarative configuration schemas and type-safe Go code by adopting the "parse, don't validate" principle. By generating Go types with integrated validation logic based on CUE schemas, we can treat configurations as injectable components, enhancing their integration with dependency injection (DI) frameworks like uber-fx.
Motivation
CUE's current capabilities excel at defining schemas and constraints for configuration data concisely and human-readably. However, translating these definitions into Go requires manual validation logic, introducing potential redundancy, boilerplate, and a higher risk of errors.
Adopting the "parse, don't validate" principle, where data structures are inherently valid upon creation, offers several benefits:
Reduces Runtime Errors: Ensures data validity at the parsing stage, minimizing the risk of runtime validation failures.
Streamlines Development: Automates the translation of CUE schemas into Go code with embedded validation logic, simplifying the development process.
Enhances Code Maintainability: Changes in the schema automatically propagate to the validation logic, ensuring consistency and easing updates.
Furthermore, treating configurations as first-class, injectable components allows for more flexible and modular application architectures. Dependency injection frameworks, like uber-fx, can manage and inject these validated configurations into various application parts, further enhancing modularity and testability.
Proposal Details
The proposed tool will:
Parse CUE schema definitions, including types and constraints.
Generate Go code artifacts, including:
Custom Go types that mirror CUE schema definitions.
Constructor functions for these types that enforce the defined constraints, embodying the "parse, don't validate" principle.
Facilitate integration with DI containers by ensuring generated types are compatible with frameworks like uber-fx, enabling configurations to be treated as injectable components.
package main
import (
"fmt""regexp"
)
// UserName represents a validated username.typeUserNamestringfuncNewUserName(valuestring) (UserName, error) {
if!regexp.MustCompile(`^[a-zA-Z0-9_]{3,20}$`).MatchString(value) {
return"", fmt.Errorf("invalid UserName: must be 3-20 characters long, containing only alphanumeric characters and underscores")
}
returnUserName(value), nil
}
// Email represents a validated email address.typeEmailstringfuncNewEmail(valuestring) (Email, error) {
if!regexp.MustCompile(`^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+$`).MatchString(value) {
return"", fmt.Errorf("invalid Email format")
}
returnEmail(value), nil
}
// Age represents a validated age.typeAgeintfuncNewAge(valueint) (Age, error) {
ifvalue<0||value>130 {
return0, fmt.Errorf("invalid Age: must be between 0 and 130")
}
returnAge(value), nil
}
// Bio represents an optional biography text.typeBio*stringfuncNewBio(value*string) (Bio, error) {
ifvalue!=nil&&len(*value) >200 {
returnnil, fmt.Errorf("Bio must be under 200 characters")
}
returnBio(value), nil
}
The proposed tool would generate the following Go code, embedding type-specific validation logic directly within constructor functions for each type, thereby embracing the "parse, don't validate" principle:
This generated code illustrates how complex validation logic defined declaratively in CUE can be automatically transformed into robust, type-safe Go code. This approach not only enforces data integrity but also streamlines the development process by eliminating manual validation code, ensuring that configurations and data structures adhere strictly to their defined schemas.
Expected Outcomes
Enhanced Developer Experience: Simplify the management of configurations and data schemas.
Increased Application Robustness: Leverage Go's type system and compile-time checks, combined with CUE's expressive power for schemas.
Seamless Integration with Modern Go Applications: Especially those utilizing DI frameworks for managing dependencies and configurations.
Conclusion
By bridging CUE's declarative schema definition capabilities with Go's strong type system and the "parse, don't validate" principle, we can enhance the safety, maintainability, and developer experience of working with configuration data.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Abstract
This proposal suggests the development of a tool within the CUE ecosystem to generate Go code from CUE schema definitions. This tool aims to bridge the gap between declarative configuration schemas and type-safe Go code by adopting the "parse, don't validate" principle. By generating Go types with integrated validation logic based on CUE schemas, we can treat configurations as injectable components, enhancing their integration with dependency injection (DI) frameworks like
uber-fx
.Motivation
CUE's current capabilities excel at defining schemas and constraints for configuration data concisely and human-readably. However, translating these definitions into Go requires manual validation logic, introducing potential redundancy, boilerplate, and a higher risk of errors.
Adopting the "parse, don't validate" principle, where data structures are inherently valid upon creation, offers several benefits:
Furthermore, treating configurations as first-class, injectable components allows for more flexible and modular application architectures. Dependency injection frameworks, like
uber-fx
, can manage and inject these validated configurations into various application parts, further enhancing modularity and testability.Proposal Details
The proposed tool will:
uber-fx
, enabling configurations to be treated as injectable components.Example
Given a CUE schema for
UserProfile
components:The proposed tool would generate the following Go code, embedding type-specific validation logic directly within constructor functions for each type, thereby embracing the "parse, don't validate" principle:
This generated code illustrates how complex validation logic defined declaratively in CUE can be automatically transformed into robust, type-safe Go code. This approach not only enforces data integrity but also streamlines the development process by eliminating manual validation code, ensuring that configurations and data structures adhere strictly to their defined schemas.
Expected Outcomes
Conclusion
By bridging CUE's declarative schema definition capabilities with Go's strong type system and the "parse, don't validate" principle, we can enhance the safety, maintainability, and developer experience of working with configuration data.
Beta Was this translation helpful? Give feedback.
All reactions