Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions examples/auth-flow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,45 +25,45 @@ flow:
steps:
- from: browser
to: app
data: GET /login
data: The user clicks "Sign in"; the browser asks the app server for the start of the login flow.
- from: app
to: oauth
data: Redirect to Google
data: The app sends the browser over to Google so the user can sign in with their Google account.
- from: oauth
to: app
data:
label: OAuth callback
label: Google bounces the browser back to the app with a one-time authorization code and the original state value so the app can prove this came from the same login attempt.
fields:
- name: code
type: string
- name: state
type: string
- from: app
to: oauth
data: Exchange code for token
data: The app trades the one-time code with Google for the real tokens that represent the signed-in user.
- from: oauth
to: app
data:
label: Token response
label: Google answers with the user's access token, identity token, and email address so the app knows who just signed in.
fields:
- name: access_token
- name: id_token
- name: email
added: true
- from: app
to: [db, cache]
data: Store user + session
data: The app saves the user record in the database and opens a session in the cache so subsequent requests don't have to re-authenticate.
- parallel:
- from: db
to: app
data: user_id
data: The database confirms the write and hands the app this user's stable identifier.
- from: cache
to: app
data: session_id
data: The session cache returns the session identifier the app will use as the cookie value.
- from: app
to: browser
data:
label: Set cookie + redirect
label: The app sets a session cookie on the browser and redirects the user to their original destination.
fields:
- name: session_id
- name: redirect_to
Expand Down
6 changes: 3 additions & 3 deletions examples/create-destroy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ flow:
# Step 1: Queue feeds a job to the dispatcher.
- from: queue
to: dispatcher
data: dequeued job
data: The dispatcher pulls the next pending job off the queue to process it.

# Step 2: Dispatcher spawns a Worker for this job. The Worker
# node doesn't exist in `nodes` above — `create:` brings it
Expand All @@ -29,7 +29,7 @@ flow:
label: Worker
type: service
data:
label: spawn
label: The dispatcher spins up a brand new worker process and hands it this job to handle.
fields:
- name: job_id
type: string
Expand All @@ -38,7 +38,7 @@ flow:
- from: worker
to: dispatcher
data:
label: result
label: The worker finishes the job and reports the outcome back to the dispatcher.
fields:
- name: status
type: string
Expand Down
42 changes: 21 additions & 21 deletions examples/order-flow.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ flow:
- from: validate
to: enrich
data:
label: validated order
label: The validator hands the cleaned-up order to enrichment so missing pricing and tax details can be filled in.
fields:
- name: items
type: "list[OrderItem]"
Expand Down Expand Up @@ -67,7 +67,7 @@ flow:
- from: user
to: api
data:
label: POST /orders
label: The shopper submits a new order with their cart items, account ID, and any coupon they're applying.
fields:
- name: items
type: "list[OrderItem]"
Expand All @@ -79,7 +79,7 @@ flow:
- from: api
to: authz
data:
label: validate session
label: The gateway forwards the user's session credentials to the auth service to confirm they're really signed in.
fields:
- name: auth_token
type: string
Expand All @@ -89,7 +89,7 @@ flow:
- from: authz
to: api
data:
label: auth context
label: The auth service confirms the session is valid and hands back the user's roles so the gateway can decide what they're allowed to do.
fields:
- name: user_id
type: int
Expand All @@ -103,7 +103,7 @@ flow:
- from: api
to: rate-limit
data:
label: rate limit check
label: The gateway asks the rate-limit service whether this user has any quota left for placing orders.
fields:
- name: user_id
type: int
Expand All @@ -113,7 +113,7 @@ flow:
- from: rate-limit
to: api
data:
label: quota approved
label: The rate-limit service approves the request and reports how many orders this user can still place in the current window.
fields:
- name: remaining_requests
type: int
Expand All @@ -123,7 +123,7 @@ flow:
- from: api
to: order-service
data:
label: create order
label: The gateway hands the actual order details to the order service so the real processing can begin.
fields:
- name: items
type: "list[OrderItem]"
Expand All @@ -134,7 +134,7 @@ flow:
- from: authz
to: order-service
data:
label: auth claims
label: At the same time, the auth service forwards the user's verified identity and roles directly to the order service so it doesn't have to re-check.
fields:
- name: user_id
type: int
Expand All @@ -146,7 +146,7 @@ flow:
- from: api
to: order-service
data:
label: gateway trace
label: The gateway also attaches a trace identifier and the edge region it came from so the order service can correlate logs across the request.
fields:
- name: request_id
type: string
Expand All @@ -158,7 +158,7 @@ flow:
- from: order-service
to: [db, cache]
data:
label: persist order
label: The order service persists the finalized order to Postgres and warms the Redis cache so future status lookups are fast.
fields:
- name: order
type: Order
Expand All @@ -172,7 +172,7 @@ flow:
- from: db
to: order-service
data:
label: order saved
label: Postgres confirms the write and returns the new order's identifier and creation timestamp.
fields:
- name: order_id
type: int
Expand All @@ -183,21 +183,21 @@ flow:
- from: cache
to: order-service
data:
label: cache updated
label: Redis confirms the cache entry was stored and is ready to serve.
fields:
- name: cached
type: bool

