Code generation

Configure Go output, understand the generated package, regenerate safely, and keep generated descriptors compatible with the runtime.

The Go generator writes a complete package into your repository. Your schema owns its public models and method tree. github.com/repost-sh/repost-go owns send behavior, which keeps generated code small and reviewable.

Configure the output

generator sdk {
  language = "go"
  output   = "../internal/repostclient"
}

output is required and resolves relative to the schema file. Generated files always declare package repostclient; the directory controls the import path. Give every generator its own output directory.

The output directory is engine-owned. Do not hand-edit generated files or place application code in that directory. Generation stages the complete package and replaces it as one unit. It refuses to overwrite an unrecognized non-empty directory.

What gets emitted

FilePurpose
types.goModel structs, enum types, and enum constants.
descriptors.goField order, wire names, defaults, enum mappings, and event bindings consumed by the runtime.
client.goClient, NewClient, Diagnostics, Close, typed input structs, and the Webhooks method tree.
schema.repostThe merged schema text used for this generation.
schemas.jsonJSON Schema catalog for the event versions in the migration lineage.
.repost-client.jsonManaged-output marker with the generator identity, schema hash, file list, and content hashes.

Commit the whole directory with the schema migration that produced it. A generated package does not contain a separate HTTP implementation. Every typed method delegates to the shared Go runtime.

Generated models and methods

For this schema:

model Order {
  id       String
  nickname String?
}
 
type Order {
  created
}

the package exports Order, OrderCreatedInput, and client.Webhooks.Order.Created(ctx, input). Every input has CustomerID, typed Data, and an optional IdempotencyKey.

Optional fields use repost.Optional[T], which preserves the difference between omission, a value, and JSON null:

order := repostclient.Order{
    ID:       "order_1001",
    Nickname: repost.Present("priority"),
}
 
order.Nickname = repost.Absent[string]() // omit, or apply a schema default
order.Nickname = repost.Null[string]()   // send null when the schema permits it

The zero value of Optional[T] is absent. Payload keys follow schema declaration order and use their @map wire names. Unknown struct fields are not part of generated models and cannot enter the payload.

Regenerate and check drift

repost schema migrate dev --name add_order_nickname

migrate dev records a schema change and regenerates every configured language. generate --check writes nothing and exits non-zero when committed output differs from current generation. Use both status and generation checks in CI.

In a monorepo, one schema can contain several generators. A single CLI run stages every output before replacing any of them. See Polyglot monorepos for ownership and commit rules.

Runtime compatibility

NewClient validates the generated descriptor format before constructing the runtime. If generated code is older than the runtime expects, regenerate with the current CLI. If generated code is newer, upgrade github.com/repost-sh/repost-go. A mismatch fails during construction, before any send can start.

Regenerate the full package after upgrading the schema engine. Do not copy an older generated client forward or patch descriptor constants by hand.

Continue