DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Building REST API Backend Easily With Ballerina Language
  • Creating a Secure REST API in Node.js
  • Enable Background Sync, Media Capture, and Geolocation APIs in Your PWA
  • The Cypress Edge: Next-Level Testing Strategies for React Developers

Trending

  • Automatic Code Transformation With OpenRewrite
  • Is Agile Right for Every Project? When To Use It and When To Avoid It
  • Event-Driven Architectures: Designing Scalable and Resilient Cloud Solutions
  • Testing SingleStore's MCP Server
  1. DZone
  2. Coding
  3. JavaScript
  4. Consuming REST APIs With React.js

Consuming REST APIs With React.js

In this post, we go through a tutorial on how to create a React application that can perform CRUD functions and take in data from a RESTful API.

By 
Sergiy Pylypets user avatar
Sergiy Pylypets
DZone Core CORE ·
Updated Nov. 02, 20 · Tutorial
Likes (20)
Comment
Save
Tweet
Share
271.1K Views

Join the DZone community and get the full member experience.

Join For Free

Recently we have experienced rapid growth of mobile, Internet-based communication. We have smartphones, tablets, netbooks, and other connected devices that create a need to serve appropriate content for each specific front-end profile. Also, the Internet is becoming available for new regions and social groups, constantly increasing web traffic. On the other side, users' computers and browsers, and JavaScript itself are getting more and more powerful, providing more possibilities for processing data on the web via the client-side. In this situation, the best solution can often be to send data as the response, instead of sending page content. That is, we don't need to reload the whole page on each request, but send back the corresponding data and let the client (front-end stuff) process the data.

We can develop a backend application exposing a remote API (usually based on the REST protocol) and a front-end (usually JavaScript) application, which communicates with the API and renders all the data on the device.

If backend data is consumed by humans, we need to develop a user interface (UI) to provide the possibility for users to manage the data. Modern web applications should have responsive and friendly UIs, ensuring adequate user experience. Also, modern UIs can be arbitrarily complex, with multi-panel, nested layouts, paging, progress bars, etc. In this case, the component model can be the right solution. React.js is a light-weight JavaScript framework, which is oriented toward the creation of component-based web UIs. React doesn't provide any means for communicating with the backend, but we can use any communication library from inside React components.

As an example, we can develop a simple React application consuming the REST API we created in a previous article. The API provides methods to use an online collection management application. Now our task is to develop a web UI to use these methods.

Before starting development, we need to set up a React.js development environment.

1. React.js Development Environment Set Up

There are several ways to use React.js. The simplest way is just to include React libraries in the <script> tags on the page. 

Listing 1.1. Including the React.js library in the HTML page:

HTML
xxxxxxxxxx
1
13
 
1
<!DOCTYPE html>
2
<html lang="en" dir="ltr">
3
  <head>
4
    <meta charset="utf-8">
5
    <title></title>
6
  </head>
7
  <body>
8
    <div id="hello_container" class=""></div>
9
    
10
    
11
    
12
  </body>
13
</html>


This way, we can very quickly start developing React applications, but we cannot use certain advanced features, like JSX, for example. So, a more appropriate solution, especially for large and sophisticated applications, would be to use the  create-react-app tool. To install it, you need Node.js and npm to be installed on your computer: npm install -g create-react-app 

Then you can run the following command in the root directory, where you want to create your project:

 .../project-root>npx create-react-app consuming-rest

This command creates a new folder ('consuming-rest') with a ready-to-run prototype React application.

Now we can enter the directory and run the application, as follows:

 .../project-root>cd consuming-rest

.../project-root/consuming-rest>npm start

 This starts the application in a new browser at http://localhost:3000:

React.js application

It is a trivial but completely functional front-end application, which we can use as a prototype for creating our UI.

Initially, we can implement a data service to communicate with the server.

2. Backend Communication Service Implementation

In general, it is a good idea to put all related functionalities in one place. Putting our functionality behind a service which exposes certain APIs ensures more flexibility and testability for our application. So, we create a communication service class, which implements all basic CRUD operations for data exchange with the server and exposes these operations as methods for all React components. To make our UI more responsive, we implement the methods as asynchronous. Provided the API is unchanged, we can change the implementation freely and none of the consumers will be affected. To put these concepts into practice, let's create a mock implementation of the service, which provides mock data for building and testing our UI. Our mock service can look like this.

