Fabrica Blog

Simple guides introducing Fabrica with hands-on examples.

View the Project on GitHub OpenCHAMI/fabrica

Spec Version History (Opt-in)

Record immutable snapshots of a resource’s Spec on create/update/patch, list version history, and retrieve specific versions. Status is never versioned. The current spec version is surfaced as status.version.

What you get

Snapshot schema:

{
  "versionId": "20251104161025-1762273000000000000",
  "createdAt": "2025-11-04T16:10:25Z",
  "uid": "sen-1234abcd",
  "name": "sensor-1",
  "labels": {"env":"dev"},
  "annotations": {"owner":"team-a"},
  "spec": { }
}

Version IDs are time-sortable strings: YYYYMMDDHHMMSS-nanots.

Enable for a resource

1) When adding a resource, pass the flag:

fabrica add resource Sensor --with-versioning

This inserts a marker at the top of the resource file:

// +fabrica:resource-versioning=enabled

2) Ensure your Status struct includes a Version field (the scaffolder adds this when --with-versioning is used):

type SensorStatus struct {
    Phase   string `json:"phase,omitempty"`
    Message string `json:"message,omitempty"`
    Ready   bool   `json:"ready"`
    // Version is the current spec version identifier (server-managed)
    Version string `json:"version,omitempty"`
}

3) Generate code:

fabrica generate

The generated handlers will:

Try it

Assuming a generated server running at http://localhost:8080 and a versioned Sensor resource:

# Create Sensor
curl -s -H 'Content-Type: application/json' \
  -d '{"name":"s1","description":"first"}' \
  http://localhost:8080/sensors | jq .

# Observe status.version in the response body

# Update Spec
curl -s -X PUT -H 'Content-Type: application/json' \
  -d '{"description":"second"}' \
  http://localhost:8080/sensors/<uid> | jq .status.version

# Patch Spec
curl -s -X PATCH -H 'Content-Type: application/merge-patch+json' \
  -d '{"description":"third"}' \
  http://localhost:8080/sensors/<uid> | jq .status.version

# Status update (does NOT change version)
curl -s -X PUT -H 'Content-Type: application/json' \
  -d '{"ready":true}' \
  http://localhost:8080/sensors/<uid>/status | jq .status.version

# List versions
curl -s http://localhost:8080/sensors/<uid>/versions | jq .

# Get a specific version
curl -s http://localhost:8080/sensors/<uid>/versions/<versionId> | jq .

# Delete a specific version
curl -s -X DELETE http://localhost:8080/sensors/<uid>/versions/<versionId>

Implementation details

Caveats and next steps

For a runnable walk-through, see the example at examples/07-spec-versioning/.