Automating an E-Commerce Platform Deployment and Monitoring on AWS Part 2: Building the E-Commerce Platform
Welcome to Part 2 of our Automating an E-Commerce Platform Deployment and Monitoring on AWS series! In Part 1, we walked through setting up the Database and storing and linking static images. This is part 2 where we build a simple E-commerce Platform using Node, Express and React.js.
Steps:
3. Create React Client and Components.
Step 1: Create server.js
To kick off the creation of our e-commerce platform, we’ll start by establishing the main entry point: server.js
.
Begin by importing foundational modules which forms the backbone of our application.
// Import dependencies
const express = require("express");
const cors = require("cors");
const bodyParser = require("body-parser");
const { dirname } = require("path");
With our modules in place, configure middleware components like body-parser
(for parsing incoming request bodies) and cors
(to handle cross-origin resource sharing).
const port = process.env.PORT || 8000;
// Initialize express app
const app = express();
// Configure middleware
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));
app.use(cors());
For sanity checks and initial testing, set up a basic route. This will greet visitors with a welcoming message, confirming the server’s operational status.
// This is a test route
app.get('/test', (req, res) => {
res.json({message: 'Welcome to Life2Fullest E-Commerce Platform'});
});
Now, it’s time to bring our server to life. Use the commands node server.js
or npm start
to start the e-commerce platform.
// start the server
app.listen(port, () => {
console.log(`Server started on port ${port}`);
});
With the above steps completed, our e-com platform’s server-side foundation is in place, paving the way for constructing more routes.
Step 2: Establish Routes.
Routes manage the project’s endpoints. Let’s create these routes to handle various tasks, such as product administration and public access.
- Directory Setup: Begin by creating a
routes
folder. Inside, add three files:home.js
,admin.js
, andpublic.js
.
Home Routes (home.js
): This handles the home page endpoint.
/ routes/home.js
const express = require("express");
const router = express.Router();
// GET /home page
router.get("/home", (req, res) => {
try {
res.json({ message });
} catch (error) {
res.status(500).json({ error: "Failed to load home page" });
}
});
module.exports = router;
Admin Routes (admin.js
): These routes cover administrative tasks, such as adding, updating, or deleting products.
// routes/admin.js
const express = require("express");
const router = express.Router();
const productDb = require("../db/productDb");
// POST /api/admin/products - Add a new product
router.post("/products", async (req, res) => {
try {
const product = req.body;
const result = await productDb.addProduct(product);
res.json(result);
} catch (error) {
res.status(500).json({ error: "Failed to add product" });
}
});
// PUT /api/admin/products/:productId - Update a product
router.put("/products/:productId", async (req, res) => {
try {
const productId = req.params.productId;
const update = req.body;
const result = await productDb.updateProduct(productId, update);
res.json(result);
} catch (error) {
res.status(500).json({ error: "Failed to update product" });
}
});
// DELETE /api/admin/products/:productId - Delete a product
router.delete("/products/:productId", async (req, res) => {
try {
const productId = req.params.productId;
const result = await productDb.deleteProduct(productId);
res.json(result);
} catch (error) {
res.status(500).json({ error: "Failed to delete product" });
}
});
module.exports = router;
Public Routes (public.js
): Handle public access and product interactions.
// routes/public.js
const express = require("express");
const router = express.Router();
const productDb = require("../db/productDb");
// GET /api/products
router.get("/api/products", async (req, res) => {
try {
const products = await productDb.scanProducts();
res.json(products);
} catch (error) {
res.status(500).json({ error: "Failed to get products" });
}
});
module.exports = router;
Let’s integrate Routes with Server.
// Import dependencies
...
const adminRoutes = require('./routes/admin');
const publicRoutes = require('./routes/public')
...
// Home route
app.use("/", require("./routes/home"));
// Public routes
app.use("/shop", require("./routes/public"));
// Admin routes
app.use("/admin", require("./routes/admin"));
...
Step 3: Create React Client and Components.
For our e-commerce platform, we’ll use React for the frontend. Even if you’re primarily focusing on the backend or infrastructure, having a basic React frontend can help visualize and interact with your API.
Initialize React: If you haven’t already set up a React project, you can do so using the Create React App CLI with the command:
npx create-react-app client
Install Dependencies: Navigate to the client
directory and confirm these dependencies in package.json
. Afterwards, run npm install
.
"dependencies": {
"axios": "^1.4.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router-dom": "^6.11.2"
},
Component Structure: Create a Components
directory within client
. For this guide, we're highlighting a few components. You can find the full component list in the provided codebase.
- Contact (
Contact.js
): Displays the contact page.
// client/src/components/Contact/Contact.js
// This is a mocked form and does not send emails because it is not configured to do so
import React from "react";
function Contact() {
return (
<div>
<h1>Contact Us</h1>
<p>Have questions? Reach out to us!</p>
<form action="#" method="post">
<div>
<label htmlFor="name">Name:</label>
<input type="text" id="name" name="name" required />
</div>
<div>
<label htmlFor="email">Email:</label>
<input type="email" id="email" name="email" required />
</div>
<div>
<label htmlFor="message">Message:</label>
<textarea id="message" name="message" rows="4" required></textarea>
</div>
<div>
<button type="submit">Send</button>
</div>
</form>
</div>
);
}
export default Contact;
- Navigation (
Navigation.js
): Contains navigation links for the application.
// client/src/components/Navigation/Navigation.js
import React from "react";
import { Link } from "react-router-dom";
function Navigation() {
return (
<nav>
<ul
style={{
listStyleType: "none",
display: "flex",
backgroundColor: "Blue",
justifyContent: "space-around",
}}
>
<li>
<Link style={{ color: "white", textDecoration: "none" }} to="/home">
Home
</Link>
</li>
<li>
<Link style={{ color: "white", textDecoration: "none" }} to="/shop">
Shop
</Link>
</li>
<li>
<Link
style={{ color: "white", textDecoration: "none" }}
to="/contact"
>
Contact
</Link>
</li>
</ul>
</nav>
);
}
export default Navigation;
- ProductList (
ProductList.js
): Lists all the products using an API call.
// client/src/components/ProductList/ProductList.js
import React, { useEffect, useState } from "react";
import axios from "axios";
function ProductList() {
const [products, setProducts] = useState([]);
useEffect(() => {
const fetchData = async () => {
const result = await axios.get("/shop/api/products");
setProducts(result.data);
};
fetchData();
}, []);
return (
<div>
{products.map((product) => (
<div key={product.productId}>
<div>{product.name}</div>
<div>${product.price}</div>
<img src={product.imageUrl} alt={product.name} />
</div>
))}
</div>
);
}
export default ProductList;
Set Up App Routing (index.js
): To navigate between different components, set up routes using react-router-dom
.
// client/src/index.js
import React from "react";
import { render } from "react-dom";
import "./index.css";
import App from "./App";
import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import Home from "./components/Home/Home";
import Shop from "./components/Shop/Shop";
import Contact from "./components/Contact/Contact";
import Navigation from "./components/Navigation/Navigation";
render(
<Router>
<App>
<Navigation />
<Routes>
<Route path="/home" element={<Home />} />
<Route path="/shop" element={<Shop />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</App>
</Router>,
document.getElementById("root")
);
This is a basic React frontend setup ready to communicate with the backend and display products.
Wrapping Up the Frontend Setup
Finally, let’s set the layout/shell for the application.
// client/src/App.js
import Header from "./components/Header/Header";
import Footer from "./components/Footer/Footer";
const App = ({ children }) => (
<>
<Header />
<main>{children}</main>
<Footer />
</>
);
export default App;
That concludes our e-commerce platform setup. Ready to dive into Infrastructure as Code (IaC) configurations? Check out the next article in this series here.