Listing 2.1.  src/shared/mock-item-service.js – mock ItemService:

JavaScript
xxxxxxxxxx
1
42
 
1
class ItemService {
2

          
3
  constructor() {
4
    this.items = [
5
      {link:1, name:"test1", summary:"Summary Test 1", year:"2001", country:"us", price:"1000", description:"Desc 1"},
6
      {link:2, name:"test2", summary:"Summary Test 2", year:"2002", country:"uk", price:"2000", description:"Desc 2"},
7
      {link:3, name:"test3", summary:"Summary Test 3", year:"2003", country:"cz", price:"3000", description:"Desc 3"},
8
    ];
9
  }
10

          
11
  async retrieveItems() {
12
      return Promise.resolve(this.items);
13
  }
14

          
15
  async getItem(itemLink) {
16
    for(var i = 0; i < this.items.length; i++) {
17
      if ( this.items[i].link === itemLink) {
18
        return Promise.resolve(this.items[i]);
19
      }
20
    }
21
    return null;
22
  }
23

          
24
  async createItem(item) {
25
    console.log("ItemService.createItem():");
26
    console.log(item);
27
    return Promise.resolve(item);
28
  }
29

          
30
  async deleteItem(itemId) {
31
    console.log("ItemService.deleteItem():");
32
    console.log("item ID:" + itemId);
33
  }
34

          
35
  async updateItem(item) {
36
    console.log("ItemService.updateItem():");
37
    console.log(item);
38
  }
39

          
40
}
41

          
42
export default ItemService;


Based on this, we can build the UI.

3. CRUD UI Implementation

React supports component hierarchies, where each component can have a state and the state can be shared between related components. Also, each component's behavior can be customized by passing properties to it. So, we can develop the main component, which contains the list of collection items and works as the placeholder for displaying forms for corresponding CRUD actions. Using the stuff generated by the create-react-app tool, we change the content of app.js as follows.

Listing 3.1. src/App.js – the main component as the application frame:

JavaScript
xxxxxxxxxx
1
140
 
1
import React, { Component } from 'react';
2
import './App.css';
3
import ItemDetails from './item-details';
4
import NewItem from './new-item';
5
import EditItem from './edit-item';
6
import ItemService from './shared/mock-item-service';
7

          
8
class App extends Component {
9

          
10
  constructor(props) {
11
    super(props);
12
    this.itemService = new ItemService();
13
    this.onSelect = this.onSelect.bind(this);
14
    this.onNewItem = this.onNewItem.bind(this);
15
    this.onEditItem = this.onEditItem.bind(this);
16
    this.onCancel = this.onCancel.bind(this);
17
    this.onCancelEdit = this.onCancelEdit.bind(this);
18
    this.onCreateItem = this.onCreateItem.bind(this);
19
    this.onUpdateItem = this.onUpdateItem.bind(this);
20
    this.onDeleteItem = this.onDeleteItem.bind(this);
21
    this.state = {
22
      showDetails: false,
23
      editItem: false,
24
      selectedItem: null,
25
      newItem: null
26
    }
27
  }
28

          
29
  componentDidMount() {
30
      this.getItems();
31
  }
32

          
33
  render() {
34
    const items = this.state.items;
35
    if(!items) return null;
36
    const showDetails = this.state.showDetails;
37
    const selectedItem = this.state.selectedItem;
38
    const newItem = this.state.newItem;
39
    const editItem = this.state.editItem;
40
    const listItems = items.map((item) =>
41
      <li key={item.link} onClick={() => this.onSelect(item.link)}>
42
         <span className="item-name">{item.name}</span> |  {item.summary}
43
      </li>
44
    );
45

          
46
    return (
47
      <div className="App">
48
          <ul className="items">
49
            {listItems}
50
          </ul>
51
          <br/>
52
          <button type="button" name="button" onClick={() => this.onNewItem()}>New Item</button>
53
          <br/>
54
            {newItem && <NewItem onSubmit={this.onCreateItem} onCancel={this.onCancel}></NewItem>}
55
            {showDetails && selectedItem && <ItemDetails item={selectedItem} onEdit={this.onEditItem}  onDelete={this.onDeleteItem} ></ItemDetails>}
56
            {editItem && selectedItem && <EditItem onSubmit={this.onUpdateItem} onCancel={this.onCancelEdit} item={selectedItem} ></EditItem>}
57
      </div>
58
    );
59
  }
60

          
61
  getItems() {
62
    this.itemService.retrieveItems().then(items => {
63
          this.setState({items: items});
64
        }
65
    );
66
  }
67

          
68
  onSelect(itemLink) {
69
    this.clearState();
70
    this.itemService.getItem(itemLink).then(item => {
71
      this.setState({
72
          showDetails: true,
73
          selectedItem: item
74
        });
75
      }
76
    );
77
  }
78

          
79
  onCancel() {
80
    this.clearState();
81
  }
82

          
83
  onNewItem() {
84
    this.clearState();
85
    this.setState({
86
      newItem: true
87
    });
88
  }
89

          
90
  onEditItem() {
91
    this.setState({
92
      showDetails: false,
93
      editItem: true,
94
      newItem: null
95
    });
96
  }
97

          
98
  onCancelEdit() {
99
    this.setState({
100
      showDetails: true,
101
      editItem: false,
102
      newItem: null
103
    });
104
  }
105

          
106
  onUpdateItem(item) {
107
    this.clearState();
108
    this.itemService.updateItem(item).then(item => {
109
        this.getItems();
110
      }
111
    );
112
  }
113

          
114
  onCreateItem(newItem) {
115
    this.clearState();
116
    this.itemService.createItem(newItem).then(item => {
117
        this.getItems();
118
      }
119
    );
120
  }
121

          
122
  onDeleteItem(itemLink) {
123
    this.clearState();
124
    this.itemService.deleteItem(itemLink).then(res => {
125
        this.getItems();
126
      }
127
    );
128
  }
129

          
130
  clearState() {
131
    this.setState({
132
      showDetails: false,
133
      selectedItem: null,
134
      editItem: false,
135
      newItem: null
136
    });
137
  }
138
}
139

          
140
export default App;


