forked from Clouda-team/Cloudajs
-
Notifications
You must be signed in to change notification settings - Fork 0
step by step for sumeru.external
einsteinhx edited this page Oct 30, 2013
·
9 revisions
Sumeru提供了三方数据同步的方法,用来满足从三方网站/三方接口获取和同步数据的需求。 此文档通过一个例子来说明一次三方数据同步的过程。
在app/model
目录下定义model,三方model定义与普通model定义完全一致
Model.student = function(exports){
exports.config = {
fields : [
{ name : 'name', type : 'text'},
{ name : 'age', type : 'int', defaultValue : 0}
]
}
}
collection.extfind方法表示此collection为三方数据,处理数据方式不同。
//与普通的collection.find不同,三方数据的publish调用collection.extfind方法表示此collection为三方数据
fw.publish('student', 'pubext', function(/** arg1, arg2, arg3...*/ callback){
var collection = this;
collection.extfind('pubext', /** arg1, arg2, arg3...*/ callback);
});
在app/publish/
下新增externalConfig.js
文件(文件名任意,推荐使用externalConfig.js),用来指定三方数据来源与解析方法,需要注意必须为抓取回来的数据指定一个唯一标识uniqueColumn
:
/**
* 获取三方数据信息,由开发者自定义
*/
function runnable(){
//{Object} config是所有三方publish配置的容器
var config = {};
config['pubext'] = {
//{String} uniqueColumn为三方数据唯一标识
uniqueColumn : "name",
//{String} method为获取三方数据的请求方式,默认发get请求
//如需通过post请求获取数据,声明method为"post"
//method : 'post',
//{Function} fetchUrl的参数就是订阅时发起的参数,返回值为pubext所抓取的url地址
fetchUrl : function(/** arg1, arg2, arg3 */){
return 'http://some.host.com';
},
//{Function} resolve方法作用是将抓取回来的原始数据(originData)转化成为符合Model定义的数据(resolved)
resolve : function(originData){
var j = JSON.parse(originData);
var resolved = j;
return resolved;
},
//{Number} fetchInterval为可选参数,用来指定抓取时间间隔,单位为ms
fetchInterval : 60 * 1000,
//{Boolean} buffer为可选参数,值为true时表示获取原始Buffer,否则获取原始数据字符串
buffer : false
}
//最后需要声明此模块为归属为'external'
return {
type : 'external',
config : config
}
}
module.exports = runnable;
note:
如果想通过发送POST请求获取数据,需要在相应的config中声明method为"post",默认请求方式为GET请求。
并且fetchUrl
方法需要做相应调整:
fetchUrl : function(arg1){
return {
hostname : 'some.host.com', //指定host
path : '/fetch' //指定path
};
}
note:
POST请求的request body为subscribe的倒数第二个参数,如无参数,默认POST请求的request body为空字符串"";
添加request body时,同时需要为publish方法增加参数。
function getExt() {
var requestBody = {test : 1};
session.extStudent = env.subscribe('pubext', postData, function(collection, info){
session.bind('extBlock', {
data : collection.find().getData()
});
});
}
如想将本地数据修改同步到三方,并且三方提供相应的post接口,可以在app/publish/
下externalConfig.js
文件中,声明三方增/删/改接口以及数据:
声明中:
-
postUrl
方法用来指定三方post接口的地址信息, 参数type为增量类型,增量类型为'insert','update','delete'三者之一; -
prepare
方法用来将增量数据转化成为符合三方POST接口要求的post数据,参数type同为增量类型,参数data为增量的实际数据。
/**
* 三方数据POST请求信息,由开发者自定义
*/
function runnable(){
var config = {}
config['pubext'] = {
/**
* 声明三方POST接口地址
* {String} type为'delete', 'insert', 'update'其中之一
* 如果subscribe时带参数,参数会按照subscribe顺序接在postUrl的参数中
*/
postUrl : function(type /** arg1, arg2, arg3... */){
var options = {
host : 'some.host.com',
path : '/' + type
}
return options;
},
/**
* prepare方法将增量数据转化为符合三方要求的post数据。
* {String} type为增量操作,值为'delete', 'insert', 'update'其一;
* {Object} data为增量数据,如:{ name : 'user1', age : 26 }。
*/
prepare : function(type, data){
var prepareData = {}; //prepareData为三方post所需的data
if(type === "delete"){
prepareData.name = data.name;
}else if(type === "insert"){
prepareData.name = data.name;
prepareData.age = data.age;
}else{
prepareData.name = data.name;
prepareData.age = data.age;
}
return prepareData;
}
}
return {
type : 'external',
config : config
}
}
module.exports = runnable;
较为工整的声明方式根据type将不同操作区分开来。
声明中:
-
deleteUrl
,insertUrl
,updateUrl
三个方法作用等同于postUrl
,返回不同操作下三方接口url信息。 -
onDelete
,onInsert
,onUpdate
三个方法作用等同于prepare
方法, 返回经过处理,传给三方接口的post数据。
function runnable(){
var config = {};
config['pubext'] = {
//arg1, arg2, arg3是subscribe时输入的参数
deleteUrl : function(/** arg1, arg2, arg3... */){
return {
host : 'some.host.com',
path : '/delete'
}
},
insertUrl : function(/** arg1, arg2, arg3... */){
return {
host : 'some.host.com',
path : '/insert'
}
},
updateUrl : function(/** arg1, arg2, arg3... */){
return {
host : 'some.host.com',
path : '/update'
}
},
onInsert : function(data){
var prepareData = {};
prepareData.name = data.name;
prepareData.age = data.age;
return prepareData;
},
onUpdate : function(data){
var prepareData = {};
prepareData.name = data.name;
prepareData.age = data.age;
return prepareData;
},
onDelete : function(data){
var prepareData = {}
prepareData.name = data.name;
return prepareData;
}
}
return {
type : 'external',
config : config
}
}
module.exports = runnable;
subscribe方法与普通subscribe无差别,开发者只用关心所订阅的pubName,而不用区分数据来源。
function getExt() {
session.extStudent = env.subscribe('pubext', function(collection, info){
session.bind('extBlock', {
data : collection.find().getData()
});
});
}
sumeru同样提供更底层,更灵活的post和get接口:
- 向三方发送get请求
var url = "http://some.host.com";
var getCallback = function(data){
console.log(data);
}
sumeru.external.get(url, getCallback);
- 向三方发送post请求
var options = {
host : "some.host.com",
path : "/insert"
}
var postData = {
name : sumeru.utils.randomStr(8),
age : parseInt( 100 * Math.random())
}
var postCallback = function(data){
console.log(data);
}
sumeru.external.post(options, postData, postCallback);