0% found this document useful (0 votes)
2 views23 pages

.NET 8 API with React Traffic Lights

.NET 8 Minimum API and React Frontend article demonstrates how to create a responsive traffic light management system using a React frontend and a .NET 8 Minimal API backend. It outlines the implementation of traffic light logic, state transitions, and real-time updates, emphasizing modern web development practices. The article also provides a step-by-step guide for setting up the necessary projects and code for the application.

Uploaded by

milivoyevich
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views23 pages

.NET 8 API with React Traffic Lights

.NET 8 Minimum API and React Frontend article demonstrates how to create a responsive traffic light management system using a React frontend and a .NET 8 Minimal API backend. It outlines the implementation of traffic light logic, state transitions, and real-time updates, emphasizing modern web development practices. The article also provides a step-by-step guide for setting up the necessary projects and code for the application.

Uploaded by

milivoyevich
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

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

You might also like