DEV Community

indrasisdatta
indrasisdatta

Posted on

1

Using Middleware to Format Express API Response

Middleware in Express allows you to customize and enhance the request-response cycle. One powerful application of middleware is to format the response before it is sent back to the client.

We'll explore how to create a middleware function to expose only specific user fields and restrict fields like password, _id etc.

Route

import { Router } from "express";
const router = Router();
router.get("/profile", getUserProfile, UserResponse);
Enter fullscreen mode Exit fullscreen mode

Controller

We are fetching user details based on request POST param userId.

user returns Mongoose User but we don't want to expose all fields in our response. Therefore, we can assign the response json to res.locals so that it can be passed on to the middleware.
Ref:

/* User profile details */
export const getUserProfile = async (
  req: Request,
  res: Response,
  next: NextFunction
) => {
  try {
    const { userId } = req;
    if (!userId ) {
      return res.status(400).json({
        status: 0,
        data: null,
        error: "User not found",
      });
    }
    const user = User.findById(userId);
    // Store data here, which can be accessed in middleware
    res.locals.apiResponse = {
      status: 1,
      data: user,
    };
    next(); // this is important so that it's forwarded to UserResponse middleware
  } catch (error) {
    res.status(500).json({ status: API_STATUS.ERROR, error });
  }
};
Enter fullscreen mode Exit fullscreen mode

Creating the middleware

import { NextFunction, Request, Response } from "express";

export const UserResponse = (
  req: Request,
  res: Response,
  Next: NextFunction
) => {
  try {
    if (res.locals?.apiResponse) {
      if (
        res.locals.apiResponse?.status == 1 &&
        typeof res.locals.apiResponse?.data === "object" &&
        res.locals.apiResponse?.data.constructor.modelName === "User"
      ) {
        const tempUser = res.locals.apiResponse?.data.toObject();
        /* Delete all private fields so that only necessary fields are exposed */
        delete tempUser._id;
        delete tempUser.createdAt;
        delete tempUser.updatedAt;
        delete tempUser.password;
        delete tempUser?.__v;
        return res.status(200).json({
          status: res.locals.apiResponse?.status,
          data: tempUser,
        });
      }
    }
    return res.status(200).json(res.locals);
  } catch (error) {
    res.status(500).json({ status: 0, error });
  }
};

Enter fullscreen mode Exit fullscreen mode

Postmark Image

Speedy emails, satisfied customers

Are delayed transactional emails costing you user satisfaction? Postmark delivers your emails almost instantly, keeping your customers happy and connected.

Sign up

Top comments (0)

A Workflow Copilot. Tailored to You.

Pieces.app image

Our desktop app, with its intelligent copilot, streamlines coding by generating snippets, extracting code from screenshots, and accelerating problem-solving.

Read the docs

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay