Skip to content

Instantly share code, notes, and snippets.

@halitbatur
Created July 4, 2024 07:17
Show Gist options
  • Save halitbatur/7ac212e06915b0fb0c4aade36c8a20e2 to your computer and use it in GitHub Desktop.
Save halitbatur/7ac212e06915b0fb0c4aade36c8a20e2 to your computer and use it in GitHub Desktop.
MVC and CRUD

Discuss the points below with your teammates and add your answers below in the comments

  1. What is the best/most common file structure for backend NodeJS projects?
  2. What is the MVC architecture? Why we will be using it?
  3. Explore defining a schema in Mongoose, you can refer to this for more information (no answer in the comments required).
  4. What are the CRUD operations? add an example code of each CRUD operations in Mongoose.
@KhileM
Copy link

KhileM commented Jul 4, 2024

Lindokuhle
Gerald Mutswi
Sakhile Motha

  1. The best and most common file structure for backend Node.js projects typically includes a config folder for configuration files, controllers for handling requests, models for database schemas, routes for defining endpoints, middleware for functions that run during request processing, utils for utility functions, tests for test files, public for static files, views for template files (optional), and logs for log files. Additionally, it includes root-level files such as .env for environment variables, .gitignore for ignored files in Git, package.json for project metadata, server.js for starting the server, and README.md for project documentation.

  2. MVC stands for Model, View, and Controller, a design pattern used in web development. The Model handles data and logic, the View manages the user interface, and the Controller processes user input and updates the Model and View. This pattern improves organization, flexibility, and development speed by separating concerns and allowing developers to work on different parts of an application simultaneously. We use for its organizational benefits, as it separates concerns into data (Model), user interface (View), and control logic (Controller), making large applications more manageable. This separation allows for flexibility, as modifying one part (like the View) doesn’t affect the others, simplifying updates and maintenance.

  3. Create (C): Adds a new document (or row, in relational terms) to the database.
    Example: createUser function creates a new User document using new User({...}) and saves it to the database using user.save().
    // Create a model
    const User = mongoose.model('User', userSchema); // Assuming mongoose is already connected to MongoDB

// 1. Create (C - Create)
async function createUser(username, email, age) {
try {
const user = new User({ username, email, age });
const newUser = await user.save();
console.log('New user created:', newUser);
} catch (err) {
console.error('Error creating user:', err);
}
}
// Usage: createUser('john_doe', 'john@example.com', 30);

Read (R): Retrieves one or more documents based on specified criteria.
Example: findUserById function uses User.findById(id) to find a user by their MongoDB ObjectId.
// Usage: createUser('john_doe', 'john@example.com', 30);
// 2. Read (R - Read)
async function findUserById(id) {
try {
const user = await User.findById(id);
if (user) {
console.log('User found:', user);
} else {
console.log('User not found');
}
} catch (err) {
console.error('Error finding user:', err);
}
}
// Usage: findUserById('some_user_id');

Update (U): Modifies existing documents based on specified criteria.
Example: updateUser function uses User.findByIdAndUpdate(id, updates, { new: true }) to find a user by ID and update their fields as specified in updates.
async function updateUser(id, updates) {
try {
const updatedUser = await User.findByIdAndUpdate(id, updates, { new: true });
console.log('User updated:', updatedUser);
} catch (err) {
console.error('Error updating user:', err);
}
}

// Usage: updateUser('some_user_id', { age: 31 });

Delete (D): Removes existing documents based on specified criteria.
Example: deleteUser function uses User.findByIdAndDelete(id) to find a user by ID and delete them from the database.

async function deleteUser(id) {
try {
const deletedUser = await User.findByIdAndDelete(id);
console.log('User deleted:', deletedUser);
} catch (err) {
console.error('Error deleting user:', err);
}
}

// Usage: deleteUser('some_user_id');

@katmafalela
Copy link

katmafalela commented Jul 4, 2024

@kgomotso Nacane

  1. The most common file structure for Node.js backend projects is the Model-View-Controller (MVC), which divides the application into three interconnected parts:

    • Model: represents data and business logic

    • View: manages the user interface and presentation

    • Controller: controls the model and view -view interaction

  2. Model-View-Controller (MVC) is a software design pattern that divides an application into three interconnected components, each with
    specific responsibilities:
    -Model: Represents data and business logic
    Controls application state and data. storage
    Provides information to and receives updates from the Controller

  • View: Handles UI and presentation
    Displays information provided by the controller
    Accepts user input and sends it to the Controller

  • Controller:Manages the interaction between the model and the view
    receives user input from the view and updates the model accordingly
    Produces data from the model and passes it to the view

