Skip to Content
Lab 2

Mongoose Models and Schemas

Scenario

A local library wants to modernize its book tracking system. They have hired you to build the backend for a new “Digital Bookshelf” application. Your first task is to create a RESTful API that allows librarians to manage their book inventory. This API must support creating new book records, viewing the list of all books, finding a specific book by its ID, updating a book’s information, and removing a book from the collection.


Learning Objectives

By the end of this activity, you will have demonstrated your ability to:

  • Define a Mongoose schema with appropriate data types and validation.
  • Compile a schema into a Mongoose model.
  • Build a full CRUD (Create, Read, Update, Delete) API using Express.
  • Implement separate, modular routes for your API endpoints.
  • Use Mongoose model methods to interact with a MongoDB database.
  • Handle request data from req.body and req.params.

Instructions

Task 1: Project Setup

  1. Create a new project directory (e.g., digital-bookshelf-api).
  2. Initialize the project with npm init -y.
  3. Install the required dependencies: express, mongoose, and dotenv.
  4. Set up your file structure. It’s a good practice to separate your concerns. Create the following:
    • server.js: The main entry point for your application.
    • db/: A directory to hold your database connection logic.
    • models/: A directory for your Mongoose models.
    • routes/: A directory for your Express route definitions.
  5. Create a .env file and add your MongoDB Atlas connection string to it.
  6. Create a .gitignore file and add node_modules/ and .env to it.

Task 2: Database Connection

  1. In the db/ directory, create a connection.js file.
  2. In this file, use mongoose.connect() to establish a connection to your database using the URI from your .env file. Export your connection logic.
  3. In server.js, require and execute your database connection.

Task 3: Book Schema and Model

  1. In the models/ directory, create a Book.js file.
  2. Define a schema for a Book with the following fields and validation rules:
    • title: A String, which is required.
    • author: A String, which is required.
    • isbn: A String, which must be unique.
    • publishedDate: A Date.
    • inStock: A Boolean, with a default value of true.
  3. Compile this schema into a model named Book and export it.

Task 4: API Routes

  1. In the routes/ directory, create a bookRoutes.js file.
  2. Use express.Router() to create a new router instance.
  3. Implement the five core CRUD endpoints on this router:
    • Create: POST / - Creates a new book using the data in req.body.
    • Read All: GET / - Retrieves all books from the database.
    • Read One: GET /:id - Retrieves a single book by its _id.
    • Update: PUT /:id - Updates a book by its _id using the data in req.body.
    • Delete: DELETE /:id - Deletes a book by its _id.
  4. Use async/await and try...catch blocks in all routes to handle errors.
  5. Export the router.

Task 5: Server Configuration

  1. In server.js:
    • Set up your Express application.
    • Use the express.json() middleware to parse request bodies.
    • Mount your book router at a base path, like /api/books.
    • Start the server on a specified port.

Submission Instructions

  1. Ensure your application runs without errors using node server.js.
  2. Test all five of your API endpoints using an API client like Postman or Insomnia. Verify that each one performs the correct CRUD operation.
  3. Submit a link to a GitHub repository containing your complete project. Do not include your .env file or the node_modules directory.

Grading Rubric

CriteriaDescriptionPoints
Project Setup (10 points)
File Structure & DependenciesProject has the correct modular structure (db/, models/, routes/) and all dependencies are installed.5
Database ConnectionA separate connection.js file successfully connects to the MongoDB Atlas database on startup.5
Schema & Model (10 points)
Schema DefinitionBook.js defines a schema with all required fields (title, author, isbn, etc.).5
Schema Validationtitle and author are required; isbn is unique; inStock has a default value.5
API Endpoints (30 points)
POST /api/books (Create)Correctly creates and saves a new book document. Responds with the created document and a 201 status.6
GET /api/books (Read All)Correctly fetches and returns an array of all book documents.6
GET /api/books/:id (Read One)Correctly fetches and returns a single book document by its ID. Handles cases where the ID is not found.6
PUT /api/books/:id (Update)Correctly finds a book by ID and updates it with req.body. Returns the updated document.6
DELETE /api/books/:id (Delete)Correctly finds a book by ID and deletes it. Returns a confirmation message.6
Total50

Reflection Questions

  1. Why is it beneficial to separate your routes, models, and database connection into different directories?
  2. What is the difference between PUT and PATCH HTTP methods, and which one does your PUT /:id endpoint more closely resemble?
  3. In the DELETE route, what is a good practice for the response you send back to the client after a successful deletion? Should you send the deleted object, a simple success message, or something else? Why?