Express.js Mastery / Express: Letโ€™s Start Building The Natours API!

Implementing the "Users" Routes

๐Ÿ“– Context

The API will have multiple resources โ€” the tours resource has already been implemented, and now it's time to start on a second one: the users resource (for user accounts, roles, etc.). This is being set up now for two reasons:

  1. The project needs to keep moving forward.

  2. It's needed as groundwork for something upcoming in the course.


๐Ÿ”น Step 1: Defining the Users Routes

Following the exact same pattern already used for tours
(app.route() with chained methods):

app
  .route('/api/v1/users')
  .get(getAllUsers)
  .post(createUser);

app
  .route('/api/v1/users/:id')
  .get(getUser)
  .patch(updateUser)
  .delete(deleteUser);

๐Ÿ’ก Why this structure works (same logic as tours):

  • ๐Ÿ‘ฅ Route without an ID (/api/v1/users):

    • ๐Ÿ“– GET โ†’ get all users (all objects belonging to this resource).

    • โž• POST โ†’ create a new user.

  • ๐Ÿ‘ค Route with an ID parameter (/api/v1/users/:id):

    • ๐Ÿ” GET โ†’ get one specific user.+2+362

    • โœ๏ธ PATCH โ†’ update that user.

    • ๐Ÿ—‘๏ธ DELETE โ†’ delete that user.

๐Ÿท๏ธ Naming convention: functions are named getAllUsers and getUser (rather than getOneUser) โ€” a personal style choice, since different naming standards exist.


๐Ÿ”น Step 2: Creating Placeholder Handler Functions

Since the actual user logic isn't being built yet, all five handlers are simple placeholders that return a "not implemented" response:

  • Right after the last route handler from the tour add this placeholder handler function:

const getAllUsers = (req, res) => {
  res.status(500).json({
    status: 'error',
    message: 'This route is not yet defined'
  });
};

const getUser = (req, res) => {
  res.status(500).json({
    status: 'error',
    message: 'This route is not yet defined'
  });
};

const createUser = (req, res) => {
  res.status(500).json({
    status: 'error',
    message: 'This route is not yet defined'
  });
};

const updateUser = (req, res) => {
  res.status(500).json({
    status: 'error',
    message: 'This route is not yet defined'
  });
};

const deleteUser = (req, res) => {
  res.status(500).json({
    status: 'error',
    message: 'This route is not yet defined'
  });
};

๐Ÿ’ก Why each part works:

  • ๐Ÿ”ด 500 indicates the feature isn't implemented yet.

  • โŒ status: 'error' is used for server-side errors.

  • ๐Ÿ“ฆ Response format: status + message.

  • ๐Ÿ“„ These functions are placed below the tour route handlers.


๐Ÿ”น Step 3: Testing in Postman

  1. Duplicate an existing request and change the URL to target /api/v1/users.

  2. Sending it returns the expected 500 response with "This route is not yet defined".

  1. Save the request into the same Postman collection, but organized into a new folder.

  2. Create folders named after each resource โ€” one for tours, one for users โ€” to keep the collection organized as more routes get added.


๐Ÿ”น Step 4: Acknowledging the File's Growing Mess

  • ๐Ÿ“ˆ At this point, the single file contains routes, route handlers (also referred to as controllers), and server startup code all mixed together.

  • ๐Ÿงน This is becoming harder to manage as the project grows.


โœ… Key Takeaway

  • ๐Ÿ‘ฅ Users follow the same routing pattern as tours using app.route().

  • ๐ŸŽฎ Route handlers are commonly called controllers.

  • ๐Ÿ”ด 500 + status: 'error' is a placeholder for unimplemented functionality.

  • ๐Ÿ“‚ Organize Postman requests into folders (e.g., Tours, Users).

  • ๐Ÿงฉ The current single-file structure is temporary and will be refactored soon.


โžก๏ธ What's Next

๐Ÿ—๏ธ The next step will begin separating routes, controllers, and other pieces into their own files for better project structure.