產品整理

gr-api系列產品整理

server api

  • yf-api-server
  • yf-fast-dbm
  • gr-api
  • biz-api ( java )

sdk

  • js angularjs
  • nodejs
  • java
  • .Net
  • php

task_trigger

scheduled task trigger for api

ci-web

http web console 4 execute shell command

總結一些自己完成的提高效率的工具

1. yfci.sh

用于在linux系統上快速安裝java和node環境的自動化腳本

  • 源碼地址: https://github.com/yfsoftcom/mytools
  • 基于centos 6.x的系統環境
  • 自動安裝如下軟件:git , lsof , node 4.5 , pm2 , cnpm , java1.8 , maven 3.2.x , tomcat 8.x
  • 自動集成ci-web , 通過瀏覽器訪問:http://[yourdomain]:3000 , 可執行系統shell命令,如:
$ free -m
$ yfci build

YF-CI-WEB

這是一個可以通過web界面來執行linux shell 的工具

0.Overview

自己平時喜歡搗騰玩意兒,弄了個centos主機,學習shell,做了一些腳本,但是執行都要xshell進,好麻煩!
于是就有了這個小工具,安裝在linux上,可以通過web來執行shell指令了。在家也可以編譯發布產品代碼,開森~
實際上就是一個nodejs的小應用,通過child_process來執行shell指令。
湊活著用唄,嘿嘿~
配合上自己寫的一些shell腳本蠻實用的

奉上源碼地址:https://github.com/yfsoftcom/yf-ci-web
歡迎拍磚

  • PC上界面如下:


    執行 free -m 命令
  • 兼容適配手機哦,不過手機上能顯示的空間小,費眼~


    iphone 6 打開 執行 free -m 命令

1. Install

$ git clone https://github.com/yfsoftcom/yf-ci-web.git

$ cd yf-ci-web

$ npm install

2. Run

$ npm start
//或者使用pm2來啟動
$ pm2 start index.js -i 1 --name yf-ci-web

3. Useage

打開 http://[yourdomain]:3000

4. Known Issues

  • windows 上無法執行cmd 的指令

2. task-trigger

可視化配置定時任務,在指定的時間執行任務請求,對已有系統無任何傾入,可快速集成使用。

任務列表
創建任務

3. yf-fast-dbm

快速極簡的orm框架

  • 源碼地址: https://github.com/yfsoftcom/yf-fast-dbm
  • 目前支持mysql,使用 jugglingdb
  • 通過delflag實現邏輯刪除
  • 默認帶有四個字段:id,createAt,updateAt,delflag
  • 支持批量插入
  • TODO:事務,存儲過程,mongodb語法

1.Installation

$ npm install yf-fast-dbm

2.API List

  • adapter

獲取原生的數據庫適配器,可執行自定義的sql來滿足一些復雜的業務操作

  • find

通過一組查詢、排序、分頁的條件篩選一組數據結果。

  • first

通過一組查詢、排序、分頁的條件篩選一行數據結果。

  • count

通過篩選條件進行統計計數

  • findAndCount

通過一組查詢、排序、分頁的條件篩選一組數據結果,并返回符合條件的所有數據行數

  • get

通過數據的ID獲取到唯一的數據

  • update

修改一些數據

  • remove

刪除一條已知的數據

  • clear

通過篩選條件刪除一組數據

  • create

添加一條或者多條數據

3.Configuration

模塊自帶的一些配置信息:

  • Code List 1:
{
    host:'localhost',           //mysql host
    port:3306,                  //mysql port
    database:'test',            //mysql dbname
    username:'root',            //mysql username
    password:'',                //mysql password
    debug:false,                //true:輸出jugglingdb生成的sql語句
    showSql:false,              //true:輸出本模塊生成的sql語句
    pool:{
        connectionLimit:10,     //鏈接池的配置
        queueLimit:0,
        waitForConnections:true
    }
}

在初始化的時候,可以通過傳入的參數覆蓋這些默認值

  • Code List 2:
var C = {
    host:'192.168.1.1',
    database:'test',
    username:'root',
    password:'root',
};
var M = require('yf-fast-dbm')(C);

4.Useage

