Bike Rental Shop Backend Variants
Compare the synchronized and concurrent BikeRentalShop backends while keeping the same API contract, packaging approach, and web-client integration points.
Full source
Files:
pwsh/tutorial/examples/BikeRentalShop/Synchronized/Service.ps1pwsh/tutorial/examples/BikeRentalShop/Synchronized/Private/State.ps1pwsh/tutorial/examples/BikeRentalShop/Concurrent/Service.ps1pwsh/tutorial/examples/BikeRentalShop/Concurrent/Private/State.ps1
# Start the real BikeRentalShop synchronized and concurrent services directly.
pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Synchronized\Service.ps1 -Port 5443
pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Concurrent\Service.ps1 -Port 5444
Step-by-step
- Entry point: The two backend entry scripts live under
pwsh/tutorial/examples/BikeRentalShop/Synchronized/Service.ps1andpwsh/tutorial/examples/BikeRentalShop/Concurrent/Service.ps1. - Shared contract: Both variants expose the same customer routes, staff routes, API key requirement, and OpenAPI surface.
- Synchronized model: The synchronized backend keeps a familiar PowerShell object graph and serializes compound updates behind one lock.
- Concurrent model: The concurrent backend stores state in concurrent dictionaries but still protects multi-record mutations and persistence with a lock.
- Persistence: Both variants export state under their own
data/folders so restarts preserve bikes and rental history. - Packaging: Both are package-ready services that can be shipped with
New-KrServicePackagewithout rewriting the host script. - Browser compatibility: Both can accept the same
-AllowedCorsOriginsvalues so the standalone web client can target either backend. - Swap story: Because the API shape is stable, clients can move between variants without changing their request payloads or routes.
Try it
Start the synchronized variant:
pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Synchronized\Service.ps1 -Port 5443
Start the concurrent variant:
pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Concurrent\Service.ps1 -Port 5444
Compare the same API calls against both services:
Invoke-RestMethod -Uri 'https://127.0.0.1:5443/api/bikes' -SkipCertificateCheck
Invoke-RestMethod -Uri 'https://127.0.0.1:5444/api/bikes' -SkipCertificateCheck
Invoke-RestMethod -Uri 'https://127.0.0.1:5443/api/staff/dashboard' `
-Headers @{ 'X-Api-Key' = 'bike-shop-demo-key' } `
-SkipCertificateCheck
Invoke-RestMethod -Uri 'https://127.0.0.1:5444/api/staff/dashboard' `
-Headers @{ 'X-Api-Key' = 'bike-shop-demo-key' } `
-SkipCertificateCheck
What changes between the variants
Synchronizedoptimizes for readability and a straightforward PowerShell object model.Concurrentoptimizes for a more explicit concurrent collection story inside the in-memory store.- Both still lock around compound operations like rental creation and returns so inventory and rental records stay consistent.
- Both publish the same external API, which makes them useful for experimentation without breaking callers.
Choosing a backend
- Choose
Synchronizedwhen you want the clearest walkthrough of shared-state initialization, route logic, and persistence. - Choose
Concurrentwhen you want the sample to demonstrate concurrent dictionaries end to end. - Use the standalone
Web/client when you want to compare both backends through the same browser experience.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| The wrong backend is running | The synchronized and concurrent services were started on unexpected ports | Start the exact service script you want to compare and keep the ports distinct |
| The variants behave differently for the same request | Their persisted data/ folders no longer contain the same seed state | Clear or compare the respective data/ folders before re-running the scenario |
| The web client works with one variant but not the other | One backend was started without matching -AllowedCorsOrigins | Start both variants with the same allowed origin list when comparing browser behavior |
| Packaging output differs unexpectedly | You packaged different source folders | Package each backend from its own folder: Synchronized/ or Concurrent/ |
References
- New-KrServicePackage
- Export-KrSharedState
- Import-KrSharedState
- Use-KrLock
- Add-KrApiKeyAuthentication
- Add-KrOpenApiRoute
- Bike Rental Shop Application
Previous / Next
Previous: Bike Rental Shop Web Client Next: Bike Rental Shop Packaging