Note that, for now, our app component uses the mock service we created in section 2:

. . .

import ItemService from './shared/mock-item-service';

. . .

Then we will create nested components for basic operations with collection items.

Listing 3.2. src/new-item.js – creating new collection items:

JavaScript
xxxxxxxxxx
1
79
 
1
import React, { Component } from 'react';
2
import './App.css';
3
import Validator from './shared/validator';
4

          
5
class NewItem extends Component {
6

          
7
  constructor(props) {
8
    super(props);
9
    this.validator = new Validator();
10
    this.onCancel = this.onCancel.bind(this);
11
    this.onSubmit = this.onSubmit.bind(this);
12
    this.handleInputChange = this.handleInputChange.bind(this);
13
    this.state = {
14
      name: '',
15
      summary: '',
16
      year: '',
17
      country: '',
18
      description: ''
19
    };
20
  }
21

          
22
  handleInputChange(event) {
23
    const target = event.target;
24
    const value = target.value;
25
    const name = target.name;
26

          
27
    this.setState({
28
      [name]: value
29
    });
30
  }
31

          
32
  onCancel() {
33
    this.props.onCancel();
34
  }
35

          
36
  onSubmit() {
37
    if(this.validator.validateInputs(this.state)) {
38
        this.props.onSubmit(this.state);
39
    }
40
  }
41

          
42
  render() {
43
    return (
44
      <div className="input-panel">
45
      <span className="form-caption">New item:</span>
46
      <div>
47
        <label className="field-name">Name:<br/>
48
          <input value={this.state.name} name="name" maxLength="40" required onChange={this.handleInputChange} placeholder="item name" />
49
        </label>
50
      </div>
51
      <div>
52
        <label className="field-name">Summary:<br/>
53
          <input value={this.state.summary} name="summary" maxLength="40" required onChange={this.handleInputChange} placeholder="summary" />
54
        </label>
55
      </div>
56
      <div>
57
        <label className="field-name">Year:<br/>
58
          <input value={this.state.year} name="year" maxLength="4" pattern="[0-9]{1,4}" onChange={this.handleInputChange} placeholder="year" />
59
        </label>
60
      </div>
61
      <div>
62
        <label className="field-name">Country:<br/>
63
          <input value={this.state.country} name="country" maxLength="2" pattern="[a-z|A-Z]{2}" onChange={this.handleInputChange} placeholder="country code" />
64
        </label>
65
      </div>
66
      <div>
67
        <label className="field-name">Description:<br/>
68
          <textarea value={this.state.description} name="description" onChange={this.handleInputChange} placeholder="description" />
69
        </label>
70
      </div>
71
      <br/>
72
      <button onClick={() => this.onCancel()}>Cancel</button> 
73
      <button onClick={() => this.onSubmit()}>Create</button>
74
      </div>
75
    );
76
  }
77
}
78

          
79
export default NewItem;


