Website to Web Applications: Lessons from Software Evolution

Website to Web Applications: Lessons from Software Evolution

Why do we need software frameworks?

Why do you think that a code that can be written in 80 to 100 lines should need different, different classes? Or separation of concerns?

For example, here is the code of a simple Node.js program having the user entity and its CRUD operation exposed as REST API using Express Framework.

// Sample Express code snippet handling CRUD for user entity
const express = require('express');
const { Pool } = require('pg');
const app = express();
app.use(express.json()); // Middleware to parse JSON bodies

// PostgreSQL pool connection setup
const pool = new Pool({
    user: 'your_username',
    host: 'localhost',
    database: 'your_database',
    password: 'your_password',
    port: 5432,
});

// Create a new user
app.post('/users', async (req, res) => {
    const { name, email } = req.body;
    const query = 'INSERT INTO users(name, email) VALUES($1, $2) RETURNING *;';
    try {
        const result = await pool.query(query, [name, email]);
        res.status(201).json(result.rows[0]);
    } catch (err) {
        console.error(err.stack);
        res.status(500).send('Server error');
    }
});

// Get a user by ID
app.get('/users/:id', async (req, res) => {
    const { id } = req.params;
    const query = 'SELECT * FROM users WHERE id = $1;';
    try {
        const result = await pool.query(query, [id]);
        res.json(result.rows[0]);
    } catch (err) {
        console.error(err.stack);
        res.status(500).send('Server error');
    }
});

// Update a user
app.put('/users/:id', async (req, res) => {
    const { id } = req.params;
    const { name, email } = req.body;
    const query = 'UPDATE users SET name = $1, email = $2 WHERE id = $3 RETURNING *;';
    try {
        const result = await pool.query(query, [name, email, id]);
        res.json(result.rows[0]);
    } catch (err) {
        console.error(err.stack);
        res.status(500).send('Server error');
    }
});

// Delete a user
app.delete('/users/:id', async (req, res) => {
    const { id } = req.params;
    const query = 'DELETE FROM users WHERE id = $1;';
    try {
        await pool.query(query, [id]);
        res.send('User deleted successfully');
    } catch (err) {
        console.error(err.stack);
        res.status(500).send('Server error');
    }
});

// Start the server
const PORT = 3000;
app.listen(PORT, () => {
    console.log(`Server running on port ${PORT}`);
});        

It's a single file of application which actually does all the four operations and looks okay to us. Right? It doesn't require any special treatment on the first look.

In a way, if this is the only application you need and the only feature you require, and it's never going to change, you might not need anything else.

In one of my initial companies, we used to create dynamic websites for customers. Back then, websites with typical 4 to 5 pages - homepage, about us, products we offer, contact us - were sufficient.

Clients needed the website just to have an internet presence for their company. So we used to write similar kinds of PHP programs where each file was self-sufficient for that particular page. The database connection, business logic, dynamic text, HTML - all of these things used to be in one single file.

To be frank, the design was not at all an important because the timelines were tight and our company had found a set way of delivering websites. We were asked to deliver projects quickly with minimal costs, maybe not more than 20-25,000 rupees at that time. The design was pretty standard across the websites, with only color themes changing on both sides, and we needed those websites to be up in a single day. The clients need were so simple that they seldomly needed an upgrade.

In today's world, applications are much more complex than before. Even micro-applications don't resemble the websites we used to create. We're living in a dynamic world where agility and security are paramount. Software evolves rapidly, necessitating frameworks and principles like SOLID.

In this fast-paced world of software development, embracing frameworks and design principles is not just a choice – it's a necessity. They empower developers to build applications that are not only agile and responsive but also secure and maintainable. As we continue to push the boundaries of technology, it's essential to remember the lessons learned from the evolution of software development and adapt our practices accordingly.

In the following articles, we delve into the reasons behind and methods for refactoring applications to enhance their agility and maintainability.

  1. Dive deeper into exploration of SOLID Principles for Scalable Solutions
  2. Find out effective strategies for applying the Single Responsibility Principle (SRP) for better code

#SoftwareDevelopment #SOLIDPrinciples #Agility #SoftwareEvolution


To view or add a comment, sign in

Others also viewed

Explore content categories