- from: order-service
to: payment
data:
- label: charge request
- label: The order service asks Stripe to charge the customer's card for the order total.
fields:
- name: amount
type: float
- name: currency
type: string
- label: order context
- label: Alongside the charge, the order service sends the order's context so Stripe can attach it to the transaction for reconciliation later.
fields:
- name: order_id
type: int
Expand All @@ -207,15 +207,15 @@ flow:
- from: payment
to: order-service
data:
- label: payment result
- label: Stripe answers with the result of the charge — the new payment identifier and whether it succeeded.
fields:
- name: payment_id
type: string
added: true
- name: status
type: string
added: true
- label: transaction details
- label: Along with the result, Stripe returns the financial breakdown so the merchant knows how much actually landed in their account after fees.
fields:
- name: amount
type: float
Expand All @@ -235,7 +235,7 @@ flow:
label: Audit Log
type: service
data:
label: log order event
label: The order service spins up a temporary audit logger for this specific transaction so the compliance trail can be written without blocking the response.
fields:
- name: order_id
type: int
Expand All @@ -252,7 +252,7 @@ flow:
- from: order-service
to: events
data:
label: publish order.created
label: The order service publishes an "order created" event to the queue so downstream systems like fulfillment, analytics, and email can react asynchronously.
fields:
- name: order_id
type: int
Expand All @@ -265,7 +265,7 @@ flow:
- from: cron
to: order-service
data:
label: retry stuck orders
label: On a fixed schedule, the retry scheduler sweeps the order service for orders that got stuck and asks it to try them again.
fields:
- name: since
type: datetime
Expand All @@ -275,7 +275,7 @@ flow:
- from: order-service
to: api
data:
label: order response
label: The order service tells the gateway the order is done and returns everything the user needs to see — order ID, total, status, and payment reference.
fields:
- name: order_id
type: int
Expand All @@ -289,7 +289,7 @@ flow:
- from: api
to: user
data:
label: "201 Created"
label: The gateway responds to the shopper confirming their order was placed successfully and shows them the order details.
fields:
- name: order_id
type: int
Expand Down
94 changes: 94 additions & 0 deletions examples/parallel.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
meta:
title: Parallel Fan-out
path: examples/parallel
description: A checkout handler that fires two independent calls at the same tick — reservation + payment — and waits for both to come back before responding

flow:
nodes:
- id: client
label: Client
type: actor
- id: api
label: API
type: endpoint
- id: inventory
label: Inventory
type: service
- id: payment
label: Stripe
type: external
icon: "logos:stripe"
color: "#635BFF"

steps:
- from: client
to: api
data:
label: The shopper kicks off checkout — the API receives the cart items and a one-time payment token together.
fields:
- name: items
type: "list[CartItem]"
- name: card_token
type: string

# Parallel: the API doesn't wait. Both calls leave at the same
# tick — inventory reservation and payment authorization fire
# together. The single-arm version would serialize them; this
# halves the wall-clock for the checkout request.
- parallel:
- from: api
to: inventory
data:
label: The API asks the inventory service to reserve the items in the cart so they can't be oversold while the payment authorization runs.
fields:
- name: items
type: "list[CartItem]"
- name: hold_seconds
type: int
- from: api
to: payment
data:
label: At the same instant the API asks Stripe to authorize the customer's card for the order total.
fields:
- name: amount
type: float
- name: currency
type: string

# Both responses arrive in parallel. The renderer fires the two
# pixels concurrently so you can see "neither side was waiting on
# the other" at a glance. The API can't respond to the client
# until both have landed.
- parallel:
- from: inventory
to: api
data:
label: Inventory confirms the reservation went through and tells the API how long the hold is valid before the items get released back to general stock.
fields:
- name: reservation_id
type: string
added: true
- name: expires_at
type: datetime
added: true
- from: payment
to: api
data:
label: Stripe confirms the authorization succeeded and returns the payment identifier the API will reference when the order eventually settles.
fields:
- name: payment_id
type: string
added: true
- name: status
type: string
added: true

- from: api
to: client
data:
label: With both the reservation and the payment authorization in hand, the API responds to the shopper that checkout completed and returns the new order details.
fields:
- name: order_id
type: int
- name: total
type: float
Loading
Loading