0

我正在尝试扩展request以劫持和增强其response和其他“身体”参数。最后,我想为我的 API 添加一些方便的方法:

var myRequest = require('./myRequest');
myRequest.get(function(err, hijackedResponse, rows) {
    console.log(hijackedResponse.metadata)
    console.log(rows)
    console.log(rows.first)
});

根据 Node 文档inherits,我认为我可以使它工作(并且使用EventEmitter文档中的示例可以正常工作)。我尝试使用@Trott 的建议让它工作,但意识到对于我的用例它可能不起作用:

// myRequest.js
var inherits = require('util').inherits;
var Request = require("request").Request;

function MyRequest(options) {
    Request.call(this, options);
}

inherits(MyRequest, Request);

MyRequest.prototype.pet = function() {
    console.log('purr')
}

module.exports = MyRequest;

我也一直在玩弄extend,希望我能找到一种方法来拦截请求的onRequestResponse原型方法,但我正在画空白:

var extend = require('extend'),
    request = require("request")

function myResponse() {}

extend(myResponse, request)

// maybe some magic happens here?

module.exports = myResponse

结束了:

var extend = require('extend'),
    Ok = require('objectkit').Ok

function MyResponse(response) {
    var rows = Ok(response.body).getIfExists('rows');
    extend(response, {
        metadata: extend({}, response.body),
        rows: rows
    });
    response.first = (function() {
        return rows[0]
    })();
    response.last = (function() {
        return rows[rows.length - 1] || rows[0]
    })();
    delete response.metadata.rows
    return response;
}

module.exports = MyResponse

请记住,在此示例中,我作弊并将其全部写在.get()方法中。在我的最终包装模块中,我实际上将method其作为参数。

4

1 回答 1

1

已更新以回答已编辑的问题:

这是您的内容的粗略模板myResponse.js。它只实现get(). 但作为一个简单的框架,this-is-how-this-sort-of-thing-can-be-done demo,我希望它能让你继续前进。

var request = require('request');

var myRequest = {};

myRequest.get = function (callback) {
    // hardcoding url for demo purposes only
    // could easily get it as a function argument, config option, whatever...
    request.get('http://www.google.com/', function (error, response, body) {
        var rows = [];
        // only checking error here but you might want to check the response code as well
        if (!error) {
            // mess with response here to add metadata. For example...
            response.metadata = 'I am awesome';

            // convert body to rows however you process that. I'm just hardcoding.
            // maybe you'll use JSON.parse() or something.
            rows = ['a', 'b', 'c'];

            // You can add properties to the array if you want.
            rows.first = 'I am first! a a a a';
        }

        // now fire the callback that the user sent you...
        callback(error, response, rows);
    });
};

module.exports = myRequest;

原始答案:

查看构造函数的源代码Request,它需要一个options对象,而该对象又需要一个uri属性。

所以你需要指定这样一个对象作为你的第二个参数call()

Request.call(this, {uri: 'http://localhost/'});

您可能不想uri在构造函数中进行这样的硬编码。您可能希望代码看起来更像这样:

function MyRequest(options) {
    Request.call(this, options);
}

...

var myRequest = new MyRequest({uri: 'http://localhost/'});

为了使您的代码正常工作,您还需要移到util.inherits(). MyRequest.prototype.pat()似乎util.inherits()破坏了第一个参数的任何现有原型方法。

于 2015-09-11T05:32:48.570 回答