Documentation

Service Connections

Service connections are the explicit edges between two deployments on the canvas. They tell ZopNight that one deployment depends on another and, optionally, instruct ZopNight to inject the target's connection URL as an environment variable on the source. Connections also drive the canvas topology and the dependency view in failures and rollouts.

Where these routes live

Service connections are owned by the deployer service (table: service_connections). The model and routes survived the Phase 3a–3c catalog/runtime split unchanged.

Why explicit edges?

Without connections, ZopNight has no reliable way to tell a database from a cache from an upstream API just by looking at running pods. Making the edges explicit lets us inject the right env var, render the right topology, and surface the right "this depends on you" warning when you're about to delete something.

Model

FieldTypeDescription
fromDeploymentIDstringThe deployment that depends on the target.
toDeploymentIDstringThe deployment being depended on (database, cache, API).
sourceHintenumHow the connection was created — manual or suggestion (see below).
injectedVarstring?When set, ZopNight injects the target connection URL as this env var on the source. Leave empty to draw the edge without injecting anything.
createdAtstringISO 8601 timestamp.
deletedAtstring?Soft-deletion timestamp. Stored at TIMESTAMP(6) precision so simultaneous deletes don't collide on the unique key.

Source hints

ValueMeaning
manualDrawn by a user on the canvas. Always preserved on re-render.
suggestionInferred by ZopNight (e.g. a deployment refers to checkout-db and a database with that name exists in the same env). Suggested edges render dotted on the canvas until accepted.

Auto-Injection of Connection Variables

When injectedVar is set, ZopNight maintains an env var on the source deployment whose value is the connection URL of the target. The URL is re-resolved each time the target's address changes (LoadBalancer reassigned, port mapping updated, datastore failed over) so the source never holds a stale reference.

Example connection — checkout depends on checkout-dbjson
{
  "fromDeploymentID": "dep_checkout",
  "toDeploymentID": "dep_checkout_db",
  "sourceHint": "manual",
  "injectedVar": "DB_URL"
}

With the connection above in place, the checkout deployment sees DB_URL in its environment, set to a value like postgres://checkout_app:***@checkout-db.zopnight.internal:5432/checkout. You don't fill the value in by hand — ZopNight rotates it when the target's address changes.

Naming is yours

The env var name (DB_URL, POSTGRES_DSN, CHECKOUT_DB_URL) is whatever your code already expects. ZopNight does not impose a naming convention.

Canvas Position

Each deployment carries an optional canvasPosition field ({ x, y }) that persists where you placed its card on the canvas. Layout is per-org and survives page reloads — you don't have to rearrange every visit. Canvas position lives on the deployment catalog row (config), not on the connection.

See Deployments for the full deployment object — canvasPosition is included on the standard deployment GET response and is updated via PATCH /deployments/{id}/canvas-position on config.

Endpoints

Connections live under their environment because they're scoped to the deployments inside it. All CRUD is served by the deployer.

POST
/environments/{envID}/deployments/connections

Create a service connection between two deployments in the environment. (deployer)

Requestbash
curl -X POST https://zopnight.com/api/environments/env_abc/deployments/connections \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{
    "fromDeploymentID": "dep_checkout",
    "toDeploymentID": "dep_checkout_db",
    "sourceHint": "manual",
    "injectedVar": "DB_URL"
  }'
GET
/environments/{envID}/deployments/connections

List every connection in the environment. (deployer)

GET
/environments/{envID}/deployments/connections/{connectionID}

Get a single connection by ID. (deployer)

DELETE
/environments/{envID}/deployments/connections/{connectionID}

Soft-delete a connection. The injected env var stops being maintained on the source deployment's next revision. (deployer)

Cascade behaviour on deployment delete

Connections are not auto-cascaded when one of their endpoints is deleted. The cascade hook that used to soft-delete attached connections at deployment-delete time was disabled in PR #1194 — it's safer to surface the dangling edge to the user than to silently drop a connection that another team may be relying on. You must DELETE the connection explicitly (or accept that the canvas will show a broken edge until you clean it up).

For the dependent deployment surface, see Deployments.