In Listing 3.2, we use the validator class, which provides a simple validation for newly created or edited collection items. This class can be shared between components, i.e. it can be used in NewItem and EditItem components in our case.

Listing 3.3. src/shared/validatior.js – a simple validation for the item form:

JavaScript
xxxxxxxxxx
1
26
 
1
class Validator {
2

          
3
  validateInputs(inputData) {
4
    let errorMsg = "";
5
    if(!inputData.name) {
6
      errorMsg +="Please enter name of this item.\n"
7
    }
8
    if(!inputData.summary) {
9
      errorMsg +="Please enter summary of this item.\n"
10
    }
11
    if(inputData.year.toString().match(/[^0-9]/g)) {
12
      errorMsg +="Year must be a number.\n"
13
    }
14
    if(inputData.country.length > 0 && !inputData.country.match(/^[a-z|A-Z][a-z|A-Z]$/)) {
15
      errorMsg +="Country code must be two letters.\n"
16
    }
17
    if(errorMsg.length == 0){
18
      return true;
19
    } else {
20
      alert(errorMsg);
21
      return false;
22
    }
23
  }
24
}
25

          
26
export default Validator;


Listing 3.4. src/item-details.js – viewing item details:

JavaScript
 
xxxxxxxxxx
1
42
 
1
import React, { Component } from 'react';
2
import './App.css';
3

          
4
class ItemDetails extends Component {
5

          
6
  constructor(props) {
7
    super(props);
8
    this.onEdit = this.onEdit.bind(this);
9
    this.onDelete = this.onDelete.bind(this);
10
  }
11

          
12
  render() {
13
    const item = this.props.item;
14
    return (
15
      <div className="input-panel">
16
      <span className="form-caption">{ item.name}</span>
17
      <div><span className="field-name">Name:</span><br/> {item.name}</div>
18
      <div><span className="field-name">Summary:</span><br/> {item.summary}</div>
19
      <div><span className="field-name">Year:</span><br/> {item.year}</div>
20
      <div><span className="field-name">Country:</span><br/> {item.country}</div>
21
      <div><span className="field-name">Description:</span><br/> {item.description}</div>
22
      <br/>
23
      <button onClick={() => this.onDelete()}>Delete</button> 
24
      <button onClick={() => this.onEdit()}>Edit</button>
25
      </div>
26
    );
27
  }
28

          
29
  onEdit() {
30
    this.props.onEdit();
31
  }
32

          
33
  onDelete() {
34
    const item = this.props.item;
35
    if(window.confirm("Are you sure to delete item: " + item.name + " ?")) {
36
      this.props.onDelete(item.link);
37
    }
38
  }
39

          
40
}
41

          
42
export default ItemDetails;


Listing 3.5. src/edit-item.js – editing existing items:

JavaScript
 
xxxxxxxxxx
1
81
 
