-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
4 changed files
with
126 additions
and
89 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
|
||
// This is a simple client that sends a create restaurant command and a change restaurant menu command to the server | ||
|
||
|
||
// Create a restaurant command JSON | ||
const createRestaurantCommandJson = ` | ||
{ | ||
"commandId": "691490bb-c4d3-45b8-99d0-efcf20e353ag", | ||
"decider": "Restaurant", | ||
"kind": "CreateRestaurantCommand", | ||
"id": "691490bb-c4d3-45b8-99d0-efcf20e353ao", | ||
"name": "Eat at Joes", | ||
"menu": { | ||
"menuItems": [ | ||
{"menuItemId": "1", "name": "Salad", "price": "8.99"}, | ||
{"menuItemId": "2", "name": "Soup", "price": "6.99"}, | ||
{"menuItemId": "3", "name": "Steak", "price": "19.99"} | ||
], | ||
"menuId": "34110e19-ca72-45e7-b969-61bebf54da08", | ||
"cuisine": "SERBIAN" | ||
} | ||
} | ||
`; | ||
|
||
// Change restaurant menu command JSON | ||
const changeRestaurantMenuCommandJson = ` | ||
{ | ||
"commandId": "691490bb-c4d3-45b8-99d0-efcf20e353ag", | ||
"decider": "Restaurant", | ||
"kind": "ChangeRestaurantMenuCommand", | ||
"id": "691490bb-c4d3-45b8-99d0-efcf20e353ao", | ||
"menu": { | ||
"menuItems": [ | ||
{"menuItemId": "1", "name": "Salad", "price": "8.99"}, | ||
{"menuItemId": "2", "name": "Soup", "price": "6.99"}, | ||
{"menuItemId": "3", "name": "Steak", "price": "19.99"} | ||
], | ||
"menuId": "34110e19-ca72-45e7-b969-61bebf54da08", | ||
"cuisine": "SERBIAN" | ||
} | ||
} | ||
`; | ||
|
||
// Send the create restaurant command to the server | ||
const createRestaurantCommandResult = await fetch("http://localhost:8000", { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: createRestaurantCommandJson, | ||
}); | ||
|
||
console.log(createRestaurantCommandResult); | ||
|
||
// Send the change restaurant menu command to the server | ||
const changeRestaurantMenuCommandResult = await fetch("http://localhost:8000", { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
body: changeRestaurantMenuCommandJson, | ||
}); | ||
|
||
console.log(changeRestaurantMenuCommandResult); | ||
|
||
|
||
// Run the client : `deno run --allow-net client.ts` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
import { blue } from "std/fmt/colors.ts"; | ||
import { | ||
Command, | ||
Event, | ||
Order, | ||
orderDecider, | ||
Restaurant, | ||
restaurantDecider, | ||
} from "./domain.ts"; | ||
import { Decider, EventSourcingAggregate } from "fmodel"; | ||
import { CommandMetadata, DenoEventRepository } from "./infrastructure.ts"; | ||
import { ApplicationAggregate } from "./application.ts"; | ||
import { commandAndMetadataSchema } from "./schema.ts"; | ||
|
||
// A simple HTTP server that handles commands of all types | ||
Deno.serve(async (request: Request) => { | ||
try { | ||
// Parse the command and metadata from the request / Zod validation/parsing | ||
const command: Command & CommandMetadata = commandAndMetadataSchema.parse( | ||
await request.json(), | ||
); | ||
|
||
console.log(blue("Handling command: "), command); | ||
|
||
// Open the key-value store | ||
const kv = await Deno.openKv(); | ||
// Combine deciders to create a new decider that can handle both restaurant and order commands | ||
const decider: Decider<Command, (Order & Restaurant) | null, Event> = | ||
restaurantDecider.combine(orderDecider); | ||
// Create a repository for the events / a Deno implementation of the IEventRepository | ||
const eventRepository = new DenoEventRepository(kv); | ||
// Create an aggregate to handle the commands of all types / Aggregate is composed of a decider and an event repository | ||
const aggregate: ApplicationAggregate = new EventSourcingAggregate( | ||
decider, | ||
eventRepository, | ||
); | ||
// Handle the commands of all types | ||
const result = await aggregate.handle(command); | ||
console.log(blue("Result of command handling: "), result); | ||
return new Response(JSON.stringify(result, null, 4), { | ||
headers: { "Content-Type": "application/json" }, | ||
status: 200, | ||
}); | ||
} catch (error) { | ||
console.error("Error of command handling: ", error); | ||
return new Response(error?.message ?? error, { | ||
headers: { "Content-Type": "application/json" }, | ||
status: 500, | ||
}); | ||
} | ||
}); | ||
// Run the application server : `deno run --unstable-kv --allow-net server.ts` |