Automating an E-Commerce Platform Deployment and Monitoring on AWS Part 2: Building the E-Commerce Platform

Rachel Murphy
5 min readOct 25, 2023

--

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:

1. Create server.js.

2. Establish Routes.

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.

  1. Directory Setup: Begin by creating a routes folder. Inside, add three files: home.js, admin.js, and public.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.

--

--