darshan a n
darshan a n

Reputation: 538

proper way to return json format using node or express

My question is actually copied from Proper way to return JSON using node or Express. I need the response in this format.

Sample format for response API

{
"success":true,
"code":200,
"message":"Ok",
"data": []
}

I followed all the methods provided in the above question, but still i couldn't crack the right answer. since i have many apis, i need this response format for every api.

app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

app.use((req, res, next) => {
    res.header("Access-Control-Allow-Origin", "*");
    res.header(
        "Access-Control-Allow-Headers",
        "Origin, X-Requested-With, Content-Type, Accept, Authorization"
    );
    if (req.method === "OPTIONS") {
        res.header("Access-Control-Allow-Methods", "POST,  DELETE, GET");
        return res.status(200).json({});
    }
    next();
});
app.use("/api", employeeRoutes);
app.use("/api", groupRoutes);

app.use((req, res, next) => {
    const error = new Error("Not found");
    error.status = 404;
    next(error);
});

the above snippet is of my app.js file. And my route code looks somethig like this.

exports.groups_Get_All = (req, res, next) => {
    Group.find()
        .exec()
        .then(docs => {
            const response =
                docs.map(doc => {
                    return {
                        gname: doc.gname,
                        employee: doc.employeeId,
                        _id: doc._id,
                        createdAt: doc.createdAt
                    };
                })
            res.send((response));
        })
        .catch(err => {
            console.log(err);
            res.status(500).json({
                error: err
            });
        });
};

Right now im getting response of just plain data in json format.

[
    {
        "gname": "wordpres",
        "employee": [
            "5c6568102773231f0ac75303"
        ],
        "_id": "5c66b6453f04442603151887",
        "createdAt": "2019-02-15T12:53:25.699Z"
    },
    {
        "gname": "wordpress",
        "employee": [
            "5c6568102773231f0ac75303"
        ],
        "_id": "5c66cbcf1850402958e1793f",
        "createdAt": "2019-02-15T14:25:19.488Z"
    }
]

Now my question is how to implement this sample format response to every api(global scope)?

Upvotes: 3

Views: 5864

Answers (3)

Contrails
Contrails

Reputation: 11

You can create a middleware to extend your response

// middlewares/responseFormatter.js

module.exports = (req, res, next) => {
  res.success = function ({ success = true, code = 200, data, message = 'ok' }) {
    this.json({
      success,
      code,
      message,
      data
    })
  }

  res.error = function ({ success = false, code = 400, error, message = 'error' }) {
    this.json({
      success,
      code,
      message,
      error
    })
  }

  next()
}

Then import it in app.js

const responseFormatter = require('./middlewares/responseFormatter')
app.use(responseFormatter)

Now you can use it through this way

const res = { data: [] }

res.success(res)

and you will get the response

{
  "success":true,
  "code":200,
  "message":"Ok",
  "data": []
}

Upvotes: 0

felipezarco
felipezarco

Reputation: 86

You can simply use responser package, it will handle this.

This manually crafted response:

res.status(400).json({
  status: 'BAD_REQUEST',
  code: 400,
  message: 'Request is wrong!',
  success: false,
  data: []
})

Will be as simple as:

res.send_badRequest('Request is wrong!', [])

To have this send_badRequest and all other http methods in your express response by default, just add responser as your middleware:

app.use(responser) 

Full example below:

const express = require('express')
const responser = require('responser').default
const app = express()
const router = express.Router()
app.use(responser) // <<<< responser middleware here
app.use(router)

router.get('/planets', (request, response, next) => {
  const planets = ['Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
  return response.send_ok('Planets were found successfully', { 
      planets, 
      planetsCount: planets.length 
  })
})

app.listen(3000, () => console.log('Server running on port 3000'))

Which outputs to:

HTTP/1.1 200 OK
X-Powered-By: Express
Content-Type: application/json; charset=utf-8
{
  "status": "OK",
  "code": 200,
  "success": true,
  "message": "Planets were found successfully",
  "data": {
    "planets": [
      "Mercury",
      "Venus",
      "Earth",
      "Mars",
      "Jupiter",
      "Saturn",
      "Uranus",
      "Neptune"
    ],
    "planetsCount": 8
  }
}

Upvotes: 0

Supermacy
Supermacy

Reputation: 1489

If you are using express, don't send the message from the controller. Make a middleware that's main purpose is to send the response to the client. This will give you a power of setting the format of consist response to the client.

For Example I have made the response middleware like this :-

module.exports = function(req, res, next) {
  const message = {};
  message.body = req.responseObject;
  message.success = true;
  message.status = req.responseStatus || 200;
  res.status(message.status).send(message);
  return next();
};

Above code will generate the format like this.

{
  "success": true,
  "status": 200,
  "body": {
    "name": "rahul"
  }
}

You can use request uplifter property of express. You can add responseObject and responseStatus from previous middleware.

Errors can be made in separate middleware likewise.

You can call by this in your routes:-

const responseSender = require('./../middleware/responseSender');
 /* your rest middleware. and put responseSender middleware to the last.*/
router.get('/',/* Your middlewares */, responseSender);

You can call it by:-

exports.groups_Get_All = (req, res, next) => {
    Group.find()
        .exec()
        .then(docs => {
            const response =
                docs.map(doc => {
                    return {
                        gname: doc.gname,
                        employee: doc.employeeId,
                        _id: doc._id,
                        createdAt: doc.createdAt
                    };
                })

            req.responseObject = response; // This will suffice
            return next()
        })
        .catch(next);
}

Upvotes: 1

Related Questions