Skip to content

Modernize SDK: plain structs + add missing API resources (cron, service connections, integrations, email) - #8

Merged
rusenask merged 8 commits into
masterfrom
refactor/functions-plain-structs
Jul 3, 2026
Merged

Modernize SDK: plain structs + add missing API resources (cron, service connections, integrations, email)#8
rusenask merged 8 commits into
masterfrom
refactor/functions-plain-structs

Conversation

@rusenask

@rusenask rusenask commented Jun 29, 2026

Copy link
Copy Markdown
Member

Brings the Go SDK up to date with the current REST API, in two parts.

Part 1 — drop protobuf, use plain structs

Removed the generated api/reactor/v1 package (the SDK's only protobuf dependency) and replaced the type aliases with plain structs mirroring the backend structs package. Also: go 1.23, io/ioutilio, removed the dead proto Makefile target.

  • Function.IdFunction.ID; Variable now uses created_at/updated_at (time.Time) and drops configuration_ids; Request/Response gain metadata/body_path/modified_body_path.

Part 2 — add missing resources + sync drifted fields

New resources (structs mirror the backend structs package):

File Resource API
crons.go Cron + CRUD /v1/crons
service_connections.go ServiceConnection (GCP/AWS/Azure) + CRUD /v1/service-connections
service_connection_inputs.go ServiceConnectionInput incl. email-to-webhook (EmailInput) /v1/buckets/{id}/service-connection-inputs
service_connection_outputs.go ServiceConnectionOutput incl. Discord/Slack /v1/buckets/{id}/service-connection-outputs
integrations.go IntegrationConfiguration (notifications) + CRUD + add/remove bucket /v1/integrations

Note: "email webhooks" is a service-connection input of type email (no separate resource). The internal /v1/email-inbound endpoint is server-to-server and intentionally not in the SDK.

Synced fields that had drifted on existing resources:

  • Output: cron_id, response_function_id, retries, tls_verification, rules (full rule tree), created_by, durability (DurabilityConfig), throttle (ThrottleConfig)
  • Bucket: static_ip, account_id, cron_id, service_connection_inputs/outputs, integration_configurations; BucketAuth gains id/created_at/updated_at
  • Input: strip_path_prefix, tls_version, legacy_tls, created_by
  • Tunnel: agent_id; Features gains skip_insecure_verify

Breaking changes

Function.IdFunction.ID and the Variable reshape (Part 1). Warrants a minor version bump on the next tag.

Verification

go build ./... ✓ · go vet ./... ✓ · new network-free JSON round-trip unit tests pass (unix-int timestamps on integrations, omitempty pointer sub-configs, time.Duration on durability/throttle, rule tree). Pre-existing integration tests still require a live RELAY_KEY.

🤖 Generated with Claude Code


Note

Medium Risk
Breaking type/auth changes for consumers plus a large API model expansion; behavior changes (force delete, config list parsing) need a minor version bump and careful rollout.

Overview
This PR brings the Go SDK in line with the current REST API: protobuf is removed (generated api/reactor/v1 deleted) and reactor/function types are plain JSON structs with breaking renames (Function.IdID, reshaped Variable timestamps/fields).

Authentication adds NewWithAPIKey (Bearer RELAY_API_KEY), documented in the README; CI and integration tests prefer it over key/secret Basic auth.

New API surface: crons, service connections, service-connection inputs/outputs (including email and Discord/Slack), and integration (notification) configs. Existing models gain fields such as bucket static_ip / nested connections, output durability/throttle/rules, and input TLS options. DeleteBucket now supports ?force=true when inputs/outputs remain.

Tests shift to smoke + httptest unit coverage and a live integration lifecycle; the Makefile drops the dead proto target. Go 1.23 and fewer dependencies (golang/protobuf removed).

Reviewed by Cursor Bugbot for commit d56be76. Bugbot is set up for automated code reviews on this repo. Configure here.

Drop the generated api/reactor/v1 package (the SDK's only protobuf
dependency) and define Function, ExecuteResponse, Request, Response,
Header, Variable and ListConfigResponse as plain structs that mirror the
backend's structs package — the REST API source of truth, which the proto
had drifted from.

- Function.Id -> Function.ID (matches the rest of the SDK)
- Variable now uses created_at/updated_at (time.Time) and drops
  configuration_ids, matching the current backend response
- Request/Response gain metadata/body_path/modified_body_path fields
- go.mod: bump to go 1.23 and drop protobuf deps via go mod tidy
- replace deprecated io/ioutil with io
- remove the now-dead `proto` Makefile target
Comment thread functions.go
Comment thread functions_config.go
…nc drifted fields

Bring the SDK up to date with the current REST API. New resources (structs
mirror the backend structs package, the API source of truth):

- crons.go: Cron + List/Get/Create/Update/Delete (/v1/crons)
- service_connections.go: ServiceConnection (GCP/AWS/Azure) + CRUD
- service_connection_inputs.go: ServiceConnectionInput incl. email-to-webhook
  (EmailInput) + bucket-scoped CRUD
- service_connection_outputs.go: ServiceConnectionOutput incl. Discord/Slack
  + bucket-scoped CRUD
- integrations.go: IntegrationConfiguration (notification configs) + CRUD +
  add/remove bucket

Sync fields that had drifted on existing resources:

- Output: cron_id, response_function_id, retries, tls_verification, rules
  (full rule tree), created_by, durability (DurabilityConfig), throttle
  (ThrottleConfig)
- Bucket: static_ip, account_id, cron_id, service_connection_inputs/outputs,
  integration_configurations; BucketAuth gains id/created_at/updated_at
- Input: strip_path_prefix, tls_version, legacy_tls, created_by
- Tunnel: agent_id; Features gains skip_insecure_verify

Add network-free JSON round-trip unit tests for the new types (unix-int
timestamps on integrations, omitempty pointer sub-configs, time.Duration on
durability/throttle, rule tree).
@rusenask rusenask changed the title Replace reactor/v1 protobuf with plain structs Modernize SDK: plain structs + add missing API resources (cron, service connections, integrations, email) Jun 29, 2026
Add NewWithAPIKey for single-key Bearer authentication alongside the
existing key/secret Basic auth. The test client now prefers RELAY_API_KEY
and falls back to RELAY_KEY/RELAY_SECRET; CI passes RELAY_API_KEY too.

Add TestIntegrationBucketLifecycle exercising the full pipeline against a
live API: bucket, input, output, function + config variables, and the
email service-connection input (email inbox). Live tests now skip cleanly
when no credentials are configured. The email step skips when the feature
is plan-gated.

Add network-free regression tests locking in behavior flagged by review:
Function.Payload round-trips as raw source (not base64) and Variable
timestamps parse from RFC3339 — both matching the backend API contract.

README examples now lead with NewWithAPIKey(RELAY_API_KEY).
Comment thread crons.go
TestListAccessTokens/TestListBuckets asserted on seeded fixtures
(test-token-1/test-bucket-1) that only exist in one account. Now that the
client prefers RELAY_API_KEY, they run against that key's account and the
fixtures aren't present. Relax them to verify listing + auth work and items
are well-formed; real CRUD coverage is in TestIntegrationBucketLifecycle.
Comment thread service_connection_inputs.go
Comment thread crons.go
rusenask added 4 commits July 3, 2026 13:27
Two bugs caught by the new live integration test:

- DeleteBucket ignored BucketDeleteOptions.Force, so the API returned 412
  Precondition Failed for any bucket with inputs/outputs (every bucket has a
  default input). Now sends ?force=true when Force is set.
- ListFunctionConfigurationVariables unmarshalled the response into a wrapper
  object, but the API returns a bare JSON array of variables; it now decodes
  into []*Variable directly.

Add network-free regression tests for both.
Re-fetch the bucket after adding an email service-connection input and
assert the nested resource is present, exercising mixed timestamp formats
(bucket unix seconds + nested RFC3339). Refutes the concern that nested
service-connection resources break bucket decoding.
Name top-level resources created by the live integration tests
test-sdk-go-<kind>-<ns> (e.g. test-sdk-go-bucket-..., test-sdk-go-fn-...)
so they are clearly this SDK's and never mix with the JavaScript SDK's
test resources.
…able

Address Bugbot review feedback by making the read/write paths robust rather
than relying on the current server format:

- Cron, ServiceConnection, ServiceConnectionInput/Output and Variable gain a
  parseTime-based UnmarshalJSON, so they decode timestamps whether the API
  sends unix seconds or RFC3339 strings (matching Bucket/Output/Input).
- Cron gains a MarshalJSON that omits read-only fields (bucket, next_run,
  created_at, updated_at) and zero StartsAt/EndsAt, so CreateCron/UpdateCron
  no longer send an empty bucket object or year-1 time bounds.

Add network-free unit tests for both directions and a live
TestIntegrationCronLifecycle (create/get/list/delete) verifying the cron
payload is accepted end-to-end.

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit d56be76. Configure here.

Comment thread integrations.go
CreatedAt: d.CreatedAt.Unix(),
UpdatedAt: d.UpdatedAt.Unix(),
Alias: (*Alias)(d),
})

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Integration create sends bogus timestamps

Medium Severity

IntegrationConfiguration.MarshalJSON always encodes created_at and updated_at from time.Time.Unix(), including when those fields are zero. CreateIntegration (and updates built from a fresh struct) therefore POST/PUT bodies with large negative unix timestamps instead of omitting read-only times, unlike the new Cron writer which omits them on create/update.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit d56be76. Configure here.

@rusenask
rusenask merged commit da6996f into master Jul 3, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant