Skip to content

Service graph (modules and layered deployments)

Source: examples/svcgraph/ — one of the domain examples that validated the language on real-world shapes (ROADMAP Phase 5).

deployment.decl
import { Topology, Service } from "./schemas.decl"
export type EnvName = "dev" | "staging" | "prod"
export type Deployment = {
env: EnvName
topology: Topology
public_count = std.array.count(std.array.filter(topology.services, (s) => s.public))
capacity_millis = std.array.fold(topology.services, 0, (a, s) =>
a + s.resources.cpu_millis * s.replicas)
assert prod_is_redundant: (
env != "prod" || std.array.all(topology.services, (s) =>
!s.public || s.replicas >= 2))
else error `every public prod service needs at least 2 replicas`
assert has_a_front_door: public_count >= 1
else warn `no public service in this deployment`
}
main.decl
import { Topology } from "./schemas.decl"
import { Deployment } from "./deployment.decl"
// A reusable topology comes from a constructor func, not a shared
// const: references bind to places, and a module const is not a root
// (§7.5) — each output binds its own copy, so links resolve inside it.
// Environment differences are constructor parameters; `with` layering
// applies to bound records (see docs/examples/02_config.decl).
func front_replicas(prod: bool): int = if prod then 3 else 1
func back_replicas(prod: bool): int = if prod then 2 else 1
func mk_topology(prod: bool): Topology = {
services: [
{ name: "gateway", protocol: "http", port: 8080, public: true, replicas: front_replicas(prod) }
{ name: "auth", protocol: "grpc", port: 9001, resources: { cpu_millis: 1000 }, replicas: back_replicas(prod) }
{ name: "billing", protocol: "grpc", port: 9002, resources: { memory: 512MiB }, replicas: back_replicas(prod) }
{ name: "ledger", protocol: "tcp", port: 5432, resources: { cpu_millis: 2000, memory: 1GiB }, replicas: back_replicas(prod) }
]
links: [
{ source: services[0], target: services[1] }
{ source: services[0], target: services[2], weight: 3 }
{ source: services[2], target: services[3], weight: 5 }
{ source: services[1], target: services[3] }
]
}
export output dev: Deployment = { env: "dev", topology: mk_topology(false) }
export output prod: Deployment = { env: "prod", topology: mk_topology(true) }
schemas.decl
// Service-graph schemas: the API/config benchmark case grown to
// production level (Phase 5) — resource quantities, health checks,
// reverse-reference fan-in, and layered environments.
export type Name = /[a-z][a-z0-9_-]*/
export type Protocol = "http" | "grpc" | "tcp"
export type Resources = {
cpu_millis?: 100..64000 = 500
memory?: quantity<DataSize> = 256MiB
assert memory_floor: memory >= 16MiB
else error `memory below the 16MiB scheduling floor`
}
export type HealthCheck = {
path?: /\/[a-z0-9\/_-]*/ = "/healthz"
interval?: quantity<Time> = 10s
timeout?: quantity<Time> = 2s
assert timely: timeout < interval
else error `health timeout must be shorter than its interval`
}
export type Service = {
name: Name
protocol: Protocol
port: 1024..65535
replicas?: 1..64 = 1
public?: bool = false
resources?: Resources = { }
health?: HealthCheck = { }
endpoint = `${name}:${port}`
inbound = $referrers(Link, "target")
inbound_count = std.array.count(inbound)
assert grpc_ports: protocol != "grpc" || port >= 9000
else warn `grpc service ${name} outside the 9000+ convention`
}
export type Link = {
source: ref<Service>
target: ref<Service>
weight?: 1..100 = 1
}
export type Topology = {
services: Service[1..128]
links?: Link[] = []
service_count = std.array.count(services)
total_replicas = std.array.fold(services, 0, (a, s) => a + s.replicas)
assert unique_names: std.array.all_distinct([s.name for s in services])
else error `service names must be unique`
assert no_self_links: std.array.all(links, (l) =>
std.ref.path(l.source) != std.ref.path(l.target))
else error `a service must not link to itself`
}

What decl evaluate main.decl prints, one section per output.

