DEV Community

Cover image for Envelope Budgeting API: Easy Money Management
Sonja
Sonja

Posted on

Envelope Budgeting API: Easy Money Management

After six months of diving into Back-End Web Development, I'm excited to share a significant milestone: my very own API that demonstrates Envelope Budgeting in action.

What does the program do?

The API provides a user-friendly webpage where you can create, update, view, and delete envelopes. It also allows budget transfers between envelopes. Feel free to explore its features. (Note: Initial loading may be slow due to deployment on a free instance.)

Screenshot of front-end

Current Limitations

The total budget is hard-coded to $5000, and changes are temporary, lasting only until the server restarts. Future versions will include a database layer and customizable total budgets.

Technical Details

The back-end is powered by Node.js and Express.js, supporting the following HTTP methods:

  • GET (1) -> displays all envelopes
  • GET (2) -> displays remaining total budget
  • GET (3) -> fetches individual envelope by name
  • POST (1) -> creates new envelope and assigns set budget
  • POST (2) -> transfers budget from one envelope to another
  • PUT -> logs spending in a particular envelope
  • DELETE -> deletes an envelope

To prevent overspending, there is a limit check in place for POST and PUT routes. For POST, PUT, and DELETE, there is also a check if an envelope with the same name already exists. If a check fails, an error message is sent.

// Transfer budget between envelopes
app.post("/envelopes/transfer/:from/:to", (req, res) => {
    const from = req.params.from;
    const to = req.params.to;
    const amount = Number(req.query.transfer);
    if (!envelopeExists(from) || !envelopeExists(to)) {
        res.status(403).send(`Operation declined. \nPlease make sure to enter names of existing envelopes to transfer money between them.`);
    } else if (envelopes[from].budget >= amount) {
        envelopes[from].budget -= amount;
        envelopes[to].budget += amount;
        res.status(201).send(`New balance: \nEnvelope "${from}" - $${envelopes[from].budget}, \nEnvelope "${to}" - $${envelopes[to].budget}`);
    } else {
        res.status(403).send(`Operation declined. \nNot enough money left in envelope "${from}".`);
    }  
});
Enter fullscreen mode Exit fullscreen mode

The front-end was developed using HTML, CSS, and JavaScript to create an easy-to-use interface for demonstrating the API. This allows users to interact with the API without downloading code or using tools like Postman, so the styling is intentionally minimal.

The front-end includes validation checks to prevent empty input fields and changes the server response display field's background color based on the HTTP response status. Different colors indicate success, errors, or failed validations, helping users understand the results of their actions.

screenshot of front-end with failed validation check message in front of orange background

I used JavaScript and asynchronous fetch() requests to connect the front-end and back-end. Going full-stack also involved adding a fourth GET method to fetch the index.html file and properly setting up CORS for the back-end.

postButton.addEventListener("click", async () => {
    const envName = postName.value;
    const envBudget = Number(postBudget.value);
    if (envName === "" || envBudget === 0) {
        serverResponseField.innerHTML = "Please enter a name and budget before clicking the CREATE button.";
        alertServerResponseField("orange");
    } else {
        try {
            const response = await fetch(`${apiUrl}/envelopes`, {
                method: "post",
                headers: {
                    "Content-Type": "application/json"
                },
                body: JSON.stringify({newEnv: envName, newBudget: envBudget}) 
            });
            if (response.ok || response.status === 403) {
                const jsonResponse = await response.text();
                clearDisplay();
                serverResponseField.innerHTML = `
                <h4>--- creating envelope ---</h4>
                <pre>${jsonResponse}</pre>
                `;
                if (response.status === 403) {
                    alertServerResponseField("red");
                } else {
                    alertServerResponseField("green");
                }
            } else {
                throw new Error("Request failed!");
            }
        } catch (err) {
            console.log(err);
        }
    }
});
Enter fullscreen mode Exit fullscreen mode

Conclusion

Creating my first API was incredibly rewarding. The hands-on experience of implementing it myself, after studying the theory, was invaluable. Seeing an HTTP request go through successfully was a moment of triumph.

Acknowledgements

I struggled the most with connecting the front-end and back-end, using a tactic called Just-in-Time Learning (JIT). While online resources, including ChatGPT, and trial-and-error were helpful, a breakthrough came after a short coaching session with a senior developer who clarified some key points. So, a shout-out and big thanks to all the people and platforms providing curated content, which significantly accelerates learning when combined with JIT. Both are essential!

Download Link

Explore the full codebase on GitHub.

GitHub logo s-mehnert / Envelope-Budgeting-API

Learn how Envelope Budgeting works by using the Envelope-Budgeting-API via the provided front-end.



The API has been created using Node 20.11.1.

Image by freepik

Top comments (0)