How do I grab json from an external api (serp api) from my backend and then make that same data available for my front end application?

Viewed 60

Right now I have a front end react application using axios and and a backend server using node.js and express. I cannot for the life of me get my serp api data to post so that my front end can get it through axios and display the json data. I know how to get data to the front end but I am not a backend developer so this is proving to be incredibly difficult at the moment. I'm able to get the data from the the external api, I just don't know how to post it once I get it. Also I would not like to have all these request running on server.js so I created a controller but I think that is where it is messing up. Any help is appreciated

//pictures controller 

const SerpApi = require('google-search-results-nodejs');
const {json} = require("express");
const search = new SerpApi.GoogleSearch("674d023b72e91fcdf3da14c730387dcbdb611f548e094bfeab2fff5bd86493fe");
const handlePictures = async (req, res) => {
const params = {
    q: "Coffee",
    location: "Austin, Texas, United States",
    hl: "en",
    gl: "us",
    google_domain: "google.com"
};

const callback = function(data) {
    console.log(data);
    return res.send(data);
};

// Show result as JSON
search.json(params, callback);
    //res.end();
}
// the above code works. how do i then post it to the server so that i can retrieve it to the backend?

    module.exports = {handlePictures};


//server.js

const express = require('express');
const app = express();
const path = require('path');
const cors = require('cors');
const corsOptions = require('./config/corsOptions');
const { logger } = require('./middleware/logEvents');
const errorHandler = require('./middleware/errorHandler');
const cookieParser = require('cookie-parser');
const credentials = require('./middleware/credentials');
const PORT = process.env.PORT || 3500;

// custom middleware logger
app.use(logger);

// Handle options credentials check - before CORS!
// and fetch cookies credentials requirement
app.use(credentials);

// Cross Origin Resource Sharing
app.use(cors(corsOptions));

// built-in middleware to handle urlencoded form data
app.use(express.urlencoded({ extended: false }));

// built-in middleware for json 
app.use(express.json());

//middleware for cookies
app.use(cookieParser());

//serve static files
app.use('/', express.static(path.join(__dirname, '/public')));

// routes
app.use('/', require('./routes/root'));
app.use('/pictures', require('./routes/api/pictures'));



app.all('*', (req, res) => {
    res.status(404);
    if (req.accepts('html')) {
        res.sendFile(path.join(__dirname, 'views', '404.html'));
    } else if (req.accepts('json')) {
        res.json({ "error": "404 Not Found" });
    } else {
        res.type('txt').send("404 Not Found");
    }
});


app.use(errorHandler);

app.listen(PORT, () => console.log(`Server running on port ${PORT}`));
//api/pictures.js
const picturesController= require('../../controllers/picturesController');
const express = require('express')
const router = express.Router();



// for POST request use app.post
router.route('/')
.post( async (req, res) => {
    // use the controller to request external API
    const response = await picturesController.handlePictures()
    // send the response back to client
    res.json(response)
})


module.exports = router;
2 Answers

You just need to return the result from SerpApi in your handlePictures function. To do this make a new Promise and when search.json runs callback do what you need with the results and pass it in resolve.

Your picturesController.js with an example of returning all results.

//pictures controller

const SerpApi = require("google-search-results-nodejs");
const { json } = require("express");
const search = new SerpApi.GoogleSearch(process.env.API_KEY);         //your API key from serpapi.com
const handlePictures = async (req, res) => {
  return new Promise((resolve) => {
    const params = {
      q: "Coffee",
      location: "Austin, Texas, United States",
      hl: "en",
      gl: "us",
      google_domain: "google.com",
    };

    const callback = function(data) {
        resolve(data);
    };

    search.json(params, callback);
  });
};

module.exports = { handlePictures };

Output: enter image description here

And I advise you to change your API key to SerpApi to prevent it from being used by outsiders.

Since I don't have the full context of your App I can just assume the context. But given the fact that you already have wrapped the logic of calling the external API into a dedicated controller you can use it in the following way in an express app (used the hello world example from express):

// import your controller here
const express = require('express')
const app = express()
const port = 3000

// for POST request use app.post
app.get('/', async (req, res) => {
  // use the controller to request external API
  const response = await yourController.method()
  // send the response back to client
  res.json(response)
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

Here's an example how to execute the http request from the frontend:

const response = await fetch('http://localhost:3000') // result from res.json(response)
Related