Creating a Warehouse Management API

Understanding Our Task

Imagine you're creating a digital system for a warehouse manager. Just as a warehouse manager needs to track inventory and update item details, our API needs to provide endpoints that allow viewing and modifying warehouse items. We'll be building two main features: viewing all new items and updating existing items.

Setting Up Our Environment

Before we start coding, let's set up our project environment, much like preparing a workspace in a real warehouse:

// First, ensure our environment is ready
cp .env.example .env

// Run our database setup
npx sequelize-cli db:migrate
npx sequelize-cli db:seed:all
    

Implementing Our API Endpoints

Let's build our API piece by piece, starting with the foundation. Here's our complete implementation that will satisfy all test requirements:

// app.js
const express = require('express');
const { WarehouseItem } = require('./db/models');

const app = express();

// This middleware is like having a package inspector who knows how to 
// handle incoming JSON packages
app.use(express.json());

// GET /items - Returns all new (unused) items
// Think of this as getting a list of all fresh inventory
app.get('/items', async (req, res) => {
    try {
        const items = await WarehouseItem.findAll({
            // We only want unused items, like filtering for new stock
            where: {
                isUsed: false
            }
        });

        // Send back our list of items
        res.json(items);
    } catch (error) {
        // If something goes wrong, handle it gracefully
        console.error('Error fetching items:', error);
        res.status(500).json({ message: 'Error retrieving warehouse items' });
    }
});

// PUT /items/:id - Updates an existing item
// Think of this as updating an item's details in inventory
app.put('/items/:id', async (req, res) => {
    try {
        // First, find the item we want to update
        const item = await WarehouseItem.findByPk(req.params.id);

        // If we can't find the item, let the user know
        if (!item) {
            return res.status(404).json({
                message: "Warehouse Item not found"
            });
        }

        // Update the item with new information
        await item.update(req.body);

        // Send back the updated item
        res.json(item);
    } catch (error) {
        console.error('Error updating item:', error);
        res.status(500).json({ message: 'Error updating warehouse item' });
    }
});

module.exports = app;
    

Understanding the Implementation

GET /items Endpoint

This endpoint works like a warehouse clerk who only shows you the new items in stock. Let's break down its key components:

// The where clause filters for unused items
where: {
    isUsed: false
}

// This is equivalent to asking:
// "Show me all items where isUsed is false"
    

The response will look like this when successful:

[
    {
        "id": 1,
        "name": "Paint",
        "price": 12.12,
        "quantity": 12,
        "isUsed": false
    },
    {
        "id": 3,
        "name": "Webcam",
        "price": 50.5,
        "quantity": 5,
        "isUsed": false
    }
]
    

PUT /items/:id Endpoint

This endpoint is like a warehouse worker updating an item's details in the inventory system. Here's how it works:

// First, we look for the item
const item = await WarehouseItem.findByPk(req.params.id);

// If we can't find it, we return a 404 error
if (!item) {
    return res.status(404).json({
        message: "Warehouse Item not found"
    });
}

// If we find it, we update it with the new information
await item.update(req.body);
    

Testing Our Implementation

Let's verify our endpoints work correctly:

// Run all tests
npm test

// Or test specific endpoints
curl http://localhost:3000/items          // Should return all unused items
curl -X PUT http://localhost:3000/items/2 // Should update item with ID 2
    

Understanding Error Handling

Our implementation includes robust error handling, much like how a warehouse needs procedures for when things go wrong:

Item Not Found

When trying to update a non-existent item, we return a clear error message:

{
    "message": "Warehouse Item not found"
}
    

Server Errors

We catch and handle unexpected errors gracefully, preventing our application from crashing.

Bonus Features

For additional functionality, we can implement these bonus endpoints:

// GET /items/:name - Find item by name
app.get('/items/:name', async (req, res) => {
    try {
        const item = await WarehouseItem.findOne({
            where: {
                name: req.params.name
            }
        });

        if (!item) {
            return res.status(404).json({
                message: "Warehouse Item not found"
            });
        }

        res.json(item);
    } catch (error) {
        res.status(500).json({ message: 'Error retrieving warehouse item' });
    }
});

// DELETE /items/:id - Remove an item
app.delete('/items/:id', async (req, res) => {
    try {
        const item = await WarehouseItem.findByPk(req.params.id);

        if (!item) {
            return res.status(404).json({
                message: "Warehouse Item not found"
            });
        }

        await item.destroy();
        res.json({ message: "Successfully deleted" });
    } catch (error) {
        res.status(500).json({ message: 'Error deleting warehouse item' });
    }
});
    

Real World Applications

These endpoints mirror real warehouse operations in several ways:

Inventory Management: The GET endpoint helps managers see available new stock, just like checking warehouse shelves for new items.

Item Updates: The PUT endpoint allows updating item details, similar to how warehouse staff might update price tags or quantity counts.

Error Handling: Just as a warehouse needs procedures for missing items, our API has clear protocols for handling errors.

Further Enhancements

Consider these additional features to make the system more robust:

Implement inventory tracking history to log all changes to items.

Add validation for price and quantity updates to prevent invalid values.

Create endpoints for batch operations to handle multiple items at once.

Add filtering and sorting options to the GET endpoint for better item discovery.