1
import React, { Component } from 'react';
2
import './App.css';
3
import Validator from './shared/validator';
4

          
5
class EditItem extends Component {
6

          
7
  constructor(props) {
8
    super(props);
9
    this.validator = new Validator();
10
    this.onCancel = this.onCancel.bind(this);
11
    this.onSubmit = this.onSubmit.bind(this);
12
    this.handleInputChange = this.handleInputChange.bind(this);
13
    const itemToEdit = props.item;
14
    this.state = {
15
      name: itemToEdit.name,
16
      summary: itemToEdit.summary,
17
      year: itemToEdit.year,
18
      country: itemToEdit.country,
19
      description: itemToEdit.description,
20
      link: itemToEdit.link
21
    };
22
  }
23

          
24
  handleInputChange(event) {
25
    const target = event.target;
26
    const value = target.value;
27
    const name = target.name;
28

          
29
    this.setState({
30
      [name]: value
31
    });
32
  }
33

          
34
  onCancel() {
35
    this.props.onCancel();
36
  }
37

          
38
  onSubmit() {
39
    if (this.validator.validateInputs(this.state)) {
40
      this.props.onSubmit(this.state);
41
    }
42
  }
43

          
44
  render() {
45
    return (
46
      <div className="input-panel">
47
      <span className="form-caption">Edit item:</span> <span>{this.state.name}</span>
48
      <div>
49
        <label className="field-name">Name:<br/>
50
          <input value={this.state.name} name="name" maxLength="40" required onChange={this.handleInputChange} placeholder="item name" />
51
        </label>
52
      </div>
53
      <div>
54
        <label className="field-name">Summary:<br/>
55
          <input value={this.state.summary} name="summary" maxLength="40" required onChange={this.handleInputChange} placeholder="summary" />
56
        </label>
57
      </div>
58
      <div>
59
        <label className="field-name">Year:<br/>
60
          <input value={this.state.year} name="year" maxLength="4" pattern="[0-9]{1,4}" onChange={this.handleInputChange} placeholder="year" />
61
        </label>
62
      </div>
63
      <div>
64
        <label className="field-name">Country:<br/>
65
          <input value={this.state.country} name="country" maxLength="2" pattern="[a-z|A-Z]{2}" onChange={this.handleInputChange} placeholder="country" />
66
        </label>
67
      </div>
68
      <div>
69
        <label className="field-name">Description:<br/>
70
          <textarea value={this.state.description} name="description" onChange={this.handleInputChange} placeholder="description" />
71
        </label>
72
      </div>
73
      <br/>
74
      <button onClick={() => this.onCancel()}>Cancel</button> 
75
      <button onClick={() => this.onSubmit()}>Update</button>
76
      </div>
77
    );
78
  }
79
}
80

          
81
export default EditItem;


Here we use the lifting-state-up approach. Instead of maintaining state in each child component and synchronizing the states, and hence the appearance of related components, we lift the shared state up to their closest common ancestor. So, we maintain state in the parent app component with the usage of callback functions which are passed to child components via properties. Then we call the callback functions inside event handlers in the child components. In these functions, we change the parent component state correspondingly to the user actions triggered in the child components. Based on the parent component state change, React rerenders child components, if appropriate. For example, see how theApp.onEditItem() method is called in theItemDetails.onEdit() event handler, which is triggered when the user clicks the Edit button.

This way, we have one-point state management that makes our UI model more consistent.

Note: Redux technology provides an even more consistent and effective way of managing component model state, especially in large applications.

Provided we have all the scripts in place, we can see the main application at http://localhost:3000:

React.js applicationBy clicking on an item in the list, we can see the item details:

React.js application

If we need to edit an item, we can make the detail view editable with the Edit button:

React.js application

Also, we can add new items with the New Item button:

React.js application

To have our UI really functional, we need to make it exchange data with the backend.

4. Real Communication

While React doesn't provide any built-in support for sending requests to the server, we are free to use any communication library inside our React applications. Let's use Fetch API, which is becoming a standard way to send HTTP requests and is supported in most modern browsers. Provided we have our communication interface defined, we can easily substitute our mock service implementation (see section 2) with a fully functional version, like the following.

Listing 4.1. src/shared/item-service.js – real functional version of ItemService:

JavaScript
xxxxxxxxxx
1
123
 