{
"env": "dev",
"topology": {
"services": [
{
"name": "gateway",
"protocol": "http",
"port": 8080,
"public": true,
"replicas": 1,
"resources": {
"cpu_millis": 500,
"memory": {
"value": 2147483648,
"unit": "bit"
}
},
"health": {
"path": "/healthz",
"interval": {
"value": 10,
"unit": "s"
},
"timeout": {
"value": 2,
"unit": "s"
}
},
"endpoint": "gateway:8080",
"inbound": [],
"inbound_count": 0
},
{
"name": "auth",
"protocol": "grpc",
"port": 9001,
"resources": {
"cpu_millis": 1000,
"memory": {
"value": 2147483648,
"unit": "bit"
}
},
"replicas": 1,
"public": false,
"health": {
"path": "/healthz",
"interval": {
"value": 10,
"unit": "s"
},
"timeout": {
"value": 2,
"unit": "s"
}
},
"endpoint": "auth:9001",
"inbound": [
"$.topology.links[0]"
],
"inbound_count": 1
},
{
"name": "billing",
"protocol": "grpc",
"port": 9002,
"resources": {
"memory": {
"value": 4294967296,
"unit": "bit"
},
"cpu_millis": 500
},
"replicas": 1,
"public": false,
"health": {
"path": "/healthz",
"interval": {
"value": 10,
"unit": "s"
},
"timeout": {
"value": 2,
"unit": "s"
}
},
"endpoint": "billing:9002",
"inbound": [
"$.topology.links[1]"
],
"inbound_count": 1
},
{
"name": "ledger",
"protocol": "tcp",
"port": 5432,
"resources": {
"cpu_millis": 2000,
"memory": {
"value": 8589934592,
"unit": "bit"
}
},
"replicas": 1,
"public": false,
"health": {
"path": "/healthz",
"interval": {
"value": 10,
"unit": "s"
},
"timeout": {
"value": 2,
"unit": "s"
}
},
"endpoint": "ledger:5432",
"inbound": [
"$.topology.links[2]",
"$.topology.links[3]"
],
"inbound_count": 2
}
],
"links": [
{
"source": "$.topology.services[0]",
"target": "$.topology.services[1]",
"weight": 1
},
{
"source": "$.topology.services[0]",
"target": "$.topology.services[2]",
"weight": 3
},
{
"source": "$.topology.services[2]",
"target": "$.topology.services[3]",
"weight": 5
},
{
"source": "$.topology.services[1]",
"target": "$.topology.services[3]",
"weight": 1
}
],
"service_count": 4,
"total_replicas": 4
},
"public_count": 1,
"capacity_millis": 4000
}
{
"env": "prod",
"topology": {
"services": [
{
"name": "gateway",
"protocol": "http",
"port": 8080,
"public": true,
"replicas": 3,
"resources": {
"cpu_millis": 500,
"memory": {
"value": 2147483648,
"unit": "bit"
}
},
"health": {
"path": "/healthz",
"interval": {
"value": 10,
"unit": "s"
},
"timeout": {
"value": 2,
"unit": "s"
}
},
"endpoint": "gateway:8080",
"inbound": [],
"inbound_count": 0
},
{
"name": "auth",
"protocol": "grpc",
"port": 9001,
"resources": {
"cpu_millis": 1000,
"memory": {
"value": 2147483648,
"unit": "bit"
}
},
"replicas": 2,
"public": false,
"health": {
"path": "/healthz",
"interval": {
"value": 10,
"unit": "s"
},
"timeout": {
"value": 2,
"unit": "s"
}
},
"endpoint": "auth:9001",
"inbound": [
"$.topology.links[0]"
],
"inbound_count": 1
},
{
"name": "billing",
"protocol": "grpc",
"port": 9002,
"resources": {
"memory": {
"value": 4294967296,
"unit": "bit"
},
"cpu_millis": 500
},
"replicas": 2,
"public": false,
"health": {
"path": "/healthz",
"interval": {
"value": 10,
"unit": "s"
},
"timeout": {
"value": 2,
"unit": "s"
}
},
"endpoint": "billing:9002",
"inbound": [
"$.topology.links[1]"
],
"inbound_count": 1
},
{
"name": "ledger",
"protocol": "tcp",
"port": 5432,
"resources": {
"cpu_millis": 2000,
"memory": {
"value": 8589934592,
"unit": "bit"
}
},
"replicas": 2,
"public": false,
"health": {
"path": "/healthz",
"interval": {
"value": 10,
"unit": "s"
},
"timeout": {
"value": 2,
"unit": "s"
}
},
"endpoint": "ledger:5432",
"inbound": [
"$.topology.links[2]",
"$.topology.links[3]"
],
"inbound_count": 2
}
],
"links": [
{
"source": "$.topology.services[0]",
"target": "$.topology.services[1]",
"weight": 1
},
{
"source": "$.topology.services[0]",
"target": "$.topology.services[2]",
"weight": 3
},
{
"source": "$.topology.services[2]",
"target": "$.topology.services[3]",
"weight": 5
},
{
"source": "$.topology.services[1]",
"target": "$.topology.services[3]",
"weight": 1
}
],
"service_count": 4,
"total_replicas": 9
},
"public_count": 1,
"capacity_millis": 8500
}

© 2026 Luuvish. Decl is open source under the MIT License.

Type: Literata and IBM Plex, under the SIL Open Font License. Built with Astro Starlight.