4

I am building a search engine that queries the Twitter and Wiki APIs server-side after the client POSTs the search string. When I was still completely client-side the AJAX request to the Wiki API looked like:

$.ajax({
    url: 'https://en.wikipedia.org/w/api.php',
    data: {
        action: 'query',
        list: 'search',
        srsearch: searchString, // variable pulled from input
        format: 'json',
        //origin: 'https://www.mediawiki.org'
    },
    xhrFields: {
        withCredentials: true
    },
    dataType: 'jsonp' // will probably use 'json' now that I'm server-side
}).done( function ( data ) {
    searchParser(data);
});
... //searchParser() below

Now, I have implemented a Node.js web app that takes the search string from a client-side form POST on the home page (index.ejs). The server will then render the results page (results.ejs) with the wiki and twitter search results. Twitter API search is already handled with BoyCook's TwitterJSClient.

I would like to know the best way to perform this exact query from my server. I have been looking around and cannot find a succinct answer. Does anyone have any advice on this?

Justin
  • 63
  • 2
  • 6
  • Node offers [`http.request()`](https://nodejs.org/api/http.html#http_http_request_options_callback) and [`http.get()`](https://nodejs.org/api/http.html#http_http_get_options_callback) for this. – Jonathan Lonowski Oct 04 '15 at 21:17
  • Sure, but what about the dataType field and xhrFields field? – Justin Oct 04 '15 at 21:34
  • There is no build-in equivalent to `dataType`. You'll have to parse the response yourself -- [`JSON.parse()`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/parse). As for credentials, the `Authorization` header may be available, if the request from the client includes it -- and you'll have to copy it to this request. The browser won't have sent cookies related to `en.wikipedia.org` or `twitter.com` to your server. – Jonathan Lonowski Oct 04 '15 at 21:37
  • Thanks for your help. See final result below. – Justin Oct 05 '15 at 06:24

2 Answers2

1

Here is the solution I came to based on Jonathan's reply:

function wikiSearch () {

    var query = querystring.stringify({
        action: 'query',
        list: 'search',
        srsearch: searchString,
        srlimit: 10,
        srwhat: 'text',
        format: 'json'
    });
    var options = {
        hostname: 'en.wikipedia.org',
        path: '/w/api.php?' + query
    };

    var req = https.request(options, function(res) {

        if (!res) { 
            wikiData = "An error occured!";
            complete();
        };

        var body = '';
        console.log("statusCode: ", res.statusCode);
        res.setEncoding('utf8');

        res.on('data', function(data) {
            body += data;
        });

        res.on('end', function() {
            wikiData = wikiDataParser( JSON.parse(body) );
            complete();
        });
    });

    req.end();
    req.on('error', function (err) {
        wikiData = "<h2>MediaWiki API is currently down.</h2>";
        complete();
    })

};
... // complete() is below

This changes the wikiData variable according to the request or response.

Community
  • 1
  • 1
Justin
  • 63
  • 2
  • 6
0

Learn about the MEAN stack. For starters, usually somebody has built a module you would install with NPM that would simplify connecting to the api. You could do it manually, but no point if an official release for node.js is available:

npm install twitter

below goes in your main express app file. It's simplified for example sake.

//include this....loads the twitter client api app...will make this a breeze
        var Twitter = require('twitter');

    //your access keys and info to login into the api....fill them.
        var client = new Twitter({
          consumer_key: '',
          consumer_secret: '',
          access_token_key: '',
          access_token_secret: ''
        });

    //the below code executes when you hit this path

    app.post('/getTweetsYo', function (res, req, data) {

// gets username from ajax post of user data....access via req.data. Passes it to twitter api request
        var params = {screen_name: req.data.username };
        client.get('statuses/user_timeline', params, function(error, tweets, response){
          if (!error) {
            console.log(tweets);

    // sending the tweets back to the front end!

    res.send(tweets);

          }
    });
deek
  • 1,085
  • 1
  • 9
  • 27