1
import Configuration from './configuration';
2

          
3
class ItemService {
4

          
5
  constructor() {
6
    this.config = new Configuration();
7
  }
8

          
9
  async retrieveItems() {
10
    return fetch(this.config.ITEM_COLLECTION_URL)
11
      .then(response => {
12
        if (!response.ok) {
13
          this.handleResponseError(response);
14
        }
15
        return response.json();
16
      })
17
      .then(json => {
18
        console.log("Retrieved items:");
19
        console.log(json);
20
        const items = [];
21
        const itemArray = json._embedded.collectionItems;
22
        for(var i = 0; i < itemArray.length; i++) {
23
          itemArray[i]["link"] =  itemArray[i]._links.self.href;
24
          items.push(itemArray[i]);
25
        }
26
        return items;
27
      })
28
      .catch(error => {
29
        this.handleError(error);
30
      });
31
  }
32

          
33
  async getItem(itemLink) {
34
    console.log("ItemService.getItem():");
35
    console.log("Item: " + itemLink);
36
    return fetch(itemLink)
37
      .then(response => {
38
        if (!response.ok) {
39
            this.handleResponseError(response);
40
        }
41
        return response.json();
42
      })
43
      .then(item => {
44
          item["link"] = item._links.self.href;
45
          return item;
46
        }
47
      )
48
      .catch(error => {
49
        this.handleError(error);
50
      });
51
  }
52

          
53
  async createItem(newitem) {
54
    console.log("ItemService.createItem():");
55
    console.log(newitem);
56
    return fetch(this.config.ITEM_COLLECTION_URL, {
57
      method: "POST",
58
      mode: "cors",
59
      headers: {
60
            "Content-Type": "application/json"
61
        },
62
      body: JSON.stringify(newitem)
63
    })
64
      .then(response => {
65
       if (!response.ok) {
66
            this.handleResponseError(response);
67
        }
68
        return response.json();
69
      })
70
      .catch(error => {
71
        this.handleError(error);
72
      });
73
  }
74

          
75
  async deleteItem(itemlink) {
76
    console.log("ItemService.deleteItem():");
77
    console.log("item: " + itemlink);
78
    return fetch(itemlink, {
79
      method: "DELETE",
80
      mode: "cors"
81
    })
82
      .then(response => {
83
        if (!response.ok) {
84
            this.handleResponseError(response);
85
        }
86
      })
87
      .catch(error => {
88
        this.handleError(error);
89
      });
90
  }
91

          
92
  async updateItem(item) {
93
    console.log("ItemService.updateItem():");
94
    console.log(item);
95
    return fetch(item.link, {
96
      method: "PUT",
97
      mode: "cors",
98
      headers: {
99
            "Content-Type": "application/json"
100
          },
101
      body: JSON.stringify(item)
102
    })
103
      .then(response => {
104
        if (!response.ok) {
105
          this.handleResponseError(response);
106
        }
107
        return response.json();
108
      })
109
      .catch(error => {
110
        this.handleError(error);
111
      });
112
  }
113

          
114
  handleResponseError(response) {
115
      throw new Error("HTTP error, status = " + response.status);
116
  }
117

          
118
  handleError(error) {
119
      console.log(error.message);
120
  }
121

          
122
}
123
export default ItemService;

Here we also follow the single-responsibility principle and put all configuration settings into one object, Configuration, which can be imported into all relevant components.

Now we have all the basic modules developed and can put all the things together and run our application.

5. Running the Front-End Application

Provided we have our backend running on http://localhost:8080, we can set its URL in the configuration class.

Listing 5.1. Configuration class – one-point application configuration:

JavaScript
x
 
1
class Configuration {
2

          
3
  ITEM_COLLECTION_URL = "http://localhost:8080/collectionItems";
4

          
5
}
6
export default Configuration;

And start up our application:

.../project-root/consuming-rest>npm start

This time, we see the main application screen with real data from the backend:

React.js application

We can add new items, like the following screenshot illustrates:

React.js application

New item added:

React.js application

So, we have developed a fully functional web application, which supports main collection management operations, i.e. the ability to add, view, update, and delete items. The source code for this article is available at https://github.com/spylypets/consuming-rest. Using the React component model, we can create sophisticated UIs with nested, multi-page views, providing a rich user experience. More details can be found at the React.js official site and sites for related technologies, like:

  • Redux - state management library.

  • Formik - HTML form support library.

  • Jest - Testing React applications.



If you enjoyed this article and want to learn more about React, check out this collection of tutorials and articles on all things React.

REST Web Protocols mobile app Listing (computer) React (JavaScript library) Data (computing) JavaScript Web Service

Opinions expressed by DZone contributors are their own.

Related

  • Building REST API Backend Easily With Ballerina Language
  • Creating a Secure REST API in Node.js
  • Enable Background Sync, Media Capture, and Geolocation APIs in Your PWA
  • The Cypress Edge: Next-Level Testing Strategies for React Developers

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!