Use a Host from Go
Core's hostclient discovers a Host, checks Form availability, prepares changes and creates or updates resources. For asynchronous responses it waits for the Operation to finish. Start by trying the call sequence against a local HTTP test fixture.
Run locally
Allow about five minutes. You need Go, Git and a network connection for the initial source and dependency downloads. In an existing checkout, run the last two commands from the repository root.
git clone https://github.com/tako0614/takoform.git
cd takoform
go mod download
go test -v ./hostclient -run '^ExampleClient_ApplyResource$' -count=1The test verifies this output and finishes with PASS.
greeting example-uid true
discovery -> availability -> prepare -> applyThe loopback test server uses a fictional Form and fixed responses. It needs no credentials, external service or durable data. It teaches client calls; it is not a deployable Host implementation.
Call the client
func ExampleClient_ApplyResource() {
// A loopback HTTP fixture, not a real resource host. See the helper below.
server, desired, calls := exampleHost()
defer server.Close()
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
defer cancel()
client := hostclient.New(server.URL, "", nil)
if _, err := client.Discover(ctx); err != nil {
panic(err)
}
// An empty fence means create. ApplyResource checks exact availability,
// prepares the request, then applies that review; it also polls a 202.
resource, err := client.ApplyResource(ctx, desired, hostclient.Fence{})
if err != nil {
panic(err)
}
fmt.Println(resource.Metadata.Name, resource.Metadata.UID, hostclient.ResourceReady(resource))
fmt.Println(strings.Join(*calls, " -> "))
// Output:
// greeting example-uid true
// discovery -> availability -> prepare -> apply
}- Pass the Host origin and authentication token to
New. The token is empty in this test. Discoverchecks the API endpoint and required features.ApplyResourcechecks support and admission for the exact FormRef, then uses theprepareresult to create the resource.- This example completes synchronously with
201 Created. If a real Host returns202 Accepted, the same method polls the Operation until completion.
Read the full code, including the fixture server, in hostclient/example_test.go. For wire-format examples, see Host API requests and responses.
Before using a real Host
| Requirement | What to check |
|---|---|
| Host origin and authentication | Obtain these from the Host's documentation. A Form Family namespace is not an endpoint |
| FormRef and settings | Use the exact version and digest from a verified definition, with input matching that definition |
| Space and resource name | Select the scope and name you intend to manage |
| Permission | Confirm that the Host admits the Form and operation for the current caller |
The current hostclient rejects a prepare response that adds omitted defaults. For a Form with defaults, build a Snapshot from the exact package admitted under your trust policy, call Snapshot.Materialize to fill defaults, and pass the result as Resource.Spec. Decode that JSON into map[string]any with formpackage.DecodeStrictIJSON. This workaround addresses schema defaults only. The current client also rejects a changed prepare echo when a Host canonicalizes settings such as hostnames. There is still an implementation gap with Host API v1's required Host-side materialization/canonicalization and client acceptance. The fixture Form on this page has neither defaults nor canonicalization.
Only then replace server.URL, the token and desired. Applying to a real Host changes resources. Keep credentials out of source files and logs.
Handle updates and failures
An empty Fence requests creation. For an update, pass the UID and generation from a retrieved Resource into Fence to avoid overwriting concurrent changes. Do not increment generation by hand.
A timeout does not mean that nothing changed. Inspect the Resource or Operation before retrying. See Host API v1 for the contract, the Host API overview for implementation context and Conformance checks for verification scope.