8.5.24. 21:17 .
NET 8 Minimum API and React Frontend - CodeProject
15,894,180 members 1.6K willywolf
articles quick answers discussions Search for articles, questions, tips
features community help
Articles / Web Development
Watch
C# All-Topics web API Typescript ReactJS C#9.0
.NET8
.NET 8 Minimum API and React
Frontend
Fred Song (Melbourne) Rate me: 4.96/5 (12 votes)
7 May 2024 CPOL 6 min read 12.2K 176 21 2
A responsive React frontend interacts in real-time with a .NET 8 Minimal API
backend to dynamically display and manage state transitions for a simulated traffic
light system.
This article encapsulates how React integrates with a .NET 8 Minimal API to create a
dynamic and responsive traffic light management system, demonstrating modern
web development practices with decoupled architecture for efficient and scalable
application design.
Download source code - 230.5 KB
Introduction
[Link] 1/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
The concept of Minimal APIs in .NET focuses on simplifying the creation of web
APIs by reducing boilerplate code, enabling you to define endpoints more
concisely. These APIs leverage the core features of [Link] Core and are designed
to create HTTP APIs quickly with minimal coding effort. They are ideal for
microservices and small applications where you want to avoid the complexity of a
full MVC application. In [Link] Core Minimal APIs, you can define endpoints
directly in the [Link] file without needing controllers or other scaffolding.
Assume to have 4 sets of lights, as follows.
Lights 1: Traffic is travelling south
Lights 2: Traffic is travelling west
Lights 3: Traffic is travelling north
Lights 4: Traffic is travelling east
The lights in which traffic is travelling on the same axis can be green at the same
time. During normal hours all lights stay green for 20 seconds, but during peak
times north and south lights are green for 40 seconds while west and east are green
for 10 seconds. Peak hours are 08:00 to 10:00 and 17:00 to 19:00. Yellow lights are
shown for 5 seconds before red lights are shown. Red lights stay on until the cross-
traffic is red for at least 4 seconds, once a red light goes off then the green is shown
for the required time.
In this article we implement a React front-end and .Net 8 Minimum API backend.
The backend will contain the logic and state of the running traffic lights. The front-
end will be a visual representation of the traffic lights, with the data served from the
backend.
Create solution with Visual Studio “Standalone
Typescript React Project” template
Prerequisites
Visual Studio 2022 (17.1 or above).
[Link] 18.20 or above
[Link] 2/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
Create React Project
Start Visual Studio 2022, select “Standalone TypeScript React Project”.
[Link] 3/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
When you get to the Additional information windows, check the Add integration for
Empty [Link] Web API Project option. This option adds files to your Angular
template so that it can be hooked up later with the [Link] Core project.
Select this option, proxy will be setup once the project is created. Essentially this
template runs “npx create-react-app” to create a react app.
Create Web API Project
In same solution add [Link] Core Web API project.
[Link] 4/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
Name this backend project as “TrafficLightsAPI”. Select .NET 8.0 for framework.
[Link] 5/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
Please note the template generate Minimum API sample, Weather Forecast in
[Link].
Set the startup project
Right-click the solution and select Set Startup Project. Change the startup project
from Single startup project to Multiple startup projects. Select Start for each
project’s action.
[Link] 6/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
Make sure the backend project and move it above the frontend, so that it starts up
first.
Change client proxy setting
Check APP URL in TrafficLightsAPI https launch profiles UI.
[Link] 7/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
Then open [Link] in your React project root folder. Update
[Link] to [Link] .
Now start the solution by press “F5” or click “Start” button at the top menu.
[Link] 8/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
API Implementation
Let's begin with the backend implementation for the traffic light system using .NET
8. I'll guide you through setting up the necessary models, service logic, and
controllers to manage the traffic lights according to the provided specifications.
Define Models and Enums
First, we'll define the necessary models and enumerations to represent the traffic
lights and their states.
LightState Enum
[Link] 9/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
This enum will represent the possible states of a traffic light.
C#
public enum LightState
{
Green,
Yellow,
Red
}
TrafficLight Model
This model will hold the current state of a traffic light and possibly other properties
related to timing.
C#
public class TrafficLight
{
public string Direction { get; set; } = [Link];
public LightState CurrentState { get; set; }
public string CurrentStateColor => [Link]();
public int GreenDuration { get; set; }
public int YellowDuration { get; set; } = 5;
public DateTime LastTransitionTime { get; set; } // The last state
transition
public bool IsRightTurnActive { get; set; } = false; // Check the
right-turn signal
public int GroupId { get; set; } // 1 for North-South, 2 for East-West
}
Traffic Light Service
This service will handle the logic for timing and state transitions of the traffic lights.
C# Shrink ▲
using [Link];
namespace [Link]
{
public class TrafficLightService
{
private List<TrafficLight> _lights;
public TrafficLightService()
{
[Link] 10/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
var currentDateTime = [Link];
_lights = new List<TrafficLight>
{
new TrafficLight { Direction = "North", GreenDuration = 20,
GroupId = 1, CurrentState = [Link], LastTransitionTime =
currentDateTime },
new TrafficLight { Direction = "South", GreenDuration = 20,
GroupId = 1, CurrentState = [Link], LastTransitionTime =
currentDateTime },
new TrafficLight { Direction = "East", GreenDuration = 20,
GroupId = 2, CurrentState = [Link], LastTransitionTime =
currentDateTime },
new TrafficLight { Direction = "West", GreenDuration = 20,
GroupId = 2, CurrentState = [Link], LastTransitionTime =
currentDateTime }
};
}
public List<TrafficLight> RetrieveLights() => _lights;
public void UpdateLights()
{
lock (_lights)
{
DateTime currentTime = [Link];
bool isPeakHours = IsPeakHours(currentTime);
AdjustSouthboundForNorthRightTurn(currentTime);
foreach (var group in _lights.GroupBy(l => [Link]))
{
bool shouldSwitchToYellow = [Link](l =>
[Link] == [Link] && ShouldSwitchFromGreen((currentTime -
[Link]).TotalSeconds, isPeakHours, [Link]));
bool shouldSwitchToRed = [Link](l => [Link]
== [Link] && (currentTime - [Link]).TotalSeconds
>= 5);
if (shouldSwitchToYellow)
{
foreach (var light in group)
{
if ([Link] == [Link])
{
break;
}
[Link] = [Link];
[Link] = currentTime;
if ([Link] == "North")
{
[Link] = false;
[Link] 11/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
}
}
}
else if (shouldSwitchToRed)
{
foreach (var light in group)
{
[Link] = [Link];
[Link] = currentTime;
}
SetOppositeGroupToGreen([Link]);
}
}
}
}
#region Private Methods
private void SetOppositeGroupToGreen(int groupId)
{
int oppositeGroupId = groupId == 1 ? 2 : 1;
foreach (var light in _lights.Where(l => [Link] ==
oppositeGroupId))
{
[Link] = [Link];
[Link] = [Link];
}
}
private bool IsPeakHours(DateTime time)
{
return ([Link] >= 8 && [Link] < 10) || ([Link] >= 17
&& [Link] < 19);
}
private bool ShouldSwitchFromGreen(double elapsedSeconds, bool
isPeakHours, string direction)
{
int requiredSeconds = direction == "North" || direction ==
"South" ?
isPeakHours ? 40 : 20 :
isPeakHours ? 10 : 20;
return elapsedSeconds >= requiredSeconds;
}
private void AdjustSouthboundForNorthRightTurn(DateTime
currentTime)
{
bool isPeakHours = IsPeakHours(currentTime);
var northLight = _lights.Single(l => [Link] == "North");
[Link] 12/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
if ([Link] == [Link] &&
![Link] && ShouldActivateRightTurn((currentTime -
[Link]).TotalSeconds, isPeakHours))
{
[Link] = true;
foreach (var light in _lights.Where(l => [Link] !=
"North"))
{
if ([Link] != [Link])
{
[Link] = [Link];
[Link] = currentTime;
}
}
}
}
private bool ShouldActivateRightTurn(double elapsedSeconds, bool
isPeakHours)
{
// Activate right-turn signal for the last 10 seconds of the
green phase
int greenDuration = isPeakHours ? 40 : 20;
return elapsedSeconds >= (greenDuration - 10);
}
#endregion
}
}
Minimum API Endpoint
Remove Weather Forecast code which generated from the template. Then setup the
new API endpoints and register services.
C#
using [Link];
var builder = [Link](args);
// Add services to the container.
[Link]<TrafficLightService>();
[Link]<TrafficLightBackgroundService>();
[Link]();
[Link]();
var app = [Link]();
// Configure the HTTP request pipeline.
if ([Link]())
[Link] 13/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
{
[Link]();
[Link]();
}
[Link]();
[Link]("/trafficlights", (TrafficLightService trafficLightService) =>
{
return [Link]([Link]());
}).WithName("GetTrafficLights")
.WithOpenApi();
[Link]();
Background Service to Update Lights
Implementing a background job to automatically update the traffic lights in your
.NET application is an efficient way to simulate a real-time traffic light system. We'll
use a background service that periodically calls the UpdateLights method in the
TrafficLightService. This approach allows the traffic light states to be updated
independently of API requests, simulating real-world behavior where traffic lights
change automatically.
Step 1: Define the Background Service
You can create a background service in .NET by deriving from BackgroundService.
This service will run a timer that triggers the UpdateLights method at regular
intervals.
C# Shrink ▲
using [Link];
using System;
using [Link];
using [Link];
public class TrafficLightBackgroundService : BackgroundService
{
private readonly TrafficLightService _trafficLightService;
private Timer _timer;
public TrafficLightBackgroundService(TrafficLightService
trafficLightService)
{
_trafficLightService = trafficLightService;
}
[Link] 14/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
protected override Task ExecuteAsync(CancellationToken stoppingToken)
{
_timer = new Timer(UpdateTrafficLights, null, [Link],
[Link](1));
return [Link];
}
private void UpdateTrafficLights(object state)
{
_trafficLightService.UpdateLights();
}
public override async Task StopAsync(CancellationToken stoppingToken)
{
_timer?.Change([Link], 0);
await [Link](stoppingToken);
}
}
Step 2: Register the Background Service
In the [Link] or [Link] (depending on your project setup), you need to
register this service so that it starts when your application does:
C#
[Link]<TrafficLightBackgroundService>();
Step 3: Modify TrafficLightService for Thread Safety
Since UpdateLights will now be called from a background service, ensure that any
shared resources within TrafficLightService are accessed in a thread-safe manner.
You might need to lock resources or use concurrent collections if multiple threads
will modify the traffic light states.
C#
public void UpdateLights()
{
lock (_lights)
{
// Existing logic to update lights here
}
}
[Link] 15/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
React Frontend Implementation
Let's start setting up the React frontend with TypeScript to interact with the traffic
light backend you've created. We'll build a simple interface to display the traffic
lights and update them in real-time based on the data received from the backend.
Open traffic-light folder with Visual Studio Code.
Integrating Material-UI (recently rebranded as MUI) with React project will give a
polished look to traffic light system and provide a cohesive user experience.
Install Material-UI
Shell
npm install @mui/material @emotion/react @emotion/styled
Creating the TrafficLight Component
Create a new component to display a single traffic light. This component will
receive props for the current light state and display the appropriate color.
TypeScript Shrink ▲
// src/components/[Link]
import { Paper } from '@mui/material';
import { styled } from '@mui/system';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faArrowsTurnRight } from '@fortawesome/free-solid-svg-icons';
interface TrafficLightProps {
direction: string;
currentState: string;
isRightTurnActive: boolean;
}
const Light = styled(Paper)(({ theme, color }) => ({
height: '100px',
width: '100px',
borderRadius: '50%',
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
backgroundColor: color,
color: [Link],
[Link] 16/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
fontSize: '1.5rem',
fontWeight: 'bold',
margin: '10px'
}));
const TrafficLight: [Link]<TrafficLightProps> = ({ direction,
currentState, isRightTurnActive }) => {
const getColor = (state: string) => {
switch (state) {
case 'Green':
return 'limegreen';
case 'Yellow':
return 'yellow';
case 'Red':
return 'red';
default:
return 'grey'; // default color when state is unknown
}
};
return (
<div>
<Light color={getColor(currentState)} elevation={4}>
{direction}
</Light>
{isRightTurnActive && direction === 'North' && (
<div style={{ color: 'green', marginTop: '10px', fontSize: '24px'
}}>
<FontAwesomeIcon icon={faArrowsTurnRight} /> Turn Right
</div>
)}
</div>
);
};
export default TrafficLight;
Creating the TrafficLightsContainer Component
This component will manage fetching the traffic light states from the backend and
updating the UI accordingly.
TypeScript Shrink ▲
// src/components/[Link]
import React, { useEffect, useState } from 'react';
import TrafficLight from './TrafficLight';
import { Grid } from '@mui/material';
interface TrafficLightData {
direction: string;
[Link] 17/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
currentStateColor: string;
isRightTurnActive: boolean;
}
const TrafficLightsContainer: [Link] = () => {
const [trafficLights, setTrafficLights] = useState<TrafficLightData[]>
([]);
useEffect(() => {
const fetchTrafficLights = async () => {
try {
const response = await fetch('trafficlights');
const data = await [Link]();
setTrafficLights(data);
} catch (error) {
[Link]('Failed to fetch traffic lights', error);
}
};
fetchTrafficLights();
const interval = setInterval(fetchTrafficLights, 1000); // Poll every 5
seconds
return () => clearInterval(interval); // Cleanup on unmount
}, []);
return (
<Grid container justifyContent="center">
{[Link](light => (
<TrafficLight key={[Link]} direction={[Link]}
currentState={[Link]} isRightTurnActive=
{[Link]} />
))}
</Grid>
);
};
export default TrafficLightsContainer;
Update App Component
Update the main App component to include the TrafficLightsContainer.
TypeScript
// src/[Link]
import './[Link]';
import TrafficLightsContainer from './components/TrafficLightsContainer';
import { CssBaseline, Container, Typography } from '@mui/material';
[Link] 18/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
function App() {
return (
<div className="App">
<CssBaseline />
<Container maxWidth="sm">
<header className="App-header">
<Typography variant="h4" component="h1" gutterBottom>
Traffic Lights System
</Typography>
<TrafficLightsContainer />
</header>
</Container>
</div>
);
}
export default App;
Update Service Proxy
Open [Link], change proxy from “/weatherforecast” to “/trafficlights”.
[Link] 19/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
Run the Application
Back to Visual Studio, now the solution looks like this:
[Link] 20/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
Click “Start” button or press F5.
[Link] 21/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
Conclusion
RESTful API Consumption:
The React frontend communicates with the .NET backend via RESTful APIs. This
interaction involves requesting and receiving traffic light data, which React then
uses to update the UI accordingly.
Decoupled Architecture:
[Link] 22/24
8.5.24. 21:17 .NET 8 Minimum API and React Frontend - CodeProject
The frontend and backend are loosely coupled. The backend can operate
independently of the frontend, focusing on logic and data management, while the
frontend focuses on presentation and user interactions. This separation of concerns
enhances the scalability and maintainability of the application.
This article encapsulates how React integrates with a .NET 8 Minimal API to create a
dynamic and responsive traffic light management system, demonstrating modern
web development practices with decoupled architecture for efficient and scalable
application design.
License
This article, along with any associated source code and files, is licensed under The
Code Project Open License (CPOL)
Written By
Fred Song (Melbourne)
Software Developer (Senior)
Australia
Fred is a senior software developer who lives in Melbourne, Australia. In 1993, he
started Programming using Visual C++, Visual Basic, Java, and Oracle Developer
Tools. From 2003, He started with .Net using C#, and then expertise .Net
development.
Fred is often working with software projects in different business domains based on
different Microsoft Technologies like SQL-Server, C#, VC++, [Link], [Link] MVC,
WCF,WPF, Silverlight, .Net Core and Angular, although he also did some
development works on IBM AS400.
Watch
[Link] 23/24