简体   繁体   中英

How can I refactor API code in Javascript?

In MEAN stack project there are 2 forms of Express functions here: one that takes a date parameter, and the other that doesn't, and the only difference is the 2nd URL component and aws method name.

-->How can I define 2 functions with all the code, that take the URL component as a parameter, construct the aws method name from that, and then return the Express function, thus reducing the code we need to maintain?

App.js file

API's which does not take date as parameter


const AWS = require("../db/data"),
      aws = new AWS("aws_" + config.db.release.set);


router.get('/data/quern', (req, res) => {
    aws.getdataquern()
        .then(
            record => { res.status(200).send(record) },
            error => { res.status(500).send(error) });
});


router.get('/data/quern1', (req, res) => {
    aws.getdataquern1()
        .then(
            record => { res.status(200).send(record) },
            error => { res.status(500).send(error) });
});

router.get('/data/quern2', (req, res) => {
    aws.getdataquern2()
        .then(
            record => { res.status(200).send(record) },
            error => { res.status(500).send(error) });
});

Api's which takes date as parameter

router.get('/data/withDate/:date', (req, res) => {
    aws.getdatawithDate(req.params.date)
        .then(
            record => { res.status(200).send(record) },
            error => { res.status(500).send(error) });
});

router.get('/data/withDate1/:date', (req, res) => {
    aws.getdatawithDate1(req.params.date)
        .then(
            record => { res.status(200).send(record) },
            error => { res.status(500).send(error) });
});

router.get('/data/withDate2/:date', (req, res) => {
    aws.getdatawithDat2(req.params.date)
        .then(
            record => { res.status(200).send(record) },
            error => { res.status(500).send(error) });
});


You can use one common function for all of them where you pass the aws method you want to call as a string and you pass any argument you want to pass to that function. Also, note that .status(200) is not necessary as that's already the default status.

const AWS = require("../db/data"),
    aws = new AWS("aws_" + config.db.release.set);

function handleResponse(res, awsFnName, arg) {
    aws[awsFnName](arg).then(
        record => { res.send(record) },
        error => { res.status(500).send(error) }
    );
}

router.get('/data/quern', (req, res) => {
    handleResponse(res, "getdataquern");
});

router.get('/data/quern1', (req, res) => {
    handleResponse(res, "getdataquern1");
});

router.get('/data/quern2', (req, res) => {
    handleResponse(res, "getdataquern2");
});

router.get('/data/withDate/:date', (req, res) => {
    handleResponse(res, "getdatawithDate", req.params.date)
});

router.get('/data/withDate1/:date', (req, res) => {
    handleResponse(res, "getdatawithDate1", req.params.date)
});

router.get('/data/withDate2/:date', (req, res) => {
    handleResponse(res, "getdatawithDate2", req.params.date)
});

Note, if the route declarations themselves were really this repetitive, they could be table driven where you generate all the routes in one loop by iterating a table of parameters. Here's how the routes themselves could be generated:

const AWS = require("../db/data"),
    aws = new AWS("aws_" + config.db.release.set);

function handleResponse(res, awsFnName, arg) {
    aws[awsFnName](arg).then(
        record => { res.send(record) },
        error => { res.status(500).send(error) }
    );
}

["quern", "quern1", "quern2"].forEach(suffix => {
    router.get(`/data/${suffix}`, (req, res) => {
        handleResponse(res, `getdata${suffix}`);
    });
});

["withDate", "withDate1", "withDate2"].forEach(suffix => {
    router.get(`/data/${suffix}/:date`, (req, res) => {
        handleResponse(res, `getdata${suffix}`, req.params.date);
    });
});

This code generates all six routes.


I'm not always a huge fan of generated routes because it's not nearly as clear to a reader of the code exactly what routes this code is registering. Obviously, it can be figured out by studying the code, but there is some maintenance advantage to the first method above, even though it has a little more redundancy in the code.

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