gels
gels copied to clipboard
A framework, which use koa2, mysql, graphql & typescript , to build micro service rapidly, safely & efficiently.
项ç®ä»ç»
åºäºkoa2ãå ³ç³»æ°æ®åºï¼ææ¶åªæ¯æmysqlï¼å»ºç«çæºè½å¾®æå¡å¿«éå¼åæ¡æ¶ï¼åæ¶æ¯ægraphqlä¸restæ åï¼ä½¿ç¨typescriptè¯è¨ç¼åï¼åæ±å®å ¨ã髿ã
A framework, which use koa2, mysql, graphql & typescript , to build micro service rapidly, safely & efficiently.
gels -- åè¶ï¼å¸å该项ç®è½æä¸ºèç»è®¾è®¡ãå¼åï¼å端ãå端çâ强åè¶æ°´âï¼æä¸ºå¾®æå¡å¿«éå¼åçæåæ¡æ¶ã
设计æè·¯
ä¸å°åä¼ä¸ï¼æ´å¤çæ¯æ³¨éå¿«éå¼åãåè½è¿ä»£ãå
³ç³»æ°æ®åºä¸ºæä»¬æä¾äºå¾å¤æç¨çæ¯æï¼æè¯å¾ææ°æ®åºè®¾è®¡ä¸ç¨åºå¼åææºçç»åèµ·æ¥ï¼è®©å端éå°å端çjson对象èªå¨æ å°æä¸ºæ åçSQLæ¥è¯¢è¯å¥ãæçè¿ç§ORMæ¹å¼ï¼æå¡ç«¯ä¸éè¦åä¸è¡ä»£ç ï¼åªé宿å
³ç³»æ°æ®åºç设计ï¼å°±è½ä¸ºå端æä¾æ åæå¡æ¥å£ã
æè®¾è®¡äºä¸å¥æ°æ®åºè®¿é®æ 忥å£ï¼å¨å®è·µä¸å·²ç»å¾å°å¾å¥½çè¿ç¨ãæå·²ç»å¨es6, typescript, java, python & goä¸å®ç°ï¼ä¸ä¸æ¥æ¯å¯¹æ°æ®åºæ¯æçæ©å±ï¼å夿¯ææµè¡çå
³ç³»æ°æ®åºï¼Mssql, sqlite3, prostgresçï¼ï¼æéæ©æ¯æä¸äºnosqlï¼æ¯å¦ï¼mongoã
æ´æ°ç¶æ
æ´æ°ææä¾èµåºï¼apollo-server-koa å级å°çæ¬3ï¼å¹¶éé 宿ã
å 容ç®å½
- 项ç®ä»ç»
- 设计æè·¯
- æ´æ°ç¶æ
- å 容ç®å½
- å®è£ è¿è¡
- 项ç®ç»æ
- æ°æ®åºæ¥å£è®¾è®¡
- é»è®¤è·¯ç±
- ä¸é´ä»¶
- restful_api
- graphql
- æºè½æ¥è¯¢
- é«çº§æä½
- ç¸å ³è§é¢è¯¾ç¨
å®è£ è¿è¡
- è¿è¡æ°æ®èæ¬
SET NAMES utf8; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- Table structure for `users` -- ---------------------------- DROP TABLE IF EXISTS `users`; CREATE TABLE `users` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(255) DEFAULT NULL, `password` varchar(255) DEFAULT NULL, `age` int(11) DEFAULT NULL, `power` json DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4; -- ---------------------------- -- Records of `users` -- ---------------------------- BEGIN; INSERT INTO `users` VALUES ('1', 'white', '123', '22', null), ('2', 'john', '456i', '25', null), ('3', 'marry', null, '22', null), ('4', 'bill', '123', '11', null), ('5', 'alice', '122', '16', null), ('6', 'zhoutk', '123456', '26', null); COMMIT; SET FOREIGN_KEY_CHECKS = 1; - é
ç½®æä»¶ç¤ºä¾ï¼./src/config/configs.ts
export default { inits: { directory: { run: false, dirs: ['public/upload', 'public/temp'] }, socket: { run: false } }, port: 5000, StandSocketPort: 1202, db_dialect: 'mysql', DbLogClose: false, dbconfig: { db_host: '192.168.0.6', db_port: 3306, db_name: 'dbname', db_user: 'root', db_pass: '123456', db_char: 'utf8mb4', db_conn: 5, }, jwt: { secret: 'zh-123456SFU>a4bh_$3#46d0e85W10aGMkE5xKQ', expires_max: 36000 //10å°æ¶ï¼åä½ï¼ç§ }, } - å¨ç»ç«¯ï¼Terminalï¼ä¸ä¾æ¬¡è¿è¡å¦ä¸å½ä»¤
git clone https://github.com/zhoutk/gels cd gels npm i -g yarn yarn global add typescript tslint nodemon yarn add tsc -w //æ command + shift + Bï¼é tsc:çè§ yarn start //æ node ./dist/index.js
项ç®ç»æ
âââ package.json
âââ src //æºä»£ç ç®å½
â âââ app.ts //koaé
ç½®åå¯å¨
â âââ common //éç¨å½æ°æå
ç´ ç®å½
â â âââ globUtils.ts
â âââ config //é
ç½®æä»¶ç®å½
â â âââ configs.ts
â âââ db //æ°æ®å°è£
ç®å½
â â âââ baseDao.ts
â âââ globals.d.ts //å
¨å±å£°æå®ä¹æä»¶
â âââ index.ts //è¿è¡å
¥å£
â âââ inits //å¯å¨åå§åé
ç½®ç®å½
â â âââ global.ts
â â âââ index.ts
â â âââ initDirectory.ts
â âââ middlewares //ä¸é´ä»¶ç®å½
â â âââ globalError.ts
â â âââ logger.ts
â â âââ router
â â âââ session.ts
â âââ routers //è·¯ç±é
ç½®ç®å½
â âââ index.ts
â âââ router_rs.ts
âââ tsconfig.json
âââ tslint.json
æ°æ®åºæ¥å£è®¾è®¡
- äºå¡å
ç´ æ¥å£ï¼sqlåæ°ç¨äºæå¨ä¹¦åsqlè¯å¥ï¼idä¼ä½ä¸ºæåä¸ä¸ªåæ°è¢«éå
¥åæ°æ°ç»ã
export default interface TransElement { table: string; method: string; params: object | Array<any>; sql?: string; id?: string | number; } - æ°æ®åºæä½æ¥å£ï¼å
æ¬åºæ¬CURDï¼ä¸¤ä¸ªæ§è¡æåsqlæ¥å£ï¼ä¸ä¸ªæ¹éæå
¥ä¸æ´æ°äºå䏿¥å£ï¼ä¸ä¸ªäºå¡æä½æ¥å£ãå®è·µè¯æï¼ä¸é¢å
«ä¸ªæ¥å£ï¼å¨ç»å¤§é¨åæ
åµä¸å·²ç»è¶³å¤ã
export default interface IDao { select(tablename: string, params: object, fields?: Array<string>): Promise<any>; insert(tablename: string, params: object): Promise<any>; update(tablename: string, params: object, id: string|number): Promise<any>; delete(tablename: string, id: string|number): Promise<any>; querySql(sql: string, values: Array<any>, params: object, fields?: Array<string>): Promise<any>; execSql(sql: string, values: Array<any>): Promise<any>; insertBatch(tablename: string, elements: Array<any>): Promise<any>; transGo(elements: Array<TransElement>, isAsync?: boolean): Promise<any>; }
é»è®¤è·¯ç±
- /op/:commandï¼åªæ¯æPOST请æ±ï¼ä¸é´æï¼æä¾ç»å½çç¹å®æå¡æ¯æ
- loginï¼ç»å½æ¥å£ï¼è¾å ¥åæ°{username, password}ï¼ç»å½æåè¿ååæ°ï¼{status:200, token}
- /rs/:table[/:id]ï¼æ¯æåç§restful请æ±ï¼GET, POST, PUT, DELELTEï¼é¤GETå¤ï¼å ¶å®è¯·æ±æ£æµæ¯å¦ææ
- /graphql ,以apollo-serveråºå®ç°graphql
- /gql ,以koa-graphqlåºå®ç°graphql
ä¸é´ä»¶
- globalErrorï¼å ¨å±é误å¤çä¸é´ä»¶
- loggerï¼æ¥å¿ï¼éælog4jsï¼è¾åºç³»ç»æ¥å¿
- sessionï¼ä½¿ç¨jsonwebtokenï¼å®ç°é´æï¼åæ¶ï¼ä¸ºéè¿çé´æçç¨æ·çæå¯¹åºçsession
- ç¨æ·ç»å½æååå¾å°çtokenï¼å¨ä»¥åçajaxè°ç¨æ¶ï¼éè¦å¨header头ä¸å å ¥token key
restful_api
- [GET] /rs/users[?key=value&...], å表æ¥è¯¢ï¼æ¯æåç§æºè½æ¥è¯¢
- [GET] /rs/users/{id}, åæ¡æ¥è¯¢
- [POST] /rs/users, æ°å¢è®°å½
- [PUT] /rs/users/{id}, ä¿®æ¹è®°å½
- [DELETE] /rs/users/{id}, å é¤è®°å½
graphql
æ¡æ¶ä¼æ ¹æ®æ°æ®è¡¨åç¹æ®ä¸å¡æä»¶èªå¨çæschemaã
ä¸äºæ°æ®åºè®¾è®¡åå约å®
- æ¯ä¸ªè¡¨å¿ é¡»æå段idï¼ç±»åä¸ºæ´æ°(èªå¢)æ8ä½å符串(uuid)ï¼ä½ä¸ºä¸»é®æå»ºç«uniqueç´¢å¼
- 表å为å°å忝ï¼ä½¿ç¨åè¯åæ°ï¼ä»¥ä¸åä½ä¸ºåè¯åé
- è¡¨å ³è约å®ï¼bookå ³èå°authorï¼è¡¨bookä¸å ³èåæ®µè®¾ä¸ºauthor_idï¼å ³èå°author.id
- è¡¨å ³èèªå¨å¨ç¸å ³ä¸åµå ¥ç¸å ³å¯¹è±¡ï¼Book对象å¢å Author对象ï¼Author对象å¢å bookså表
- æ¯ä¸ªè¡¨ä¼é»è®¤çæä¸¤ä¸ªqueryï¼ä¸ä¸ªæ¯ä»¥idä¸ºåæ°è¿è¡åæ¡æ¥è¯¢ï¼å¦ä¸ä¸ªæ¯å表æ¥è¯¢ï¼å½åè§åï¼åæ¡æ¥è¯¢ä¸è¡¨åç¸åï¼å表æ¥è¯¢ä¸ºè¡¨å+sï¼è¥è¡¨åæ¬èº«ä»¥sç»å°¾ï¼åås为zã
- ç¹æ®ä¸å¡å¤ç请æç §/src/graphqlç®å½ä¸ç模å¼è¿è¡ç¼åï¼æ¡æ¶ä¼èªå¨åå¹¶ä¸å¡
æµè¯ç¨æ°æ®åºèæ¬
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for author
-- ----------------------------
DROP TABLE IF EXISTS `author`;
CREATE TABLE `author` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of author
-- ----------------------------
BEGIN;
INSERT INTO `author` VALUES (1, 'john');
INSERT INTO `author` VALUES (2, 'white');
COMMIT;
-- ----------------------------
-- Table structure for book
-- ----------------------------
DROP TABLE IF EXISTS `book`;
CREATE TABLE `book` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主é®ï¼èªå¢',
`title` varchar(255) NOT NULL COMMENT '书å',
`author_id` int(11) DEFAULT NULL COMMENT 'ä½è
ID',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of book
-- ----------------------------
BEGIN;
INSERT INTO `book` VALUES (1, 'learn mysql', 1);
INSERT INTO `book` VALUES (2, 'learn graphql', 1);
INSERT INTO `book` VALUES (3, 'javascript practice', 2);
COMMIT;
SET FOREIGN_KEY_CHECKS = 1;
æºè½æ¥è¯¢
æ¥è¯¢ä¿çåï¼fields, page, size, sort, search, lks, ins, ors, count, sum, group
- fields, å®ä¹æ¥è¯¢ç»æåæ®µï¼æ¯ææ°ç»åéå·åéå符串两ç§å½¢å¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?username=white&age=22&fields=["username","age"] çæsqlï¼ SELECT username,age FROM users WHERE username = ? and age = ? - page, å页忰ï¼ç¬¬å 页
- size, åé¡µåæ°ï¼æ¯é¡µè¡æ°
- sort, æ¥è¯¢ç»ææåºåæ°
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?page=1&size=10&sort=age desc çæsqlï¼ SELECT * FROM users ORDER BY age desc LIMIT 0,10 - search, æ¨¡ç³æ¥è¯¢åæ¢åæ°ï¼ä¸æä¾æ¶ä¸ºç²¾ç¡®å¹é
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?username=i&password=1&search çæsqlï¼ SELECT * FROM users WHERE username like ? and password like ? - ins, æ°æ®åºè¡¨ååæ®µinæ¥è¯¢ï¼ä¸å段对å¤ä¸ªå¼ï¼ä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?ins=["age",11,22,26] çæsqlï¼ SELECT * FROM users WHERE age in ( ? ) - ors, æ°æ®åºè¡¨å¤å段精确æ¥è¯¢ï¼orè¿æ¥ï¼å¤ä¸ªå段对å¤ä¸ªå¼ï¼æ¯ænull弿¥è¯¢ï¼ä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?ors=["age",1,"age",22,"password",null] çæsqlï¼ SELECT * FROM users WHERE ( age = ? or age = ? or password is null ) - lks, æ°æ®åºè¡¨å¤åæ®µæ¨¡ç³æ¥è¯¢ï¼orè¿æ¥ï¼å¤ä¸ªå段对å¤ä¸ªå¼ï¼æ¯ænull弿¥è¯¢ï¼ä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?lks=["username","i","password",null] çæsqlï¼ SELECT * FROM users WHERE ( username like ? or password is null ) - count, æ°æ®åºæ¥è¯¢å½æ°countï¼è¡ç»è®¡ï¼ä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?count=["1","total"]&fields=["username"] çæsqlï¼ SELECT username,count(1) as total FROM users - sum, æ°æ®åºæ¥è¯¢å½æ°sumï¼å段æ±åï¼ä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?sum=["age","ageSum"]&fields=["username"] çæsqlï¼ SELECT username,sum(age) as ageSum FROM users - group, æ°æ®åºåç»å½æ°groupï¼ä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?group=age&count=["*","total"]&fields=["age"] çæsqlï¼ SELECT age,count(*) as total FROM users GROUP BY age
ä¸çæä½ç¬¦æ¥è¯¢æ¯æ
æ¯æçä¸çæä½ç¬¦æï¼>, >=, <, <=, <>, =ï¼éå·ç¬¦ä¸ºåé符ï¼ä¸ä¸ªåæ®µæ¯æä¸æäºä¸ªæä½ã
ç¹æ®å¤ï¼ä½¿ç¨"="å¯ä»¥ä½¿æä¸ªå段跳è¿searchå½±åï¼è®©æ¨¡ç³å¹é
ä¸ç²¾ç¡®å¹é
åæ¶åºç°å¨ä¸ä¸ªæ¥è¯¢è¯å¥ä¸
- ä¸ä¸ªå段ä¸ä¸ªæä½ï¼ç¤ºä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?age=>,10 çæsqlï¼ SELECT * FROM users WHERE age> ? - ä¸ä¸ªå段äºä¸ªæä½ï¼ç¤ºä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?age=>,10,<=,35 çæsqlï¼ SELECT * FROM users WHERE age> ? and age<= ? - 使ç¨"="å»é¤å段çsearchå½±åï¼ç¤ºä¾ï¼
æ¥è¯¢ç¤ºä¾ï¼ /rs/users?age==,22&username=i&search çæsqlï¼ SELECT * FROM users WHERE age= ? and username like ?
é«çº§æä½
- æ°å¢ä¸æ¡è®°å½
- url
[POST]/rs/users- header
Content-Type: application/json token: eyJhbGciOiJIUzI1NiIsInR...- è¾å ¥åæ°
{ "username":"bill", "password":"abcd", "age":46, "power": "[\"admin\",\"data\"]" }- è¿ååæ°
{ "affectedRows": 1, "id": 7, "status": 200, "message": "data insert success." } - execSqlæ§è¡æåsqlè¯å¥ï¼ä¾å端å
é¨è°ç¨
- 使ç¨ç¤ºä¾
await new BaseDao().execSql("update users set username = ?, age = ? where id = ? ", ["gels","99","6"])- è¿ååæ°
{ "affectedRows": 1, "status": 200, "message": "data execSql success." } - insertBatchæ¹éæå
¥ä¸æ´æ°äºå䏿¥å£ï¼ä¾å端å
é¨è°ç¨
- 使ç¨ç¤ºä¾
let params = [ { "username":"bill2", "password":"523", "age":4 }, { "username":"bill3", "password":"4", "age":44 }, { "username":"bill6", "password":"46", "age":46 } ] await new BaseDao().insertBatch('users', params)- è¿ååæ°
{ "affectedRows": 3, "status": 200, "message": "data batch success." } - tranGoäºå¡å¤çæ¥å£ï¼ä¾å端å
é¨è°ç¨
- 使ç¨ç¤ºä¾
let trs = [ { table: 'users', method: 'Insert', params: { username: 'zhou1', password: '1', age: 1 } }, { table: 'users', method: 'Insert', params: { username: 'zhou2', password: '2', age: 2 } }, { table: 'users', method: 'Insert', params: { username: 'zhou3', password: '3', age: 3 } } ] await new BaseDao().transGo(trs, true) //trueï¼å¼æ¥æ§è¡ï¼false,忥æ§è¡- è¿ååæ°
{ "affectedRows": 3, "status": 200, "message": "data trans success." }
ç¸å ³è§é¢è¯¾ç¨
è¿ç¨typescriptè¿è¡node.jså端å¼åç²¾è¦
nodejs宿乿ºè½å¾®æå¡å¿«éå¼åæ¡æ¶
JSON-ORMï¼å¯¹è±¡å
³ç³»æ å°ï¼è®¾è®¡ä¸å®ç°
Koa2å°è£
æ°æ®åºé«çº§æä½
èè宿¶ç¬åæ°æ®æä¾å¾ä¹¦ä¿¡æ¯å¾®æå¡