Online Demo | Document | 中文 | Update log | Feedback | Gitee | Message Board
- Simple and efficient architecture, full TS writing, highly friendly TS declaration support
- Support highly customized middleware system
- Built-in router middleware
- JSON middleware: Support JSON files for data storage
- CORS middleware: supports cross-origin requests
- Static Middleware: Support static file directories
- Form middleware: Support formdata parsing and file upload
- Config middleware: supports highly flexible parameter configuration and dynamic change and monitoring 9.log Middleware: Support flexible logging system and log level control
- MySQL Middleware: Supports MySQL connections
- Mongo middleware: Support for Mongo connections
- RPC middleware: remote call support, support client and server use, support injection request X-trace-id
npm i sener
Simple demo:
import {Sener} from 'sener';
new Sener();
options:
new Sener({
port: 9000, // port: default value is 9000
middlewares: [], // Sener middlewares
});
- Use ebuild-cli
npm i ebuild-cli -g
ebuild init <Project name>
In the subsequent mode selection, select sener
- Copy from github address
git clone https://github.com/theajack/sener-best-practice.git
Router middleware
import {Sener, Router} from 'sener';
const router = new Router({
'/demo': ({ query }) => {
query.message = 'from get';
return { data: query };
},
'post:/demo': async ({ body }) => {
body.message = 'from post'
return { data: body };
},
});
new Sener({
middlewares: [router],
});
Use a JSON file as a database
npm i sener sener-json
import {Sener, Router} from 'sener';
import {Json} from 'sener-json';
const router = new Router({
'/data': ({ query, read }) => {
// 'data' is json file name
return { data: read('data') };
},
'post:/data': async ({ body, write }) => {
const { data, save, id } = write('aa');
body.message = 'from post'
data.push({...body, id: id()}); // Add increment id
save(); // save it, THIS Method must be called
return { data };
},
});
new Sener({
middlewares: [router, new Json()],
});
options
new Json({
dir: '', // directory for save json files. default value is ''
format: false, // Whether to format the JSON file. Default value: The development environment is false and the production environment is true
})
Middleware that handles cross-origin requests
npm i sener sener-cors
import {Sener, Cors} from 'sener';
new Sener({
middlewares: [new Cors()],
// new Cors(header); Or Set your custom headers
});
options
new Cors({
// headers: Set your custom headers
})
Middleware that handles static resources
npm i sener sener-static
import {Sener} from 'sener';
import {Static} from 'sener-static';
new Sener({
middlewares: [new Static()],
// new Static({dir}); dir default value is ./public
});
options
new Static({
dir: './public', // Static directory, default value is ./public
})
Middleware that handles formdata and file uploads
npm i sener sener-form
import {Sener, Router} from 'sener';
import {Form} from 'sener-form';
const router = new Router({
'post:/upload': ({ formData, files }) => {
return { formData, files }
},
});
new Sener({
middlewares: [new Form(), router],
// new Form({dir}); dir default value is ./public
});
options
new Form({
dir: './public/upload', // File upload directory, default value is ./public/upload
})
npm i sener sener-log
Middleware that supports logging systems
import {Sener, Router} from 'sener';
import {Log} from 'sener-log';
const router = new Router({
'get:/test': ({ query, logger }) => {
logger.log('msg', 'payload')
return { data: query }
},
});
new Sener({
middlewares: [new Log(), router],
});
typings
class Logger {
log(msg: string | IMessageData, payload?: any, type?: TLogType): void;
get traceid (): string;
refreshDurationStart(): void;
refreshTraceId(): void;
}
interface IMessageData {
msg?: string;
payload?: any;
type?: 'error' | 'log' | 'warn' | 'info';
level?: number;
extend?: object;
}
options
new Log({
dir: '', // The directory where the log file is stored. default value is '', use root directory
useConsole: false, // Whether to enable console.log Print logs when the service is running. It is not recommended to turn on the production environment. default value is false
maxRecords: 10000, // The maximum number of stored records for a single log file , default value is 10000
level: -1, // The level of log printing, logs with a level less than this number will not be printed
// level?: (()=>number) Level can also be a method for dynamically obtaining level values, typically used in conjunction with config middleware
})
Middleware that supports flexible use of JSON configuration files
npm i sener sener-config
import {Sener, Router} from 'sener';
import {Config} from 'sener-config';
const router = new Router({
'get:/test': ({ query, config, writeConfig, onConfigChange }) => {
const level = config.level;
level(); // read config
level(5); // write config
writeConfig('level', 5) // write config with writeConfig
onConfigChange(({key, value, prev}) => { // on config change
console.log(key, value, prev);
})
return { data: query }
},
});
const config = new Config();
// Use config instance
config.onConfigChange(({key, value, prev}) => { // on config change
console.log(key, value, prev);
});
config.data.level(); // read config
config.data.level(5); // write config
config.writeConfig('level', 2); // write config with writeConfig
new Sener({
middlewares: [config, router],
});
options
new Config({
dir: '', // directory for save config files. default value is ''
file: 'default', // file name of your config file. default value is 'default'
// file: ['c1', 'c2'], // Passing in an array indicates that multiple profiles are used
format: false, // Whether to format the JSON file. Default value: The development environment is false and the production environment is true
})
Middleware that supports mysql
npm i sener sener-mysql
import {Sener, Router} from 'sener';
import {Mysql} from 'sener-mysql';
const router = new Router({
'get:/test': async ({ query, querySql, mysqlConn }) => {
const { results, fields } = await querySql('select * from user');
// Or use mysqlConn
return { data: query }
},
});
const mysql = new Mysql({
// Please refer to (https://www.npmjs.com/package/mysql) for details
})
mysql.connection;
new Sener({
middlewares: [mysql, router],
});
Please refer to mysql for details
Middleware that supports mongodb
npm i sener sener-mongodb
import {Sener, Router} from 'sener';
import {Mongo} from 'sener-mongodb';
const router = new Router({
'get:/test': async ({ query, queryMongoDB, mongoClient }) => {
const {db, close} = await queryMongoDB('user');
// do something
// Or use mongoClient
return { data: query }
},
});
const mongodb = new Mongo({
// Please refer to (https://www.npmjs.com/package/mongodb) for details
});
mongodb.client;
new Sener({
middlewares: [mongodb, router],
});
Please refer to mongodb for details
RPC middleware is used to make remote calls to services deployed on different servers or on different ports of the same server, allowing developers to initiate requests like remote services like function calls
It can also be used in scenarios where web clients initiate requests like the server
The middle will also inject an x-trace-id header into the request to ensure that the interface of the same access call has the same tracid, which can be used effectively with log middleware to locate the problem
npm i sener sener-rpc
- Use configuration
import {Sener, Router} from 'sener';
import {RPC} from 'sener-rpc';
const router = new Router({
'get:/test': async ({ query, rpc }) => {
const list = rpc.comment.get('/message', {page: 1}); // url and query
// use rpc.comment.request for more details
return { data: {query, list} }
},
});
new Sener({
middlewares: [new RPC({
user: 'https://localhost:3000', // The access base address of the user service
comment: 'https://localhost:3001', // The access base address of the comment service
}), router],
});
- Use the createServices function
import {Sener, Router} from 'sener';
import {RPC, Request} from 'sener-rpc';
class CommentRequest extends Request {
getList ({ app = 'common', index = 1 }: {
app?: string
index?: number
} = {}) {
return this.get('/message', {
app,
index,
size: 10,
});
}
}
function createServices(traceid = '') {
const base = (port: number) => `https://localhost:${port}`;
return {
comment: new CommentRequest({ base: base(3001), traceid }),
};
}
const router = new Router({
'get:/test': async ({ query, rpc }) => {
const list = rpc.comment.getList();
return { data: {query, list} }
},
});
new Sener({
middlewares: [new RPC(createServices), router],
});
- npm use
npm i sener-rpc
import {WebRPC} from 'sener-rpc/dist/web.umd';
// 1. A single service can pass in the base address
const comment = new WebRPC('https://localhost:3001');
await comment.get('/message', {page: 1});
// 2. Multiple services pass into the map
const rpc = new WebRPC({
user: 'https://localhost:3000', // The access base address of the user service
comment: 'https://localhost:3001', // The access base address of the comment service
});
await rpc.comment.get('/message', {page: 1});
// 3. Use inheritance
class Comment extends WebRPC {
getList ({ app = 'common', index = 1 }: {
app?: string
index?: number
} = {}) {
return this.get('/message', {
app,
index,
size: 10,
});
}
}
await (new Comment()).getList();
- cdn use
<script src='https://cdn.jsdelivr.net/npm/sener-rpc'></script>
<script>
SenerRpc.WebRPC
</script>
- Dir
Sener stores all data files in ~/sener-data folder by default
let BASE_SENER_DIR = path.resolve(homedir(), './sener-data')
If you want to modify,Please use the static property Dir
Sener.Dir = 'xxxxx'
- Version
Get version
Sener.Version
Documentation will continue to be improved
For now please refer to middleware packages