find
  • Code List 3:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 condition: "delflag=0",
 fields: "id,article,ptags,product"
};
M.find(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});
first
  • Code List 4:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 condition: "delflag=0",
 fields: "id,article,ptags,product"
};
M.first(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});
count
  • Code List 5:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 condition: "delflag=0"
};
M.count(arg).then(function (c) {
 // do success here
}).catch(function (err) {
 // do error here
});
findAndCount
  • Code List 6:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 condition: "delflag=0",
 fields: "id,article,ptags,product"
};
M.first(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});
get
  • Code List 7:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 id: 1
};
M.get(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});
update
  • Code List 8:
    修改所有key為test的val為123
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 condition: "key = 'test'",
    row:{val:"123"}
};
M.update(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});
remove
  • Code List 9:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 id: 1
};
M.remove(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});
clear
  • Code List 10:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 condition: "delflag=0"
};
M.clear(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});
create
  • Code List 11:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 row: {key:"test",val:"mmm"}
};
M.create(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});

or batch insert

  • Code List 12:
// M 的初始化代碼請參看 Code List:2
var arg = {
 table: "test",
 row:[{key:"test",val:"mmm"},{key:"test2",val:"mmm2"}]
};
M.create(arg).then(function (data) {
 // do success here
}).catch(function (err) {
 // do error here
});

4. yf-api-server

0.OVERVIEW

一款靈活的api服務端,自動集成crud的數據操作,靈活擴展自定義業務邏輯

設計概要

背景

團隊的產品從單平臺,慢慢擴展到多個客戶端,且有多個異構系統的數據交互,所以需要一個統一的數據輸入輸出口。

  • 用node有個人私心,因為喜歡它,雖然編寫java已經有近7年的時間了,但我還是想跳出自己的舒適區。
  • 使用restify作為http框架,因為它夠輕,夠簡潔,幾乎沒有學習成本,而且體積小,自然坑也少 [偷笑]。
  • 沒有使用restful風格,因為業務需要對數據有權限限制,而且業務交集很多,對路由的管理成本就大。
  • 經過一小段時間的糾結,決定采用taobao和jd的開放平臺的設計方案,定義統一的入口,通過參數定位業務接口,實現靈活的業務開發。
定義

服務只有一個入口 /api ; 只接受post方式的請求,定義如下

  • 傳入參數結構
參數名 類型 是否必須 參數說明 默認值 示例
method String Y 需要調用的業務函數
appkey String Y 應用被分配的密鑰
timestamp Number Y 應用端的時間戳,用于驗證請求的時效性 13位時間戳
v String N 調用的服務端接口的版本號
param Object N 業務函數需要用到的參數,以JsonObject的形式傳入
sign String Y 將接口參數進行升序排列,如 appkey,method,param,timestamp添加一個masterKey=xxx[此處的key來自于注冊的key] 組合成appkey=123&masterKey=xxx&param=44444&tmiestamp=140932932932[所有的參數值使用urlencode] 過md5加密,生成一個32位的密鑰
  • 輸出參數結構
參數名 類型 是否必須 參數說明
errno Number Y 業務函數的錯誤代碼,通常為0,表示正常執行,<0 則表示執行錯誤,可通過應用說明獲取到具體的錯誤原因。
message String N 通常在執行出錯的情況下,會輸出錯誤的信息。
timestamp Number N 返回服務端處理完信息之后的時間戳。
data Object/Array Y 一般的查詢類的業務函數,會在該字段下攜帶查詢結果信息;具體是Object類型還是Array類型則根據不同的業務函數的說明而定。
error Object N 錯誤信息的詳細內容

這樣的設計不能滿足現在的restful范式,但是能滿足我們團隊現有的需求,提高了業務實現的開發效率;

  • 效果預覽
啟動服務
postman 測試

1.Install

  • 依賴不少,請耐心等待幾分鐘。
    $ npm install yf-api-server --save

  • 需要手動創建一下logs記錄日志文件的目錄
    $ mkdir logs

  • 創建一個數據庫和兩張表
    api_app:保存了appkey和secretkey的記錄


    api_app

    api_record:記錄每一次的接口請求


    api_record

SQL腳本

--
-- 表的結構 `api_app`
--

