Interfacer.js 4.22 KB
var util = require('util');
var Emitter=require('events');
var Request = require('request');
var async=require('async');
/*接口*/
var _ = require('lodash');

var Utils=require('./Utils');


var Interfacer=function(config,app){
	this.config=config;
	this.CONSTS=app.get("Register");
	this.config.domain=this.config.domain||app.get("Register").domain;
	this.apis={};
	Emitter.call(this);
};

util.inherits(Interfacer,Emitter);

Interfacer.prototype.register = function(mos) {
	var me=this,name=mos.namespace;
	if(!name){
		console.info(" Interfacer name can not empty");
	}
	for(var key in mos.apis){
		var name_key=name+"_"+key;
		if(me.isExisted(name_key)){
			console.info("can not add repeat Interfacer key,please checkout");
		}
		/*需要进行验证判断*/
		me.apis[name_key]=mos.apis[key];
	}
};

Interfacer.prototype.isExisted=function(key){
	return !!this.apis[key];
};

function __requestApi(config, apiOpt, req, callback){
	var me=this;
    if (typeof apiOpt == "function") {
        return apiOpt.call(0, req, function (err, result) {
            req._yoheaders = req._yoheaders;
            return callback(null, result);
        });
	}
    var method = apiOpt.method || "POST";
	var data={};
	if(apiOpt.params&&(_.isArray(apiOpt.params)||_.isPlainObject(apiOpt.params))){
		if(_.isArray(apiOpt.params)){
			apiOpt.params.forEach(function(param){
				var name=param.name;
				if(req.param(name)){
					if(param.type.toUpperCase()=="NUMBER"){
						data[name]=Number(req.param(name));
					}else{
						data[name]=String(req.param(name));
					}
				}
			});
		}else
		if(_.isPlainObject(apiOpt.params)){
			for(var name in apiOpt.params){
				var param=apiOpt.params[name];
				if(param.default){
					data[name]=param.type(param.default);
				}
				if(req.param(name)){
					data[name]=param.type(req.param(name));
				}
			}
		}
	}
	var options={
		url: Utils.template((apiOpt.domain||config.domain)+apiOpt.url,me.CONSTS),
		method:apiOpt.method,
		//数据组装
		qs: method.toUpperCase()=="GET"?data:undefined,
		// form:apiOpt.method.toUpperCase()=="GET"?undefined:data//,
		body: method.toUpperCase()=="GET"?undefined:JSON.stringify(data),

		headers: apiOpt.headers||{
	       'Content-Type' : 'application/json'
	    }
    };
    if (req._yoheaders) { 
        options.headers= _.merge(options.headers, req._yoheaders);
    }
    console.log("*************************************");
    console.log("Http",options.url,data,options.headers);
	console.log("*************************************");

	Request(options,function(error, response, body){
		var _err_=new Error();
		if(error){
			console.info("Request 请求错误");
			console.error(error);
			return callback(error,null); 
		}
		try{
			if(response && response.statusCode === 200){
				var obj=JSON.parse(body)
				if(!(typeof obj=="object")){
					_err_.message="Error[json parse@"+apiOpt.title+"]:"+body;
					return callback(_err_,null);
	            }
			}else{
				_err_.message="Error[response@"+apiOpt.title+"]:"+response.statusCode;
				return callback(_err_,null);
			}
			
		}catch(err){
			console.info("Request 内容转化JSON错误@"+apiOpt.title+"");
			console.info(response);
			console.error(err);
			return callback(err,null);
		}
		return callback(null,JSON.parse(body)); 
	});
};
/*
* {mos} 接口key 数组 比如[key1,key2] 后面可能要兼容字符串 比如 传key1
*/
Interfacer.prototype.require=function(mos,req,res,cb){
	var me=this,funcs=[],names=[],errName=[];

	mos.forEach(function(name){

		if(me.apis.hasOwnProperty(name)){
			names.push(name);
			if(me.config.mock){
				funcs.push(me.apis[name].output);
			}else{
				funcs.push(function(callback){
					__requestApi.call(me,me.config,me.apis[name],req,callback);
				});
			}
		}else{
			errName.push(name);
		}
	});

    if (funcs.length != mos.length) {
        var err = new Error();
        err.message = "某个"+errName.join("->")+" 可能不存在!";
        cb(err, funcs, names);
		return;
	}
	if(me.config.mock){
		cb(null,funcs,names);
		return;
	}
	async.parallel(funcs, function(err, results){
		if(err){
			console.info("Async Error");
			console.error(err);
			console.error(results);
			return cb(err,results,names);
        }
        console.log(names);
        return cb(null, results, names);
	});
};


module.exports= Interfacer;