我正在尝试扩展request
以劫持和增强其response
和其他“身体”参数。最后,我想为我的API添加一些便利方法:
var myRequest = require('./myRequest');
myRequest.get(function(err, hijackedResponse, rows) {
console.log(hijackedResponse.metadata)
console.log(rows)
console.log(rows.first)
});
根据inherits
上的节点文档,我认为我可以使其工作(并使用文档中的EventEmitter
示例正常工作)。我尝试使用@Tlott的建议让它工作,但意识到对于我的用例它可能不会起作用:
// 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
作为参数。
答案 0 :(得分:1)
更新以回答编辑过的问题:
以下是myResponse.js
内容的粗略模板。它只实现get()
。但是,作为一个简单的骨头,这是一个如何做这种可以完成的演示,我希望它能让你前进。
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;
原文回答:
查看the source code for the Request
constructor,它需要一个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()
破坏了第一个参数的任何现有原型方法。