2.1 We use the MVC architecture for several reasons:
- Concern for Separation: Each component has a specific role that makes it easy to maintain, update and scale the application.
- Reusability: Components can be reused in other parts of the application or even in different projects.
- Flexibility: MVC makes it easy to replace or replace individual components without affecting the entire application.
- Easier testing: When problems are clearly separated from each other, it becomes easier to test individual components.

  • Improved readability: Code structure and organization are clearer, making it easier for developers to understand and work with the
    codebase.
  1. CRUD stands for Create, Read, Update, and Delete. These are the four basic operations for managing data in a database.
    4.1. - Create:: Use new Model() and .save() to create a new document.
    const newUser = new User({ name: 'Katleho Mafalela', age: 10, email: 'katleho@mafalela.com' });
    newUser.save();
    - Read: Use methods like find, findOne, and findById to retrieve documents.
    User.find().then(users => console.log(users));
    User.findOne({ email: 'katleho@mafalela.com' }).then(user => console.log(user));
    User.findById('60d4b54b8f8b4c26d8f8c8e0').then(user => console.log(user));
    • Update: Use methods like updateOne, updateMany, and findByIdAndUpdate to modify documents.
      User.updateOne({ email: 'katleho@mafalela.com' }, { age: 10 });
      User.findByIdAndUpdate('60d4b54b8f8b4c26d8f8c8e0', { name: 'Kgomotso Nacane' }, { new: true });

    • Delete: Use methods like deleteOne, deleteMany, and findByIdAndDelete to remove documents.
      User.deleteOne({ email: 'katleho@mafalela.com' });
      User.findByIdAndDelete('60d4b54b8f8b4c26d8f8c8e0');

@Tumelo2748
Copy link

Selepe Thinane
Mthokozisi Dhlamini @sthabiso-iv
Thabiso Makolana @thabiso-makolana

  1. Root directory:

package.json: Contains project metadata and dependencies.

node_modules: Installed dependencies from package.json.
public: Stores static files served directly (e.g., images, CSS).
Source code directory (often named src or app):

models: Represents data structures and interacts with the database.

controllers: Handles incoming requests, interacts with models and services.

routes: Defines API endpoints and maps them to controller functions.

middlewares: Reusable functions that process requests before reaching controllers (e.g., authentication, logging).

services: Handles complex business logic or interacts with external services.

utils: Utility functions used across the project.

config: Configuration files for database, server, etc.

index.js: Main application entry point.

  1. MVC's main idea is to separate concerns and divide responsibilities, which can make it easier to maintain and extend the application over time. It's commonly used to implement user interfaces, data, and controlling logic, and is especially popular for building web applications.
    we will be using it to build more full-fledged backend applications, we will be following the MVC pattern in our project files structure.


  2. CRUD stands for Create, Read, Update, and Delete, the fundamental operations for interacting with data in applications. Mongoose provides a powerful way to perform these operations on your MongoDB database.

  3. Create (C):

const newRecord = new ModelName({
  key1: value1,
  key2: value2,
});

newRecord.save()
  .then((result) => {
    console.log('New record created:', result);
  })
  .catch((error) => {
    console.error('Error creating new record:', error);
  });
  1. Read (R):
ModelName.find({ key: value })
  .then((result) => {
    console.log('Retrieved records:', result);
  })
  .catch((error) => {
    console.error('Error retrieving records:', error);
  });
  1. Update (U):
ModelName.updateOne({ _id: recordId }, { $set: { key: updatedValue } })
  .then((result) => {
    console.log('Record updated:', result);
  })
  .catch((error) => {
    console.error('Error updating record:', error);
  });
  1. Delete (D):
ModelName.deleteOne({ _id: recordId })
  .then((result) => {
    console.log('Record deleted:', result);
  })
  .catch((error) => {
    console.error('Error deleting record:', error);
  });

@Pumlanikewana
Copy link

Pumlanikewana commented Jul 4, 2024

Mpho Oganne
Simphiwe Ndlovu
Pumlani Kewana

A well-organized file structure for backend Node.js projects can greatly enhance readability, maintainability, and scalability. A widely accepted and scalable structure is based on the principles of separation of concerns and modularization.

├── src/
│ ├── controllers/
│ │
│ ├── models/
│ │
│ ├── routes/
│ │
│ ├── middlewares/
│ │
│ ├── services
│ │
│ ├── utils/
│ │
│ ├── config/
│ │
│ ├── app.js

├── tests/

├─ .env
├── gitignore
├──package.json
├─ package-lock.json
└─ README.md

MVC architecture helps you to organize your web application and make it more manageable. It allows you to separate business logic from presentation logic, which makes it very easy to add new features or change existing ones without affecting the whole application.

  1. CRUD - create, read , update and delete.

example 1:
Create

// lines of code ommitted

const User = mongoose.odel('user', userSchema);

// creating a new user (some code from external source, leetcode and chatgpt)

const createUser = async () = >
{

const newUser = new User ({
// details of users code ommitted for saving time
});

// error handling code omitted

createUser();

Read

const readUsers = async () => { const users = await User.find({ age: { $gte: 18 } });
console.log('Users:', users); }; readUsers();

Update

Delete

const deleteUserById = async (userId) => {
// wrap inside a try and catch error handling code omitted

const deletedUser = await user.findByIdAndDelete(userId);

deleteUserById('...'); // user id goes here.

const User = mongoose.model('User', userSchema); // Update a user const updateUser = async () => { const updatedUser = await User.findByIdAndUpdate( '60c72b2f9b1e8b001c8e4b6c', { age: 26 }, { new: true } ); updateUser();

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment