This tutorial will show how to build a powerful combination: a React frontend that seamlessly interacts with data from a Jakarta EE REST backend application running as a WildFly bootable JAR.
Prerequisites:
- Node.js and npm (or yarn) installed on your system.
- A basic understanding of React and JAX-RS.
Step # 1 Define the Rest Endpoint
Firstly, bootstrap a Jakarta EE application. You can either use WildFly archetypes ( see Maven archetype for WildFly applications tutorial ) or the Jakarta EE Online Initializer which is available here: https://start.jakarta.ee/
Then, add the following REST Endpoint which returns a List of Person objects with randon names, using the Data Faker Library:
@Path("/persons") public class GettingStartedEndpoint { Faker faker = new Faker(); @GET @Produces(MediaType.APPLICATION_JSON) public List<Person> getPosts() { List<Person> persons = new ArrayList<>(); for (int ii=1;ii<10;ii++) persons.add(new Person(ii, faker.name().fullName())); return persons; } } class Person { public int id; public String fullname; public Person(int id, String fullname) { this.id = id; this.fullname = fullname; } }
Finally, since we want to produce a WildFly bootable JAR from our REST Endpoint, we include the WildFly JAR plugin in the pom.xml:
<plugin> <groupId>org.wildfly.plugins</groupId> <artifactId>wildfly-jar-maven-plugin</artifactId> <version>11.0.2.Final</version> <configuration> <feature-pack-location>wildfly@maven(org.jboss.universe:community-universe)#32.0.0.Final</feature-pack-location> <layers> <layer>jaxrs-server</layer> </layers> <plugin-options> <jboss-fork-embedded>true</jboss-fork-embedded> </plugin-options> <cloud/> <cli-sessions> <cli-session> <script-files> <script>cors.cli</script> </script-files> </cli-session> </cli-sessions> </configuration> <executions> <execution> <goals> <goal>package</goal> </goals> </execution> </executions> </plugin>
As you can see, the Bootable JAR launches a cli-session with the cors.cli command. As a matter of fact, you need to enable CORS (Cross-Origin Resource Sharing) on your Wildfly application when it’s accessed by a React web application hosted on a different domain or port than Wildfly itself. This is because of a browser security feature called the Same-Origin Policy (SOP).
You can learn more about enabling CORS on WildFly in this article: How to configure CORS on WildFly
Within the source code of this project, you will find the cors.cli
script which enables the communication between React and WildFly.
Finish by building the Bootable JAR file with:
mvn install
You can then start the WildFly Bootable JAR application with:
java -jar target/ROOT-bootable.jar
Step # 2 Create the React REST Client
To start a React project, beginners often choose Create React App (CRA) as it offers a pre-configured template for a quick setup. Begin by installing Node.js, then in your terminal, run:
npx create-react-app my-app
The npx
template will create the following project structure:
. ├── node_modules ├── package.json ├── package-lock.json ├── public ├── README.md └── src
The most interesting folder for the purpose of this article is the src. This folder contains both the React entry point (App.js) and the stylesheet file (App.css):
tree src src ├── App.css ├── App.js ├── App.test.js ├── index.css ├── index.js ├── logo.svg ├── reportWebVitals.js └── setupTests.js
Within the App.js file we will code our basic Rest Client using the Fetch API. The Fetch API is a browser API for making asynchronous HTTP requests in the browser.
import React, { useState, useEffect } from 'react'; import './App.css'; const App = () => { const [data, setData] = useState([]); useEffect(() => { const fetchData = async () => { try { const response = await fetch('http://localhost:8080/persons'); const result = await response.json(); setData(result); } catch (error) { console.error('Error fetching data:', error); } }; fetchData(); }, []); return ( <div className="App"> <h1>React with WildFly !</h1> <table border="1"> <thead> <tr> <th>ID</th> <th>Full Name</th> </tr> </thead> <tbody> {data.map((item) => ( <tr key={item.id}> <td>{item.id}</td> <td>{item.fullname}</td> </tr> ))} </tbody> </table> </div> ); }; export default App;
This code utilizes two main React APIs:
- useState:
- This hook manages the component’s state. Here, it’s used to store the fetched data from the API in a state variable named
data
.
- This hook manages the component’s state. Here, it’s used to store the fetched data from the API in a state variable named
- useEffect:
- This hook allows you to perform side effects in your component, such as fetching data. In this case, it fetches data from the
/persons
endpoint on the server (http://localhost:8080/persons
) and updates thedata
state variable with the retrieved information.
- This hook allows you to perform side effects in your component, such as fetching data. In this case, it fetches data from the
Then, we will run the npm install
command to install packages from the npm (Node Package Manager) registry into your Node.js project. These packages can contain reusable code modules, libraries, or tools that enhance your project’s functionality.
npm install
Then, launch your React application with:
npm start
Viewing the REST Endpoint from React
The npm start
command will launch a browser window pointing to localhost:3000
. In this page, you should be able to see the random Person object which are produced by the REST Endpoint:
Hosting the React Application on WildFly
Finally, I want to mention that, as you can see in this excellent tutorial – https://lofthouse.dev/2024/03/07/hosting-a-react-application-on-wildfly/ – it is also possible to deploy the React Application within the WildFly Web application.
For that, you will need to add the frontend-maven-plugin
in your pom.xml. This Maven plugin allows building the React application and including it the war application.
Source code: You can find the source code for this tutorial as usual on GitHub: https://github.com/fmarchioni/mastertheboss/tree/master/web/react/rest-demo