Creating a full stack application is an excellent way to enhance your web development skills. We will walk through the process of building a full stack book store app using React for the front end, Node.js for the back end, and MongoDB for the database. This project will give you hands-on experience with the MERN stack (MongoDB, Express, React, Node.js) and help you understand how to manage both the client and server sides of a web application.
Before we dive into the code, make sure you have the following installed on your machine:
- Node.js: This will allow you to run JavaScript on the server side.
- MongoDB: A NoSQL database to store your book data.
- npm: Node package manager, which comes with Node.js.
- Basic knowledge of JavaScript and familiarity with React and Node.js concepts.
Project Structure
We’ll create a project structure that separates the front end and back end:
book-store-app/
├── client/ # React front end
└── server/ # Node.js back end
Setting Up the Server
First, let’s set up the back end using Node.js and Express.
Initialize the Server
Navigate to the server
directory and initialize a new Node.js project:
mkdir server
cd server
npm init -y
Install Dependencies
Install the necessary packages:
npm install express mongoose cors dotenv
- express: A web framework for Node.js.
- mongoose: An ODM (Object Data Modeling) library for MongoDB.
- cors: A middleware to enable CORS (Cross-Origin Resource Sharing).
- dotenv: A module to load environment variables from a
.env
file.
Create the Server File
Create a file named server.js
in the server
directory:
const express = require('express');
const mongoose = require('mongoose');
const cors = require('cors');
require('dotenv').config();
const app = express();
const PORT = process.env.PORT || 5000;
// Middleware
app.use(cors());
app.use(express.json());
// MongoDB connection
mongoose.connect(process.env.MONGODB_URI, { useNewUrlParser: true, useUnifiedTopology: true })
.then(() => console.log('MongoDB connected'))
.catch(err => console.error(err));
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Create the Book Model
Create a models
directory and a Book.js
file inside it:
const mongoose = require('mongoose');
const bookSchema = new mongoose.Schema({
title: { type: String, required: true },
author: { type: String, required: true },
description: { type: String, required: true },
price: { type: Number, required: true },
imageUrl: { type: String, required: true }
});
module.exports = mongoose.model('Book', bookSchema);
Create Routes for Books
Create a routes
directory and a books.js
file inside it:
const express = require('express');
const router = express.Router();
const Book = require('../models/Book');
// Get all books
router.get('/', async (req, res) => {
try {
const books = await Book.find();
res.json(books);
} catch (err) {
res.status(500).json({ message: err.message });
}
});
// Add a new book
router.post('/', async (req, res) => {
const book = new Book(req.body);
try {
const savedBook = await book.save();
res.status(201).json(savedBook);
} catch (err) {
res.status(400).json({ message: err.message });
}
});
module.exports = router;
Connect Routes to the Server
In server.js
, import and use the routes:
const bookRoutes = require('./routes/books');
app.use('/api/books', bookRoutes);
Setting Up the Client
Now, let’s set up the front end using React.
Create the React App
Navigate back to the root directory and create a React app:
npx create-react-app client
cd client
Install Axios
Install Axios for making HTTP requests:
npm install axios
Create Components
Create a components
directory and add the following components:
- BookList.js: To display the list of books.
- AddBook.js: To add a new book.
BookList.js
import React, { useEffect, useState } from 'react';
import axios from 'axios';
const BookList = () => {
const [books, setBooks] = useState([]);
useEffect(() => {
const fetchBooks = async () => {
const response = await axios.get('http://localhost:5000/api/books');
setBooks(response.data);
};
fetchBooks();
}, []);
return (
<div>
<h2>Book List</h2>
<ul>
{books.map(book => (
<li key={book._id}>{book.title} by {book.author}</li>
))}
</ul>
</div>
);
};
export default BookList;
AddBook.js
import React, { useState } from 'react';
import axios from 'axios';
const AddBook = () => {
const [book, setBook] = useState({ title: '', author: '', description: '', price: '', imageUrl: '' });
const handleChange = (e) => {
setBook({ ...book, [e.target.name]: e.target.value });
};
const handleSubmit = async (e) => {
e.preventDefault();
await axios.post('http://localhost:5000/api/books', book);
setBook({ title: '', author: '', description: '', price: '', imageUrl: '' });
};
return (
<form onSubmit={handleSubmit}>
<input name="title" value={book.title} onChange={handleChange} placeholder="Title" required />
<input name="author" value={book.author} onChange={handleChange} placeholder="Author" required />
<textarea name="description" value={book.description} onChange={handleChange} placeholder="Description" required />
<input name="price" type="number" value={book.price} onChange={handleChange} placeholder="Price" required />
<input name="imageUrl" value={book.imageUrl} onChange={handleChange} placeholder="Image URL" required />
<button type="submit">Add Book</button>
</form>
);
};
export default AddBook;
Update App.js
In src/App.js
, import and use the components:
import React from 'react';
import BookList from './components/BookList';
import AddBook from './components/AddBook';
const App = () => {
return (
<div>
<h1>Book Store</h1>
<AddBook />
<BookList />
</div>
);
};
export default App;
Running the Application
Start the Server
In the server
directory, run:
node server.js
Start the Client
In the client
directory, run:
npm start
Conclusion
Congratulations! You have successfully built a full stack book store application using React, Node.js, and MongoDB. This project not only helps you understand the MERN stack but also gives you a practical application that you can expand upon. You can add features like user authentication, book reviews, and more to enhance your app further. Happy coding!