4. Route between Components
Add a web shop loader that receives placed orders and never sees cancellations.
Scaffold the loader
Section titled “Scaffold the loader”From the distribution-workspace root (cd .. if you are still in order-notifications/), the same command as chapter 1 with the new names:
intropy int create loader -n WebLoader -o web-loader \ --subscribes order-placed -s topic=orders -s organization=Fluxia -s empty=falseusing cached integrio-intropy/intropy-templates@v2.0.0created web-loader from integrio-intropy/intropy-templates@v2.0.0 (template loader)dependency Contracts already scaffolded from shared-contracts — skippedThe loader has one pipeline, for order-placed. Which messages reach it is decided in the System.
Wire it into the System
Section titled “Wire it into the System”Edit three host files. First add the web shop Port (doc comments omitted here):
public static class Ports{ public static readonly PortRef ErpExtractorSource = PortRef.Define("erp-extractor-source");
public static readonly PortRef WebLoaderDestination = PortRef.Define("web-loader-destination");
public static readonly PortRef WmsLoaderDestination = PortRef.Define("wms-loader-destination");}Then add the Component. The AddLoader name must match the web-loader directory:
public void Define(SystemBuilder builder){ builder.AddExtractor("erp-extractor") .From(Ports.ErpExtractorSource) .Publishes(Messages.OrderPlaced) .Publishes(Messages.OrderCancelled) .Calls(Services.Idempotency) .Calls(Services.BusinessIncidents); builder.AddLoader("web-loader") .Subscribes(Messages.OrderPlaced, configure: sub => sub .IgnoreOthers()) .To(Ports.WebLoaderDestination) .Calls(Services.Idempotency) .Calls(Services.BusinessIncidents); // Rendered as a declarative Dapr Subscription: one routing rule per route, in order, // and a default route for the rest of the topic. The subscription's first message // anchors it; the rest are also handled on the same channel. builder.AddLoader("wms-loader") .Subscribes(Messages.OrderPlaced, configure: sub => sub .AlsoHandles(Messages.OrderCancelled) .IgnoreOthers()) .To(Ports.WmsLoaderDestination) .Calls(Services.Idempotency) .Calls(Services.BusinessIncidents);}Every loader on the topic receives its own copy of every message, so web-loader also receives order-cancelled. Its subscription does not handle that message, so the sidecar delivers it on the default route. IgnoreOthers() acknowledges and drops it. Without IgnoreOthers(), the message stays unacknowledged and the broker dead-letters it.
Last, resolve the new Port to a local folder:
public void Define(DevelopmentBuilder development){ development.Mock(Services.Idempotency).FromOpenApi("mocks/idempotency-service.openapi.yaml"); development.Mock(Services.BusinessIncidents).FromOpenApi("mocks/business-incident-service.openapi.yaml"); development.Files(Ports.ErpExtractorSource).RootPath("./test/erp-extractor-source"); development.Files(Ports.WebLoaderDestination).RootPath("./test/web-loader-destination"); development.Files(Ports.WmsLoaderDestination).RootPath("./test/wms-loader-destination"); development.Rerun("erp-extractor").AfterEachRun(TimeSpan.FromSeconds(30));}No other host files change.
See the routing rule
Section titled “See the routing rule”cd order-notificationstask checktask generatecat out/components/web-loader-subscription.yamltask check ends with:
ok: 'order-notifications' is valid (3 components).apiVersion: dapr.io/v2alpha1kind: Subscriptionmetadata: name: "web-loader-subscription"spec: pubsubname: "order-notifications-pubsub" topic: "orders" routes: rules: - match: "event.type == 'order-placed'" path: "/order-placed" default: "/unhandled"scopes:- "web-loader"Subscribes and AlsoHandles also take a when: argument: a Dapr CEL expression over the event, such as event.data.status == '0', that the sidecar appends to the type match.
Run it
Section titled “Run it”task seedtask runCheck it
Section titled “Check it”In a second terminal, from order-notifications/:
ls test/wms-loader-destination test/web-loader-destinationtest/web-loader-destination:ORD-1001.order-placed.json
test/wms-loader-destination:ORD-1001.order-placed.jsonORD-1002.order-cancelled.jsonwms-loader received both messages. web-loader received only the placed order. The cancellation arrived on its default route and was acknowledged without reaching a pipeline.
Stop the host with Ctrl+C.
Where to go from here
Section titled “Where to go from here”Continue with the transactional integration tutorial to write a Component pipeline step by step. Use Build, connect, deploy when the System is ready to move toward real environments.