Every request leaves a visual trace through the exact graph that defines and runs your service. Draw the architecture — it generates the code, executes in production, and shows you everything in real time.
Code is an implementation detail.
Architecture is what matters.
Every system you build starts as a diagram on a whiteboard. Boxes, arrows, flows. That picture is the real design — clean, understandable, true.
Then you translate it into code. And from that moment, the diagram starts lying.
Service Architect keeps the diagram alive. It is the system — not a description of it. What you draw runs in production. What runs in production is what you drew.
Building distributed systems means dealing with complexity that compounds at every layer.
You don't need to understand distributed systems to understand this: your engineering team is spending most of its time building infrastructure nobody sees, instead of features customers pay for.
A new service takes 2–4 weeks before a single business line ships — engineers write HTTP handlers, middleware, configs, metrics, tests from scratch.
The graph generates all of that in seconds. Engineers open a code editor and write only business logic on day one.
Architecture diagrams are drawn once and never updated. Nobody trusts them six months later.
The graph is the architecture. It runs the system. It is always accurate by definition.
When something breaks in production, engineers spend hours reading logs trying to reconstruct what happened.
Every request leaves a visual trace through the graph. The team sees exactly which node failed and what data it held.
Giving a feature to an AI assistant means handing it the entire codebase and hoping it doesn't break anything.
AI gets a single, bounded function with clear inputs and outputs. The scope is enforced by the graph structure.
Ship backend services without a dedicated platform team. Move as fast as a large engineering org from day one.
Standardize how services are built across teams. Eliminate the inconsistency that comes with ten engineers making ten different infrastructure choices.
Reduce the cost of maintaining distributed systems. Get visibility into every service without a dedicated observability team.
The code generation and AI-integration market is growing fast. This is a developer tool with a clear ROI story and zero runtime lock-in.
Not a diagram of the system. Not documentation that will drift. The graph defines, generates, and runs your service — simultaneously.
Model services, pipelines, and connections as a graph. Any process — from a single API endpoint to a complex async workflow — is a node.
The graph generates a complete Go service and runs it. Transport, metrics, tracing, config — all wired from the same definition.
Every request traces through the exact nodes it touched — on the same graph you designed. Architecture and observability are one thing.
// HTTP handler
func processOrderHandler(w http.ResponseWriter, r *http.Request) {
var req ProcessOrderRequest
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
http.Error(w, err.Error(), 400); return
}
ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second)
defer cancel()
orderID := uuid.New().String()
results := make(chan OrderItemResult, len(req.Items))
errs := make(chan error, len(req.Items))
var wg sync.WaitGroup
for _, item := range req.Items {
wg.Add(1)
go func(item OrderItem) {
defer wg.Done()
span, ctx := tracer.StartSpanFromContext(ctx, "inventory.check")
defer span.Finish()
conn, err := grpc.DialContext(ctx, cfg.InventoryAddr,
grpc.WithInsecure(),
grpc.WithUnaryInterceptor(otelgrpc.UnaryClientInterceptor()),
)
if err != nil { errs <- err; return }
defer conn.Close()
client := pb.NewInventoryClient(conn)
res, err := client.ProcessOrderItem(ctx,
&pb.ProcessOrderItemRequest{
Sku: item.SKU, Quantity: int32(item.Qty),
})
if err != nil { errs <- err; return }
results <- OrderItemResult{SKU: item.SKU, Reserved: res.Reserved}
}(item)
}
// deadline ticker
softDeadline := time.NewTimer(cfg.SoftDeadlineDuration)
defer softDeadline.Stop()
var confirmed []OrderItemResult
received := 0
status := "CONFIRMED"
for received < len(req.Items) {
select {
case r := <-results:
confirmed = append(confirmed, r)
if !r.Reserved { status = "PARTIALLY_CONFIRMED" }
received++
case err := <-errs:
log.Error("item error", zap.Error(err))
received++
case <-softDeadline.C:
status = "TIMED_OUT"; goto done
case <-ctx.Done():
status = "TIMED_OUT"; goto done
}
}
done:
// metrics
orderDuration.Observe(time.Since(start).Seconds())
ordersTotal.With(prometheus.Labels{"status": status}).Inc()
w.Header().Set("Content-Type", "application/json")
json.NewEncoder(w).Encode(ProcessOrderResponse{
OrderID: orderID, Status: status,
ConfirmedItems: confirmed,
})
}settings:
name: Example
services:
orderService:
pipelines:
order:
processOrder:
type: Input
endpoint: processOrder
valueType: order
splitPipeline:
type: Split
source: processOrder
softDeadline:
type: Delay
source: splitPipeline
fn: SoftDeadline
processOrderItems:
type: FlatMap
source: splitPipeline
valueType: orderItem
fn: ProcessOrderItems
processOrderItem:
type: Sink
source: processOrderItems
endpoint: processOrderItem
mergeResults:
type: Merge
sources: [mapToOrderState, mapOrderItemResult]Instead of asking AI to generate an entire application — constrain it to one function at a time. The framework handles everything else.
func (f *GetInventoryItemData) Process(
_ context.Context,
_ runtime.Stream,
value *types.OrderItem,
out runtime.Collect[*types.OrderItemResult],
rout runtime.Collect[*types.OrderItemResult],
) {
result, err := f.db.ReserveStock(value.SKU, value.Quantity)
if err != nil || !result.Reserved {
rout.Collect(&types.OrderItemResult{
SKU: value.SKU, Status: "OUT_OF_STOCK",
AvailableQty: result.AvailableQty,
})
return
}
out.Collect(&types.OrderItemResult{
SKU: value.SKU, Reserved: true, Status: "CONFIRMED",
AvailableQty: value.Quantity,
})
}AI stays focused on a single, well-defined function — not an entire application.
Bounded context with clear inputs and outputs means fewer mistakes and cleaner logic.
AI doesn't need to invent infrastructure — it only implements business logic within a strict contract.
10 lines of business logic is easy to review. 2000 lines of generated scaffolding is not.
Execution traces aren't separate from your architecture — they run through the exact graph you drew. Click any node, see every request that touched it, and drill down to the exact values it held.
The trace runs through the exact nodes you designed. No separate trace UI to learn.
Parallel fanout, timeout paths, error streams — all visible as separate branches in the trace, matching graph structure exactly.
See the actual data — inputs, outputs, errors — at each node for any request. No log parsing required.
Tracing, spans, and node-level metrics are generated automatically. You write business logic; traces appear.
Most frameworks generate almost nothing. Service Architect generates an entire operational service — ready to deploy on day one.
The order pipeline example. Graph defined, code generated, service running — with full traces included automatically.
curl -X POST /v1/processorder \
-d '{
"items": [
{ "sku": "ITEM-001", "qty": 2 },
{ "sku": "ITEM-042", "qty": 1 }
]
}'{
"order_id": "ord-9f3a1c",
"status": "CONFIRMED",
"confirmed_items": [
{ "sku": "ITEM-001", "reserved": true },
{ "sku": "ITEM-042", "reserved": true }
],
"trace_id": "d1e2f3a4-bc5d-6789",
"latency_ms": 22
}trace_id gives you full execution visibility across both services — included automatically in every response.| Traditional Development | Service Architect |
|---|---|
| Architecture docs drift from reality | Graph is the source of truth |
| Manual service wiring | Generated automatically |
| Observability added later — or never | Built in from day one |
| AI generates entire uncontrolled apps | AI implements focused functions |
| Debugging means reading logs | Execution graph + full traces |
| Hidden runtime behavior | Visual execution at every level |
The first question backend developers ask: "How is this different from Temporal, Dapr, or Camunda?" Short answer: those are workflow engines — they coordinate long-running processes with a central server. Service Architect is different in kind, not just degree.
| Aspect | Temporal / Dapr / Camunda | Service Architect |
|---|---|---|
| Primary use case | Long-running workflows, sagas, compensation | Request processing pipelines, service orchestration, parallel fanout, event processing |
| Central server | Required (Temporal/Cadence cluster) | None — standard Go binary, no sidecar |
| Observability | Separate UI, separate traces | Architecture graph IS the trace — same diagram |
| Code ownership | Framework controls execution model | You own all generated code, no framework lock-in |
| Architecture source | Lives in code and workflow definitions | Graph is the single source of truth |
Use Temporal when you need sagas, compensation, or durable execution across days. Use Service Architect when you need stream processing pipelines, parallel request fanout, and a system where architecture and observability are the same graph.
No vendor lock-in. No black box. The generated code is standard Go — it belongs to you.
Read, audit, and contribute to the framework.
Generated code is yours. No runtime dependency on us.
Standard Go projects you can build and run anywhere.
Works with any compatible tracing and metrics backend.
A small runtime library coordinates the graph execution. Generated code is standard Go — you own it, build it, deploy it anywhere.
Architecture becomes executable.
Observability becomes the primary interface.
AI focuses on business logic.
Developers focus on system design.
Build distributed applications as executable graphs. Observe every execution. Let AI implement the details.