CREATE TABLE IF NOT EXISTS `api_app` (
  `id` int(12) NOT NULL AUTO_INCREMENT,
  `appid` int(12) NOT NULL,
  `appname` varchar(120) NOT NULL,
  `apptype` varchar(120) NOT NULL,
  `appkey` varchar(120) NOT NULL,
  `secretkey` varchar(120) NOT NULL,
  `appenvironment` varchar(120) NOT NULL,
  `approot` varchar(120) NOT NULL,
  `createAt` int(32) NOT NULL,
  `updateAt` int(32) NOT NULL,
  `delflag` int(12) NOT NULL,
  `status` int(12) NOT NULL DEFAULT '1',
  `about` varchar(250) NOT NULL,
  `appurl` varchar(500) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `appid` (`appid`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;

--
-- 表的結構 `api_record`
--

CREATE TABLE IF NOT EXISTS `api_record` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `appkey` varchar(100) NOT NULL,
  `createAt` bigint(20) NOT NULL,
  `timestamp` bigint(20) NOT NULL,
  `param` varchar(1000) NOT NULL,
  `sign` varchar(100) NOT NULL,
  `v` varchar(100) NOT NULL,
  `method` varchar(100) NOT NULL,
  `updateAt` bigint(20) NOT NULL,
  `delflag` tinyint(4) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=utf8 AUTO_INCREMENT=9 ;

INSERT INTO `api_app` (`id`, `appid`, `appname`, `apptype`, `appkey`, `secretkey`, `appenvironment`, `approot`, `createAt`, `updateAt`, `delflag`, `status`, `about`, `appurl`) VALUES
(1, 10001, 'YFDemoKey', 'PC', 'a81bc1bb1122323b', '3fc4h39d3ed9b33b67fcbc359131e7ee', 'DEV', '*', 1462610156, 1462773916, 0, 1, 'YF所有,抄襲必究', NULL)

-- 這里的appkey 和 secretkey會在接口調用的時候被使用到
-- appkey : 'a81bc1bb1122323b'

2.Config

$ touch config.js
$ vi config.js
var k = {
  db:{
      host: '192.168.1.1',
      port:3306,
      username:'root',
      password:'',
  },
  database:{'api':'api'},
  server:{port:8080},
  dev:'DEV'
};

var getDbConfig = function(option){
    var originConfig = {
        host: 'localhost',
        port:3306,
        username:'root',
        password:'',
        debug:false,
        pool:{
            connectionLimit:10,
            queueLimit:0,
            waitForConnections:true
        }
    };
    for(var key in k.db){
        originConfig[key] = k.db[key];
    }
    for(var key in option){
        originConfig[key] = option[key];
    }
    return originConfig;
};
module.exports = {
    db:(function(database){
        var _dbs = {};
        for(var d in database){
            _dbs[d] = getDbConfig({database:database[d]});
        }
        return _dbs;
    })(k.database),
    server: k.server||{
        port: k.dev == 'PRODUCT'?9001:8080
    },
    defaultVersion:'0.0.1',
    dev:k.dev,
    log4js: {
        appenders: [
            { type: 'console' },{
                type: 'file',
                filename: 'logs/access.log',
                maxLogSize: 1024 * 1024 * 100, //100Mb一個文件
                backups:10,
                category: 'normal'
            }
        ],
        replaceConsole: true,
        levels:{
            dateFileLog: 'debug',
            console: 'errno'
        }
    }
};

3.Code

編寫代碼,最終的目錄結構預覽如下

項目目錄
$ mkdir V0.0.2 && cd V0.0.2 && touch index.js && vi index.js
'use strict';
var _ = require('underscore');
var Q = require('q');
module.exports = function(C,M,H){
  var q = Q.defer();

  M.test = function(){
    var _q = Q.defer();
    _q.resolve({data:"中文和zimu from v0.0.2"})
    return _q.promise;
  }

  q.resolve({'foo':M});  //業務名稱: foo.test
  return q.promise;
};

$ touch app.js
$ vi app.js
var async = require('async');
var config = require('./config.js');
var M = {};
var v002 = require('./V0.0.2');
var yfserver = require('yf-api-server');
var app = yfserver(config);

async.parallel({
  '0.0.2':function(cb){
    v002(config,M,yfserver.hook).then(function(biz){
      cb(null,biz);
    });
  }
},function(err,results){
    if(err){
      console.log(err);
      return;
    }
    app.setBizModules(results);
    app.start();
  }
);

4.Run

$ node app.js

node app.js

postman測試


postman測試

5.Other

到此,一個能滿足基本業務的api服務端就搭建好了
目前我的項目在使用它做生產環境了

代碼結構

pm2 logs

pm2 logs

歡迎拍磚~~

測試的
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容