production-level Node.js project for a simple note-taking application

Below is an example of a production-level Node.js project for a simple note-taking application, along with its source code structure. ├── package.json ├── server.js ├── routes │ └── notes.js ├── controllers │ └── notesController.js ├── models │ └── note.js ├── services │ └── noteService.js ├── config │ └── db.js └── test └── notes.test.js package.json: Defines project dependencies and scripts. { "name": "note-taking-app", "version": "1.0.0", "description": "Simple note-taking application", "main": "server.js", "scripts": { "start": "node server.js", "dev": "nodemon server.js", "test": "jest --watchAll --coverage" }, "dependencies": { "express": "^4.17.1", "mongoose": "^6.0.12", "dotenv": "^10.0.0", "jest": "^27.3.1", "supertest": "^6.1.6" }, "devDependencies": { "nodemon": "^2.0.15" } } server.js: Main entry point of the application. // server.js const express = require('express'); const mongoose = require('mongoose'); const dotenv = require('dotenv'); const routes = require('./routes/notes'); const app = express(); dotenv.config(); // Middleware to parse JSON request bodies app.use(express.json()); // Routes app.use('/api/notes', routes); const start = async () => { try { await mongoose.connect(process.env.MONGO_URI); app.listen(process.env.PORT, () => console.log(`Server started on port ${process.env.PORT}`)); } catch (error) { console.error(error); process.exit(1); } }; start(); routes/notes.js: Defines API endpoints for notes. // routes/notes.js const express = require('express'); const router = express.Router(); const notesController = require('../controllers/notesController'); router.get('/', notesController.getAllNotes); router.post('/', notesController.createNote); router.get('/:id', notesController.getNoteById); router.put('/:id', notesController.updateNote); router.delete('/:id', notesController.deleteNote); module.exports = router; controllers/notesController.js: Handles request logic. // controllers/notesController.js const noteService = require('../services/noteService'); const getAllNotes = async (req, res) => { try { const notes = await noteService.getAllNotes(); res.json(notes); } catch (error) { res.status(500).json({ message: error.message }); } }; const createNote = async (req, res) => { try { const newNote = await noteService.createNote(req.body); res.status(201).json(newNote); } catch (error) { res.status(500).json({ message: error.message }); } }; const getNoteById = async (req, res) => { try { const note = await noteService.getNoteById(req.params.id); if (!note) { return res.status(404).json({ message: 'Note not found' }); } res.json(note); } catch (error) { res.status(500).json({ message: error.message }); } }; const updateNote = async (req, res) => { try { const updatedNote = await noteService.updateNote(req.params.id, req.body); if (!updatedNote) { return res.status(404).json({ message: 'Note not found' }); } res.json(updatedNote); } catch (error) { res.status(500).json({ message: error.message }); } }; const deleteNote = async (req, res) => { try { const result = await noteService.deleteNote(req.params.id); if (!result) { return res.status(404).json({ message: 'Note not found' }); } res.status(204).send(); } catch (error) { res.status(500).json({ message: error.message }); } }; module.exports = { getAllNotes, createNote, getNoteById, updateNote, deleteNote, }; models/note.js: Defines the note schema using Mongoose. // models/note.js const mongoose = require('mongoose'); const noteSchema = new mongoose.Schema({ title: { type: String, required: true }, content: { type: String, required: true }, createdAt: { type: Date, default: Date.now }, updatedAt: { type: Date, default: Date.now } }); module.exports = mongoose.model('Note', noteSchema); services/noteService.js: Business logic for notes // services/noteService.js const Note = require('../models/note'); const getAllNotes = async () => { return await Note.find(); }; const createNote = async (noteData) => { con

Feb 22, 2025 - 17:19
 0
production-level Node.js project for a simple note-taking application

Below is an example of a production-level Node.js project for a simple note-taking application, along with its source code structure.

├── package.json
├── server.js
├── routes
│   └── notes.js
├── controllers
│   └── notesController.js
├── models
│   └── note.js
├── services
│   └── noteService.js
├── config
│   └── db.js
└── test
    └── notes.test.js

package.json: Defines project dependencies and scripts.

    {
      "name": "note-taking-app",
      "version": "1.0.0",
      "description": "Simple note-taking application",
      "main": "server.js",
      "scripts": {
        "start": "node server.js",
        "dev": "nodemon server.js",
        "test": "jest --watchAll --coverage"
      },
      "dependencies": {
        "express": "^4.17.1",
        "mongoose": "^6.0.12",
        "dotenv": "^10.0.0",
        "jest": "^27.3.1",
        "supertest": "^6.1.6"
      },
      "devDependencies": {
        "nodemon": "^2.0.15"
      }
    }

