Chapter 3

The generator turns source declarations into profile YAML.

This page follows the explicit declaration path in the Go demo. It uses real files from the repo and shows enough surrounding code to make each step clear.

1. The application imports the declaration package

The declarations are regular Go calls. They are intentionally no-op at runtime, but the generator can identify them in the AST.

go/apps/request-logger-http/main.go source
package main

import (
  "context"
  "encoding/json"
  "errors"
  "fmt"
  "net/http"
  "os"
  "strings"

  rc "github.com/colinjlacy/golang-ast-inspection/go/runtimeconditions"
)

type Todo struct {
  ID        int    `json:"id"`
  Title     string `json:"title"`
  Completed bool   `json:"completed"`
}

2. The app declares the runtime integrations it expects

The API declaration names the catalog entry, the HTTP operation the workload calls, the expected response shape, and the environment variable the app reads.

go/apps/request-logger-http/main.go source
func init() {
  rc.API("todos-api",
    rc.Spec("openapi", "catalog://api/default/todos-api", "1.0.0"),
    rc.GET("/todos/{id}", rc.Response[Todo]()),
    rc.Env("baseUrl", "TODOS_API_URL"),
  )

  rc.Cache("request-cache",
    rc.KeyValue(rc.Redis),
    rc.EnvAlternative(rc.Env("url", "REDIS_URL")),
    rc.EnvAlternative(
      rc.Env("hostname", "REDIS_HOST"),
      rc.Env("port", "REDIS_PORT"),
    ),
  )
}

3. The app uses those env vars in normal runtime code

The profile records the names `TODOS_API_URL` and `REDIS_URL`; it does not provide their values. The adapter supplies those later.

go/apps/request-logger-http/main.go source
func checkTodosAPI(ctx context.Context) error {
  baseURL := strings.TrimRight(os.Getenv("TODOS_API_URL"), "/")
  if baseURL == "" {
    return errors.New("TODOS_API_URL is not set")
  }

  request, err := http.NewRequestWithContext(
    ctx,
    http.MethodGet,
    baseURL+"/todos/1",
    nil,
  )
  if err != nil {
    return err
  }
  response, err := http.DefaultClient.Do(request)
  if err != nil {
    return fmt.Errorf("todos-api request failed: %w", err)
  }
  defer response.Body.Close()
  return nil
}

4. The declaration helpers themselves do nothing at runtime

This keeps application behavior unchanged. The generator reads calls to these functions; the compiled service just receives inert values.

go/runtimeconditions/declarations.go source
// API declares an external API dependency.
func API(name string, options ...APIOption) Declaration {
  return Declaration{}
}

// Env declares that a Condition property is supplied through an
// environment variable with the provided name.
func Env(property, name string, options ...EnvOption) ConditionConfigOption {
  return ConditionConfigOption{}
}

// Cache declares a cache dependency.
func Cache(name string, options ...CacheOption) Declaration {
  return Declaration{}
}

5. Run the generator against the app directory

The generator parses the Go AST, finds the declaration calls, resolves their arguments, and emits a Runtime Conditions Profile.

Command
cd go
go run ./profiler/cmd/runtimeconditions \
  -dir ./apps/request-logger-http \
  -name request-logger-http \
  -workload-uri github.com/example/request-logger-http \
  -workload-version v0.1.0

6. The generated profile contains the same requirements

Generated profile excerpt, with full document shape
apiVersion: runtimeconditions.io/v1alpha1
kind: RuntimeConditionsProfile

metadata:
  name: request-logger-http

workload:
  uri: github.com/example/request-logger-http
  version: v0.1.0

extensions:
  - https://runtimeconditions.io/extensions/common-integrations:v1alpha1
  - https://runtimeconditions.io/extensions/env-configuration:v1alpha1

conditions:
  - name: todos-api
    kind: api
    interface:
      type: http
      spec:
        format: openapi
        uri: catalog://api/default/todos-api
        version: 1.0.0
      operations:
        - method: GET
          path: /todos/{id}
    configuration:
      env:
        - property: baseUrl
          name: TODOS_API_URL

  - name: request-cache
    kind: cache
    interface:
      type: key_value
      engine: redis
    configuration:
      alternatives:
        - env:
            - property: url
              name: REDIS_URL