Bike Rental Shop Web Client

Add a standalone Razor Pages frontend that talks to the BikeRentalShop API over HTTP while keeping the backend services focused on API concerns.

Full source

Files:

  • pwsh/tutorial/examples/BikeRentalShop/Web/README.md
  • pwsh/tutorial/examples/BikeRentalShop/Web/Service.ps1
  • pwsh/tutorial/examples/BikeRentalShop/Web/Pages/Index.cshtml
  • pwsh/tutorial/examples/BikeRentalShop/Web/Pages/Operations.cshtml
  • pwsh/tutorial/examples/BikeRentalShop/Web/wwwroot/app.js
# Use the real BikeRentalShop web client from the tutorial examples.
pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Web\Service.ps1 -Port 5445 -Backend Synchronized

Step-by-step

  1. Entry point: The standalone web client source lives at pwsh/tutorial/examples/BikeRentalShop/Web/Service.ps1; run the repo-local script from the checkout when you want to execute it.
  2. Backend selection: The web service accepts Synchronized, Concurrent, or Custom so the same frontend can point at any compatible bike-rental API.
  3. HTTPS: The web client creates or reuses its own development certificate and binds a separate HTTPS listener.
  4. Razor runtime: Add-KrPowerShellRazorPagesRuntime enables page rendering while sibling .cshtml.ps1 scripts build page data per request.
  5. Browser assets: The service exposes site.css and app.js under /static so the frontend stays self-contained.
  6. Page model flow: The service publishes backend metadata into script-scoped variables, and the page model scripts turn that into ClientConfigJson for the browser.
  7. CORS boundary: The browser calls the backend directly, so the backend must allow the web origin with -AllowedCorsOrigins.
  8. Operations flow: The same frontend supports customer booking and staff actions, but protected browser calls still go through the backend API key boundary.

Try it

Start the backend and web client together:

pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Synchronized\Service.ps1 -Port 5443 `
    -AllowedCorsOrigins @('https://127.0.0.1:5445', 'https://localhost:5445')

pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Web\Service.ps1 -Port 5445 -Backend Synchronized

Open the browser-facing routes:

Invoke-WebRequest https://127.0.0.1:5445/ -SkipCertificateCheck | Select-Object StatusCode
Invoke-WebRequest https://127.0.0.1:5445/Operations -SkipCertificateCheck | Select-Object StatusCode
Invoke-WebRequest https://127.0.0.1:5445/static/site.css -SkipCertificateCheck | Select-Object StatusCode

Point the same frontend at the concurrent backend:

pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Concurrent\Service.ps1 -Port 5444 `
    -AllowedCorsOrigins @('https://127.0.0.1:5445', 'https://localhost:5445')

pwsh .\docs\_includes\examples\pwsh\BikeRentalShop\Web\Service.ps1 -Port 5445 -Backend Concurrent

How the web flow works

  1. The web service renders / and /Operations with Razor Pages.
  2. Each page includes a JSON config block with the backend base URL and the API paths the browser should call.
  3. The browser JavaScript loads the live bike catalog, rental health, and staff dashboard from the backend.
  4. Customer booking uses POST /api/rentals, rental lookup uses GET /api/rentals/{rentalId}, and staff actions use the protected /api/staff/* routes.
  5. The backend remains the system of record, so the web client never mutates local state directly.

Why keep the web client separate

  • The backend samples stay focused on routing, persistence, authentication, and OpenAPI.
  • The browser-facing service can evolve its layout, styles, and interaction logic without changing the backend API shape.
  • CORS becomes explicit instead of hidden inside the backend routing layer.
  • The same frontend can be pointed at a package-deployed backend or a custom endpoint by changing startup parameters.

Troubleshooting

Symptom Cause Fix
The home page loads but API calls fail in the browser The backend was not started with the web origin in -AllowedCorsOrigins Start the backend with both https://127.0.0.1:5445 and https://localhost:5445
The page returns but looks unstyled The /static asset routes are unavailable Verify GET /static/site.css succeeds on the web service origin
Browser fetches fail with certificate warnings The dev certificate is not trusted by the browser Accept the certificate in the browser or trust it locally before testing cross-origin calls
The UI points at the wrong backend The -Backend or -ApiBaseUrl startup option is incorrect Restart the web service with -Backend Concurrent, -Backend Synchronized, or -Backend Custom -ApiBaseUrl ...

References


Previous / Next

Previous: Bike Rental Shop Application Next: Bike Rental Shop Backend Variants