Lab09 - Express
Lab09 - Express
JS
Objective:
To enable students to build a structured and functional backend using Express.js that
simulates real-world product listing APIs. This task emphasizes route handling, middleware
usage, query and route parameters, and error management without a database, enhancing
students' confidence in backend development fundamentals.
Activity Outcomes:
Run the server and open http://localhost:3000/users/123 in your browser. Try changing the
number in the URL.
Create a route that handles query parameters in the URL, such as "/search?q=example", and
extract the parameter value.
Run the server and open http://localhost:3000/search?q=test. Try changing the value of "q".
req.query.q: The req.query object contains the values of the query parameters. In this
case, req.query.q will hold the value of the "q" query parameter from the URL.4
express.static('public'): This middleware tells Express to serve static assets (files that don't
change, like CSS, JavaScript, images) from the "public" directory. Now, files in the public
directory are accessible via URLs like /styles.css and /my-image.jpg.
Run the server and visit any of the defined routes in your browser. Check the console in your
terminal.
myLogger function: This is a middleware function. It takes req, res, and next as
arguments.
console.log(...): Logs the request method and URL.
next(): This is crucial. It tells Express to move on to the next middleware in the chain
or to the route handler. If you don't call next(), the request will be left hanging.
app.use(myLogger): This tells Express to use the myLogger middleware for all
incoming requests.
// Middleware function 1
const loggerMiddleware = (req, res, next) => {
console.log(`[${req.method}] ${req.url}`);
next(); // Pass control to the next middleware/route handler
};
// Middleware function 2
const authMiddleware = (req, res, next) => {
// Simulate authentication
const isAuthenticated = true;
if (isAuthenticated) {
next(); // User is authenticated, proceed to the next handler
} else {
res.status(401).send('Unauthorized'); // User is not authenticated
}
};
Modify app.js:
const bodyParser = require('body-parser'); // Import body-parser
app.use(express.static('public'));
// Use body-parser middleware to parse form data
app.use(bodyParser.urlencoded({ extended: false }));
Modify app.js
Postman:
o Set the request type to POST.
o Enter the URL: http://localhost:3000/submit-json
o Set the "Body" to "raw" and select "JSON" as the format.
o Enter the JSON data above.
o Click "Send".
Curl:
curl -X POST -H "Content-Type: application/json" -d '{"name": "John Doe", "age": 30,
"city": "New York"}' http://localhost:3000/submit-json
Instructions:
1. Set up the Express.js application
2. Define the routes
3. Handle HTTP methods appropriately
o GET: Retrieve data.
o POST: Create new data.
o PUT: Update existing data.
o DELETE: Delete data.
4. Send responses:
o Use res.json() to send JSON responses with the requested data or appropriate
messages.
o Set appropriate HTTP status codes (e.g., 200 OK, 201 Created, 404 Not
Found, 500 Internal Server Error).
5. Data storage: For simplicity, store the items in an in-memory array. You do not need
to use a database for this lab.
Sample Solution:
// GET /items
app.get('/items', (req, res) => {
res.json(items);
});
// GET /items/:id
app.get('/items/:id', (req, res) => {
const id = parseInt(req.params.id);
const item = items.find((i) => i.id === id);
if (item) {
res.json(item);
} else {
res.status(404).json({ message: 'Item not found' });
}
});
// POST /items
app.post('/items', (req, res) => {
const newItem = {
id: items.length + 1,
title: req.body.title,
};
items.push(newItem);
res.status(201).json(newItem);
});
// PUT /items/:id
app.put('/items/:id', (req, res) => {
const id = parseInt(req.params.id);
const itemIndex = items.findIndex((i) => i.id === id);
if (itemIndex > -1) {
items[itemIndex].title = req.body.title;
res.json(items[itemIndex]);
} else {
res.status(404).json({ message: 'Item not found' });
}
});
// DELETE /items/:id
app.delete('/items/:id', (req, res) => {
const id = parseInt(req.params.id);
const itemIndex = items.findIndex((i) => i.id === id);
app.listen(port, () => {
console.log(`Server is running on http://localhost:${port}`);
});
Write a custom middleware function that logs every incoming request with a timestamp,
route, and method. Append these logs to a file using the fs module.
Develop a product catalog RESTful API using Express.js that supports viewing, filtering, and
retrieving product data. The data will be stored temporarily in memory (no database). This
activity will help students simulate backend functionalities similar to those found in e-
commerce applications.
Functional Requirements:
1. Data Setup:
o Create an array of products with the following fields:
id (unique number)
name (string)
price (number)
category (string)
inStock (boolean)
2. GET /products Route:
o Respond with all products in JSON format.
o Support optional query parameters for:
category (e.g., /products?category=electronics)
maxPrice (e.g., /products?maxPrice=100)
inStock=true|false
3. GET /products/:id Route:
o Return the product matching the provided id.
o Respond with a 404 Not Found if the product doesn't exist.
4. POST /products Route (Bonus):
o Accept a JSON body to add a new product.
o Validate that all required fields are present.
o Return a success message and the added product.
5. Middleware:
o Add middleware to log the HTTP method and path of incoming requests.
6. Error Handling:
o Return meaningful error messages and status codes for:
Invalid routes
Missing required data
Invalid data types in input
Further Requirements:
Ensure clean code structure and proper use of app.use() for middleware.
Responses must be consistent and in JSON format.
Input data should be validated for type and completeness before processing.