server.js: Main entry point of the application.

    // server.js
    const express = require('express');
    const mongoose = require('mongoose');
    const dotenv = require('dotenv');
    const routes = require('./routes/notes');
    const app = express();
    dotenv.config();

    // Middleware to parse JSON request bodies
    app.use(express.json());

    // Routes
    app.use('/api/notes', routes);

    const start = async () => {
      try {
        await mongoose.connect(process.env.MONGO_URI);
        app.listen(process.env.PORT, () => console.log(`Server started on port ${process.env.PORT}`));
      } catch (error) {
        console.error(error);
        process.exit(1);
      }
    };

    start();

routes/notes.js: Defines API endpoints for notes.

    // routes/notes.js
    const express = require('express');
    const router = express.Router();
    const notesController = require('../controllers/notesController');

    router.get('/', notesController.getAllNotes);
    router.post('/', notesController.createNote);
    router.get('/:id', notesController.getNoteById);
    router.put('/:id', notesController.updateNote);
    router.delete('/:id', notesController.deleteNote);

    module.exports = router;


controllers/notesController.js: Handles request logic.

    // controllers/notesController.js
    const noteService = require('../services/noteService');

    const getAllNotes = async (req, res) => {
      try {
        const notes = await noteService.getAllNotes();
        res.json(notes);
      } catch (error) {
        res.status(500).json({ message: error.message });
      }
    };

    const createNote = async (req, res) => {
        try {
            const newNote = await noteService.createNote(req.body);
            res.status(201).json(newNote);
        } catch (error) {
            res.status(500).json({ message: error.message });
        }
    };

    const getNoteById = async (req, res) => {
        try {
            const note = await noteService.getNoteById(req.params.id);
            if (!note) {
                return res.status(404).json({ message: 'Note not found' });
            }
            res.json(note);
        } catch (error) {
            res.status(500).json({ message: error.message });
        }
    };

    const updateNote = async (req, res) => {
        try {
            const updatedNote = await noteService.updateNote(req.params.id, req.body);
            if (!updatedNote) {
                return res.status(404).json({ message: 'Note not found' });
            }
            res.json(updatedNote);
        } catch (error) {
            res.status(500).json({ message: error.message });
        }
    };

    const deleteNote = async (req, res) => {
        try {
            const result = await noteService.deleteNote(req.params.id);
            if (!result) {
                return res.status(404).json({ message: 'Note not found' });
            }
            res.status(204).send();
        } catch (error) {
            res.status(500).json({ message: error.message });
        }
    };

    module.exports = {
        getAllNotes,
        createNote,
        getNoteById,
        updateNote,
        deleteNote,
    };    

models/note.js: Defines the note schema using Mongoose.

    // models/note.js
    const mongoose = require('mongoose');

    const noteSchema = new mongoose.Schema({
      title: {
        type: String,
        required: true
      },
      content: {
        type: String,
        required: true
      },
      createdAt: {
        type: Date,
        default: Date.now
      },
      updatedAt: {
        type: Date,
        default: Date.now
      }
    });

    module.exports = mongoose.model('Note', noteSchema);

services/noteService.js: Business logic for notes

    // services/noteService.js
    const Note = require('../models/note');

    const getAllNotes = async () => {
      return await Note.find();
    };

    const createNote = async (noteData) => {
        const note = new Note(noteData);
        return await note.save();
    };

    const getNoteById = async (id) => {
        return await Note.findById(id);
    };

    const updateNote = async (id, noteData) => {
        return await Note.findByIdAndUpdate(id, noteData, { new: true });
    };

    const deleteNote = async (id) => {
        return await Note.findByIdAndDelete(id);
    };

    module.exports = {
        getAllNotes,
        createNote,
        getNoteById,
        updateNote,
        deleteNote,
    };

config/db.js: Configuration for MongoDB connection.

    // config/db.js
    const mongoose = require('mongoose');

    const connectDB = async () => {
      try {
        await mongoose.connect(process.env.MONGO_URI, {
          useNewUrlParser: true,
          useUnifiedTopology: true,
          useCreateIndex: true,
          useFindAndModify: false
        });
        console.log('MongoDB connected');
      } catch (error) {
        console.error('MongoDB connection error:', error);
        process.exit(1);
      }
    };

    module.exports = connectDB;