简体   繁体   中英

How to Count API Calls using Node.js/Express.js and Mongodb

I want to count all my API calls and update into my mongodb. Please find below my code I am using Express.js mongoose , In this code I fetch my APIUser info from mongodb and validate authorize user and after that increment APICall filed.

This code is working fine when API user is sending request at less rate eg. 10-20req/sec

But in real scenario i am getting large about of request eg. 1000req/sec.

Is there any way i can accurately count my API calls.

kindly replace process.env.MONGOURI with your mongodb url.

app.js -

const express = require('express');
const morgan = require('morgan');
const colors = require('colors');
const dotenv = require('dotenv');
const bodyParser = require('body-parser');
const mongoose = require('mongoose');

dotenv.config({ path: './config/config.env' });

const Employee = require('./models/EmployeeSchema');
const APIUser = require('./models/APIUserSchema');

 mongoose.connect(process.env.MONGOURI, {
      useNewUrlParser: true,
      useCreateIndex: true,
      useUnifiedTopology: true,
    });

const app = express();
app.use(express.json());
app.use(bodyParser.urlencoded({ extended: false }));

app.post('/addemployee', async (req, res, next) => {
  var IP = req.header('X-Real-IP');
  const APIClientInfo = await APIUser.findOne({
    APIClientID: req.header('API-Client-ID'),
    APISecretKey: req.header('API-Secret-Key'),
  });
  //console.log(APIClientInfo);
  if (APIClientInfo) {
    try {
      //Copturaing API Request
      const { Name, PhoneNo, Age, Department, Salary } = req.body;
      const addemployee = await Employee.create(req.body);
      const Response = {
        Status: 'Success',
        Data: addemployee,
        Message: 'Successfully! Record has been inserted.',
      };
      
      APIClientInfo.APICalls++;
      await APIClientInfo.save();

      //Send Response
      res.status(201).json(Response);

      //Log

    } catch (err) {
      //if Valid Error Found
      if (err.name == 'ValidationError') {
        const messages = Object.values(err.errors).map((val) => val.message);
        const Response = {
          Error: {
            message: messages,
          },
        };
        res.status(400).json(Response);
  
      } else {
        const Response = {
          Error: {
            message: 'Internal Server Error',
          },
        };
        res.status(500).json(Response);
        //Send Error
  
      }
    }
  } else {
    //if API-Key is not valid
    res.status(401).json({
      Error: {
        message: 'Unauthorized',
      },
    });
  }
});

app.use((req, resp, next) => {
  resp.setHeader('Access-Control-Allow-Headers', '*');
  resp.setHeader('Access-Control-Allow-Origin', '*');
  resp.removeHeader('X-Powered-By', '*');
  resp.removeHeader('Server', '*');
  next();
});

// Error handling
app.use((req, resp, next) => {
  var error = new Error('Not Found ⛔ ');
  error.status = 404;
  next(error);
});

app.use((error, req, resp, next) => {
  resp.status(error.status || 500);
  resp.json({
    Error: {
      message: error.message,
    },
  });
});

//console.log = function(){};

const PORT = process.env.PORT || 5000;

app.listen(
  PORT,
  console.log(
    `Server Started in ${process.env.NODE_ENV} mode on Port ${PORT}`.white.bold
  )
);

APIUser Schema -

const mongoose = require('mongoose');
const uuid = require('uuid');
const moment = require('moment-timezone');

const UserSchema = new mongoose.Schema({
  _id: {
    type: String,
    default: uuid.v4,
  },
  Username: {
    type: String,
    index: { unique: true },
    required: [true, 'Please Enter Your UserName'],
  },
  Password: {
    type: String,
    required: [true, 'Please Enter Your Password'],
  },
  Email: {
    type: String,
    index: { unique: true },
    required: [true, 'Please Enter Your Email ID'],
  },
  APIClientID: {
    type: String,
    index: { unique: true },
    minlength: 10,
    maxlength: 40,
    default: uuid.v4,
  },
  APISecretKey: {
    type: String,
    index: { unique: true },
    minlength: 10,
    maxlength: 40,
    default: uuid.v4,
  },
  APICalls: {
    type: Number,
    default: 0,
  },
  CreatedAt: {
    type: String,
    default: function () {
      return moment().tz('Asia/Kolkata').format('MMMM Do YYYY, hh:mm:ss A');
    },
  },
  ModifiedAt: {
    type: String,
    default: function () {
      return moment().tz('Asia/Kolkata').format('MMMM Do YYYY, hh:mm:ss A');
    },
  },
});

UserSchema.set('toJSON', {
  transform: function (doc, ret, options) {
    ret.UserRefNo = ret._id;
    delete ret._id;
    delete ret.__v;
  },
});

module.exports = mongoose.model('APIUser', UserSchema);

EmployeeSchema.js -

const mongoose = require('mongoose');
const uuid = require('uuid');
const moment = require('moment-timezone');

const EmployeeSchema = new mongoose.Schema({
  _id: {
    type: String,
    default: uuid.v4,
  },
  Name: {
    type: String,
    trim: true,
    required: [true, 'Please Enter Your Name'],
  },
  PhoneNo: {
    type: String,
    trim: true,
    required: [true, 'Please Enter Your Phone No'],
  },
  Age: {
    type: String,
    required: [true, 'Please Enter Your Employee Age'],
  },
  Department: {
    type: String,
    trim: true,
    required: [true, 'Please Enter Your Department Name'],
  },
  Salary: {
    type: String,
    required: [true, 'Please Enter Your Employee Salary PA'],
  },
  CreatedAt: {
    type: String,
    default: function () {
      return moment().tz('Asia/Kolkata').format('MMMM Do YYYY, hh:mm:ss A');
    },
  },
  ModifiedAt: {
    type: String,
    default: function () {
      return moment().tz('Asia/Kolkata').format('MMMM Do YYYY, hh:mm:ss A');
    },
  },
});

EmployeeSchema.set('toJSON', {
  transform: function (doc, ret, options) {
    ret.EmpRefNo = ret._id;
    delete ret._id;
    delete ret.__v;
  },
});

module.exports = mongoose.model('Employee', EmployeeSchema);

Try updating the api calls value with a single function of updateOne :

 await APIUser.updateOne({
    APIClientID: req.header('API-Client-ID'),
    APISecretKey: req.header('API-Secret-Key'),
  }, {
    $inc: {
      APICalls: 1
    }
  });
 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM