Data Modeling
Data models are core to our applications and architectures.
With hof
, you specify their types, shapes, and relations using CUE
and will combine, checkpoint, and track history
as your data models and applications evolve.
They become the source of truth when generating or updating
code across yor technology stack or service fleet.
hof datamodel
features enable:
- checkpoints, history tracking, structural diff calculations
- auto generated database migrations
- client/server version negotiation and request/response upgrades
- data lenses and other transformations
- More than CRUD generation from relations and history
Base Datamodel
The base data model is any CUE Value with
#hof: datamodel: root: true
set.
hof
leaves those details to the user and module authors.
We also provide some common schemas and extras you can use
along with the main data model features hof
provides.
Extending Datamodels
With hof datamodels
powered by CUE, you will be able to:
- enforce schemas and provide defaults
- share them as modules across applications
- merge or unify them like any CUE value
- enrich them conditionally before code gen
The first three points are native to CUE,
so you have all the same capabilities when using hof
.
Modules are currently only available if hof
.
CUE is working on their own dependency management
and we are involved in that work as well.
Learn more in the modules section.
When it comes to enriching, there are a few ways or places this happens.
hof
’s base datamodel doesn’t provide any structure,
in part because there is not one to rule them all,
but also because we want to let users define their own
while still getting the checkpointing, history, and diff features.
Providing structure
More often than not, you will want to
provide structure to the datamodel.
hof/schema/dm/sql is one example of this.
You define the structure by using the @history()
on a collection within your datamodel.
This is a tracking and pivot point.
hof
will manage history and diffs
on a structural level, at each history point.
hof
will manage each CUE field in a value with @history()
.
In the above code, this would be
- each model in
Models
, likeUser
- each field in
User.Fields
- each view in
Views
Enriching values
Generally, the input Datamodel
to a Generator
will use generic field types.
When generating code, it can be helpful to enrich these values to calculate
template output in CUE rather than the templates themselves.
You can apply these by wrapping the datamodel or applying them in your generator inputs.
Places where this is helpful are:
- mapping types, especially collections and relations, to the target language or technology.
- adding various string casings or manipulations
An example of this is mapping hof
s schema/dm/fields
like uuid
to a package in languages like Go or Python
Future ideas
We plan to make data models usable in other hof
sub-systems
- more features around multiple datamodels. Multiple are supported today, we could provide mappings from an instance in one to the other.
hof/flow
to enable similar transparent, inter-version transformshof/chat
to provide generator specific schemas for LLMs to target (like Microsoft/Guidance)
Datamodel Commands
Datamodels and Code Generation
Datamodels form the basis for input to code generation.
Typically, a generator will require a dm.Datamodel
and
some other inputs specific to that generator.
You can then use them in the templates like any other value.
Here is an example snippet that you would use with our supacode generator for full stack applications.