CRUD App: React, Node.js, MySQL, & GitHub
CRUD App: React, Node.js, MySQL, & GitHub
Hey guys! Ever wanted to build a full-fledged CRUD application from scratch? You know, one where you can Create, Read, Update, and Delete data? Well, you’re in the right place! We’re diving headfirst into a project that brings together some of the most popular technologies out there: React for our user interface, Node.js and Express.js on the backend to handle our server-side logic, MySQL for our database, and GitHub for version control and collaboration. This is a fantastic project for anyone looking to level up their web development skills. We’ll be walking through each step, from setting up the initial project structure to deploying our application. No worries if you’re new to some of these technologies; I’ll break it down in a way that’s easy to understand. We’ll be covering everything from setting up your development environment, designing the database schema, building the API endpoints, and constructing the React components. You’ll get a solid understanding of how these technologies work together to create a dynamic and functional web application. So, buckle up, because we’re about to embark on an awesome journey into the world of full-stack development, and by the end of this guide, you’ll have a fully functional CRUD application under your belt, and a shiny new project for your GitHub profile! Let’s get started!
Table of Contents
Setting Up Your Development Environment
Alright, before we start coding, let’s get our environment set up. First things first, make sure you have
Node.js
and
npm
(Node Package Manager) installed on your machine. You can download them from the official Node.js website. After installation, verify the installations with the following commands in your terminal or command prompt:
node -v
and
npm -v
. This ensures you have the correct versions. We’ll also need a code editor. I personally love
Visual Studio Code
, but feel free to use whatever editor you’re comfortable with. Next, you’ll need a
MySQL
database. You can either install it locally or use a cloud-based service like
MySQL Workbench
. When you’ve downloaded the MySQL server, during the installation, configure the username and password to connect your database. Make sure you can connect to the database. Make sure you can connect to the database. I’ll show you how to set up the database and create tables later, so don’t worry about that right now. Next, let’s create a new project directory. In your terminal, navigate to where you want to keep your project, and run
mkdir crud-app && cd crud-app
. Inside this directory, we’ll create separate directories for our front-end (
React
) and back-end (
Node.js
) code. Run
mkdir client && mkdir server
. In the
client
directory, we’ll initialize our React app using
npx create-react-app .
(the period is important here, it creates the app in the current directory). Now, let’s move into the
server
directory and initialize our Node.js project. Run
npm init -y
. This creates a
package.json
file where we’ll manage our dependencies. We’ll install the necessary packages later. Don’t forget to initialize a
git repository
within your project directory:
git init
. This will allow us to track changes and upload our code to GitHub later. You should also create a
.gitignore
file to tell Git which files and folders to ignore. It is recommended to add
node_modules
to your
.gitignore
. With these initial steps, we have laid the foundation for our project. Let’s move on to the next exciting stages. Good job!
Backend with Node.js and Express.js
Time to build the backend with
Node.js
and
Express.js
! Navigate into your
server
directory. First, let’s install the necessary packages:
npm install express mysql cors body-parser dotenv
.
- Express.js will be our web application framework, making it easy to handle routes and HTTP requests.
- MySQL will be our MySQL connector, helping us interact with the database.
- CORS (Cross-Origin Resource Sharing) will allow our React application to communicate with our Node.js server, especially when they’re running on different ports.
- Body-parser will help to parse the request body in our routes.
-
Dotenv
will load environment variables from a
.envfile.
Now, create a file named
index.js
or
server.js
(or whatever you like) in your
server
directory. This will be the entry point of your server. Let’s start with setting up the server and connecting to the database. First, import the necessary modules:
const express = require('express');
const mysql = require('mysql');
const cors = require('cors');
const bodyParser = require('body-parser');
require('dotenv').config();
const app = express();
const port = process.env.PORT || 5000; // Use environment variable for port
app.use(cors());
app.use(bodyParser.json());
Then, let’s set up the MySQL connection. I’d recommend storing your database credentials in environment variables for security. You can do this by creating a
.env
file in your
server
directory and adding variables like
DB_HOST
,
DB_USER
,
DB_PASSWORD
, and
DB_DATABASE
. Then, you can access these variables using
process.env.VARIABLE_NAME
. Here’s how the database connection might look:
const db = mysql.createConnection({
host: process.env.DB_HOST,
user: process.env.DB_USER,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE
});
db.connect(err => {
if (err) {
console.error('MySQL connection error:', err);
return;
}
console.log('Connected to MySQL!');
});
Next, let’s create some simple API routes for CRUD operations. For example, to get all records from a table called ‘items’, you might have a route like this:
app.get('/api/items', (req, res) => {
db.query('SELECT * FROM items', (err, results) => {
if (err) {
console.error('Error fetching items:', err);
return res.status(500).send({ message: 'Error fetching items' });
}
res.json(results);
});
});
You’ll also need routes for creating, updating, and deleting items. For creating, you’ll typically use a
POST
request and the
body-parser
middleware to access the data sent in the request body. For updating, you’ll likely use a
PUT
or
PATCH
request, and for deleting, a
DELETE
request. Make sure to handle potential errors and send appropriate HTTP status codes in your responses. Finally, start your server with
app.listen(port, () => { console.log("Server is running on port ", port); });
Congratulations, you’ve built the foundation of your backend!
Database Design with MySQL
Before we start working on the frontend, let’s define the structure of our database using
MySQL
. Decide what kind of data you want to manage with your
CRUD
app. For a simple example, let’s imagine we’re building a to-do list application. In that case, we will need a table to store the to-do items. I’d advise creating a table called
todos
with the following columns:
-
id: INT, PRIMARY KEY, AUTO_INCREMENT - This will be the unique identifier for each to-do item. -
text: VARCHAR(255) - This will store the text of the to-do item. -
completed: BOOLEAN - This will indicate whether the to-do item is completed or not.
Now, let’s use the MySQL client (or MySQL Workbench) to create the table. Connect to your database, and run the following SQL query:
CREATE TABLE todos (
id INT PRIMARY KEY AUTO_INCREMENT,
text VARCHAR(255) NOT NULL,
completed BOOLEAN DEFAULT FALSE
);
This SQL statement creates the
todos
table with the specified columns and constraints. The
AUTO_INCREMENT
attribute ensures that each new item gets a unique
id
. The
NOT NULL
constraint enforces that the
text
column cannot be empty. The
DEFAULT FALSE
sets the
completed
column’s default value to false. You can then insert some sample data to test your queries. For instance:
INSERT INTO todos (text) VALUES ('Buy groceries');
INSERT INTO todos (text) VALUES ('Do laundry');
INSERT INTO todos (text) VALUES ('Walk the dog');
Once you have created your table and added some data, you can start building the API routes in your Node.js backend to interact with this data. For instance, you could implement a
GET
request to fetch all to-do items, a
POST
request to create a new item, a
PUT
or
PATCH
request to update an item, and a
DELETE
request to remove an item. Remember to replace
'todos'
with the actual table name if you’ve chosen a different name. Proper database design is the cornerstone of a well-functioning application, so make sure to take the time to plan your table structure carefully. If you’re building something else, adapt the table structure accordingly. If you’re using a database client like MySQL Workbench, you can visually create and modify tables, making the process even easier.
Frontend with React
Let’s switch gears and build the frontend with
React
! Go to your
client
directory. Remember, we created this directory earlier and ran
npx create-react-app .
inside it. We already have a basic React app ready to go. Now, let’s install some dependencies: You typically won’t need to install anything extra for a basic
CRUD
app, but depending on your requirements, you might want to consider packages like:
-
axiosorfetch: For making API requests to our backend. -
react-router-dom: For handling navigation and routing (if your app has multiple pages). -
styled-componentsormaterial-ui: For styling your components.
npm install axios
Once you have installed the required packages, let’s start by modifying the
src/App.js
file. First, import
useState
and
useEffect
from React. We’ll use these to manage the state of our application and fetch data from the server. Define a
useState
hook for your items. This will store the data fetched from the server. Inside your
App.js
, you’ll likely want to create components for the following:
-
A component to display the list of items (e.g.,
TodoList). -
A component for adding new items (e.g.,
TodoForm). -
A component for each individual item (e.g.,
TodoItem).
Here is a simple example for the TodoList:
import React, { useState, useEffect } from 'react';
import axios from 'axios';
function App() {
const [todos, setTodos] = useState([]);
useEffect(() => {
// Fetch data from the backend
axios.get('/api/items') // Replace with your API endpoint
.then(response => {
setTodos(response.data);
})
.catch(error => {
console.error('Error fetching items:', error);
});
}, []);
return (
<div className="App">
<h1>My Todo List</h1>
<ul>
{todos.map(todo => (
<li key={todo.id}>{todo.text}</li>
))}
</ul>
</div>
);
}
export default App;
In this example, we’re using the
useEffect
hook to fetch data from the
/api/items
endpoint (which we defined in our Node.js backend). Inside the
useEffect
, we’re using
axios
to make a
GET
request to the backend. The response data is then used to update the
todos
state. After fetching the data, we’re mapping over the
todos
array and rendering a list of items. Remember to adapt the API endpoint to match the routes you’ve defined in your Node.js backend. You’ll need to create the
TodoForm
and
TodoItem
components, implement the logic for adding, updating, and deleting items, and handle the user interactions. When interacting with the backend, you’ll need to use
POST
,
PUT
, and
DELETE
requests to perform
CRUD
operations. With a little extra effort, you can make your React app shine with styling and user experience improvements. Remember to regularly test your React components. React components can range from simple components like displaying text to complex ones, like interactive forms. Testing your components helps ensure that they’re working correctly. Good luck!
Connecting Frontend and Backend
Now, let’s connect our
React
frontend to our
Node.js
backend. To allow our frontend to make requests to the backend (which typically runs on a different port), we’ll use
CORS
(Cross-Origin Resource Sharing). Remember that we installed the
cors
package in our
server
? We need to configure it in our
server/index.js
file:
const cors = require('cors');
app.use(cors());
This simple line of code enables CORS for all origins, which means any domain can access your API. However, for production environments, it’s recommended to configure CORS to only allow requests from specific origins for security reasons. In our React app, we’ll use
axios
(or the built-in
fetch
API) to make requests to our backend API endpoints. For example, to fetch items, you might use:
import axios from 'axios';
useEffect(() => {
axios.get('http://localhost:5000/api/items') // Replace with your backend URL and the correct route
.then(response => {
setItems(response.data);
})
.catch(error => {
console.error('Error fetching items:', error);
});
}, []);
Replace
'http://localhost:5000'
with the address where your Node.js server is running (including the port). You will also need to adjust the API endpoints to match the routes defined in your backend. When sending data, use the appropriate HTTP methods (e.g.,
POST
for creating items,
PUT
or
PATCH
for updating, and
DELETE
for removing). Don’t forget to send the data in the request body. For example, when adding a new item, send the data as JSON:
axios.post('http://localhost:5000/api/items', { text: newItemText })
.then(response => {
// Handle the successful creation
})
.catch(error => {
// Handle the error
});
Make sure your backend routes are correctly configured to handle these requests and parse the data from the request body. If you’re running your React app and Node.js server locally, they’ll usually run on different ports (e.g., React on port 3000 and Node.js on port 5000). Ensure that your frontend requests are pointing to the correct backend address and port. Check the browser’s developer console for any errors. Inspect the network requests to verify that the requests are being sent to the correct endpoints and that the responses are what you expect. Connecting the frontend and backend is a crucial step in building a full-stack CRUD application, so taking the time to troubleshoot any issues will pay off in the long run!
Version Control with GitHub
Time to version control your project with
GitHub
! First, make sure you have a
GitHub
account. If you don’t already have one, create an account at
github.com
. Now, navigate to your project directory in the terminal, where you initialized the
Git
repository (
git init
). Let’s add and commit your initial files. Run the following commands:
git add .
git commit -m "Initial commit: Project setup"
This adds all the files and commits them with a descriptive message. Next, create a new repository on GitHub. Go to your GitHub profile and click the “+” button in the top right corner and select “New repository”. Give your repository a name (e.g.,
crud-app
) and optionally add a description. Make sure to select “Public” or “Private” depending on your preference. Once your repository is created, GitHub will provide you with a set of instructions on how to connect your local repository to your remote repository. Usually, it looks something like this:
git remote add origin <your_repository_url>
git push -u origin main
Replace
<your_repository_url>
with the URL of your GitHub repository. The
git remote add origin
command associates your local repository with the remote repository on GitHub. The
git push -u origin main
command pushes your local code to the
main
branch (or
master
if you’re using that branch name) of your remote repository. After the push, your code will be available on GitHub. From now on, whenever you make changes to your code, you can use these commands to update your GitHub repository:
git add .
git commit -m "Descriptive commit message"
git push
Remember to replace `