How do I properly route data through my Node API?

I have the following files:

My routes – where the orders_count route lives:

routes/index.js

const express = require('express');
const router = express.Router();

const transactionsController = require('../controllers/transactionsController');
const ordersController = require('../controllers/ordersController');
const ordersCountController = require('../controllers/ordersCountController');

router.get('/transactions', transactionsController);
router.get('/orders', ordersController);
router.get('/orders_count', ordersCountController);

module.exports = router;

I then have my orders count controller living in the controllers directory:

controllers/ordersCountController.js

const ordersCountService = require('../services/ordersCountService');

const ordersCountController = (req, res) => {
    ordersCountService((error, data) => {
        if (error) {
            return res.send({ error });
        }

        res.send({ data })
    });
};

module.exports = ordersCountController;

My controller then calls my order count service which fetches data from another API.

services/ordersService.js

const fetch = require('node-fetch');

// connect to api and make initial call
const ordersCountService = (req, res) => {
    const url = ...;

    const settings = { method: 'Get'};

    fetch(url, settings)
        .then(res => {
            if (res.ok) {
                res.json().then((data) => {
                    return data;
                });
            } else {
                throw 'Unable to retrieve data';
            }
        }).catch(error => {
        console.log(error);
    });
}

module.exports = ordersCountService;

I’m trying to return the JSON response. I initially had it setup with requests but looking at the NPM site, it appears that it’s depreciated so have been digging through how to use node-fetch.

I have tried both ‘return data’ and res.send({data}), but neither are solving the problem.

I am still new to this so I am likely missing something very obvious, but how come I am not sending the JSON back through so that it displays at the /api/orders_count endpoint?

I keep thinking I messed something up in my controller but have been looking at it for so long and can’t seem to figure it out.

Any help would be greatly appreciated and if there is anything I can add for clarity, please don’t hesitate to ask.

Best.

Answer

  1. please learn promises and await syntax. life will be easier.
  2. never throw a string. always prefer a real error object, like that : throw new Error(‘xxx’); that way you will always get a stack. its way easier to debug.
  3. avoid the callback hell : http://callbackhell.com/
  4. you need to decide if you want to catch the error in the controller or in the service. no need to do in both.
  5. in the controller you call the service that way :
ordersCountService((error, data) => {

but you declare it like that :

const ordersCountService = (req, res) => {

which is not compatible. it should look like this if you work with callback style :

const ordersCountService = (callback) => {
...
if (error) return callback(error)
...
callback(null, gooddata);

here is an example to flatten your ordersCountService function to await syntax, which allows the “return data” you were trying to do :

const fetch = require('node-fetch');

// connect to api and make initial call
const ordersCountService = async (req, res) => {
    const url = ...;

    const settings = { method: 'Get'};
    try {
        const res = await fetch(url, settings);
        if (!res.ok) throw new Error('Unable to retrieve data');

        return await res.json();
    } catch(error) {
        console.log(error);
    }
}

module.exports = ordersCountService;

in fact i would prefer to error handle in the controller. then this woud be sufficient as a service

const fetch = require('node-fetch');

// connect to api and make initial call
const ordersCountService = async () => {
    const url = ...;

    const settings = { method: 'Get'};
    const res = await fetch(url, settings);
    if (!res.ok) throw new Error('Unable to retrieve data');

    return await res.json();
}

module.exports = ordersCountService;

then you can call this funtion like this :

try {
  const data = await ordersCountService(req, res);
} catch(err) {
  console.log(err);
}

//or 
ordersCountService(req, res).then((data) => console.log(data)).catch((err) => console.error(err));