Skip to content

The generated client

tide generate writes a typed Go client into a repository, committed so schema changes appear in review as an API diff.

tide generate writes a typed Go client into your repository, scoped to the namespaces your caller consumes. The generated code is committed: a schema change appears in review as a diff of the API your application calls, and the application builds from a clean checkout with no atlantis server, no buf, and no shared SDK.

What gets generated

With output_dir and generate: set in tide.yaml, tide generate fetches the canonical schema from the server, so proto field numbers match the server exactly. It filters that schema to the generate: namespaces. A cross-namespace foreign key is a scalar column, so referencing another namespace’s entity does not require generating its types. It then emits proto sources and typed wrappers under output_dir, inside your own module with your own import paths, running buf generate for the wire types.

Each entity gets a client interface with its six RPCs (Get, BatchGet, Create, Update, Delete, Query) and a typed method per custom query and procedure. A keyless entity gets no client: without a key there is nothing to address a row by. A namespace declaring jobs also gets a jobs.go with a typed Args struct, handler interface, and Register<Job> helper per job.

generate owns only the roots it writes — atlantis/, pb/, client/, and the two buf config files — and leaves everything else under output_dir alone. It refuses a tree generated by a different caller.

Why a stale client still works

Proto field numbers are preserved by field name across applies. A removed field’s number is retired and reserved for as long as the entity exists, and a new field takes the smallest free number. An old client therefore keeps sending a shape the server understands. It cannot see fields added since it was generated, and code using a new entity will not compile until you regenerate. A column whose type changes keeps its number with a new proto type, so regenerate after a type change before relying on that field.

tide apply never regenerates the client; it refreshes only the .tide-cache/ mirror. Its success message reminds you to run tide generate.

The manifest and --check

tide generate writes tide.manifest.json beside the code: the caller, the namespaces, the module prefix, and a committed hash per generated file.

  • tide generate --check verifies the tree against the manifest with no server, no credentials, and no buf. It catches hand-edited, missing, and leftover files.
  • tide generate --check --against-server also reports whether the schema has moved since this client was generated. It needs credentials for that.

The manifest records no timestamp and no checkpoint hash, so two runs that produce identical code produce an identical manifest.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close