Package Exports
- koa-decorator-resolver
- koa-decorator-resolver/index.js
This package does not declare an exports field, so the exports above have been automatically detected and optimized by JSPM instead. If any package subpath is missing, it is recommended to post an issue to the original package (koa-decorator-resolver) to support the "exports" field. If that is not possible, create a JSPM override to customize the exports field for this package.
Readme
koa-decorator-resolver ⚡
This is a solution with using decorator in Koa
Depends on the supported version
Directory
- Install
- Default Restful
- Use Database
- Common Restful
Install
# install package
npm install koa-decorator-resolve
# if you need sqlite database, you will need to install the sqlite driver, such as
npm install sqlite@4.x.x sqlite3@5.x.x
# if you need mysql database, you will need to install the mysql driver, such as
npm install mysql2@2.x.xDefault-Restful
You don't need to declare restful urls, the names of classes and functions are automatically resolved to urls, and the url format is ":hostname/:className/:functionName", but the default restful method is "post", if you want to send a get request, you can add a custom decorators to resolve it.
how-to-use-it
- file: index.ts
// the entry of project
import * as Koa from 'koa';
import * as Router from 'koa-router';
import { routeBinder } from 'koa-decorator-resolve';
import * as serviceModules from './serviceModules';
const router = new Router();
routeBinder(router,serviceModules);
app.use(router.routes());
app.listen(8080, () => {
console.log('server start on 8080');
});- file: serviceModules.ts
// the restful modules
export class serviceModule1 {
func1(data){
return {name:data.name + ' func1',msg:'success'}
}
func2(data){
return {name:data.name + ' func2',msg:'success'}
}
}
export class serviceModule2 {
func3(data){
return {name:data.name + ' func3',msg:'success'}
}
}- send request in frontend
axios.post('/serviceModule1/func1',{name:'m1f1'}).then(res=>{
console.log(res); // the result is : {name:'m1f1 func1',msg'success'}
})
axios.post('/serviceModule2/func3',{name:'m2f3'}).then(res=>{
console.log(res); // the result is : {name:'m2f3 func3',msg'success'}
})plugins-define
you can define some decorator, and to extend extra function
1. define plugins and decorator
- file: plugins.ts
import {injectorBuilder,Injector} from 'koa-decorator-resolve';
// declare decorator
type Option = {value:string}
export const Transfer: Injector<Option> = injectorBuilder('Transfer');
// config interceptor
export const config = {
Transfer: {
method: 'get', // default is post
before: {
plugin: (ctx: any, option?: Option) => {
return {'transfer-before':option.value};
},
replaceProps: true, // replace service function input parameter
},
after: {
plugin: (res: any, ctx: any, option?: Option) => {
return {'transfer-after':res}
},
replaceProps: true, // replace service function output return data
}
}
}2. add plugins
- file: index.ts
// the entry of project
import * as Koa from 'koa';
import * as Router from 'koa-router';
import {routeBinder,PluginConfig} from 'koa-decorator-resolve';
import * as serviceModules from './serviceModules';
import {config} from './plugins';
const router = new Router();
routeBinder(router,serviceModules,config as PluginConfig);
app.use(router.routes());
app.listen(8080, () => {
console.log('server start on 8080');
});3. use decorator
- file: serviceModules.ts
// the restful modules
import {Transfer} from './plugins';
export class serviceModule {
@Transfer({value:123})
func(data){
// value of data : {'transfer-before':123}
return 456
}
// the result of request : {'transfer-after':456}
}Use-Database
Invoke the database through the decorator
config-database
Create a instance of database with tables
- create-connection-instance
the first is create a database connection.
- file: initTables.ts
import {defineTables} from 'koa-decorator-resolve';
import {TablesType,tablesStructure,relationCallback} from './declareTables';
export const tablesInstance = new defineTables<TablesType>(tablesStructure, relationCallback, {
connConf: {
driver: 'sqlite',
path: require('path').resolve('db/database_file.db')
}
});// The connConf of mysql and postgres contains the following contents
{
connConf : {
database: 'test_db',
username: 'test_user',
password: 'test_pw',
host: 'localhost',
port: 2001
}
}- declare-tables
Used to generate models of "sequelize", it is base in sequelize.
- file: declareTables.ts
// it used sequelize' type
import { STRING, INTEGER, BIGINT, DATE, TIME, DATEONLY, BOOLEAN, FLOAT, DOUBLE } from 'sequelize';
// this is tables' structure
export const tablesStructure = {
ACCESS: ({sequelize,tableName,option}) => sequelize.define(tableName, {
id: {
type: BIGINT,
primaryKey: true,
},
user_name: STRING(20),
role: STRING(4),
access: INTEGER,
begin_date: DATE,
end_date: DATE,
}, option)
}
export const TablesType = Record<keyof typeof tablesStructure, any>;
// Relationships between tables can be defined here
export const relationCallback = (tableModels) => {
const accessModel = tableModels['ACCESS'];
// ...
}- declare-decorator
- file: declareDecorator.ts
import {tablesInstance} from './initTables';
export const Sqlite = tablesInstance.Database.bind(tablesInstance) as typeof tablesInstance.Database;- use-sequelize
You can use decorators in service modules
// the restful modules
import {OrmConnectionType} from 'koa-decorator-resolve';
import {Sqlite} from './declareDecorator';
export class serviceModule {
private db: OrmConnectionType;
@Sqlite({
useOrm:true,
tables:['ACCESS'] // If this parameter is not defined, all tables were defined
})
async func(data){
return await this.db.ACCESS.findAll() // Usage refer to the website of sequelize
}
}- use-transaction
You can use transaction in service modules
// the restful modules
import {OrmConnectionType} from 'koa-decorator-resolve';
import {Sqlite} from './declareDecorator';
export class serviceModule {
private db: OrmConnectionType;
@Sqlite({
useOrm:true,
tables:['ACCESS'],
useTransaction:true // use transaction
})
async func(data){
return await this.db.ACCESS.findAll() // Usage refer to the website of sequelize
}
}use-file
You can also configure the database using configuration files
# You need to prepare both files in your root directory
[base] -- .env
| -- db.sqlite.js (if you want to use sqlite)
| -- db.mysql.js (if you want to use mysql)
| -- db.postgres.js (if you want to use postgres)
# The .env file contains the following contents
--------------------------------
| # if you want to use sqlite
| DB_DRIVER=sqlite
| # if you want to use mysql
| # DB_DRIVER=mysql
| # if you want to use postgres
| # DB_DRIVER=postgres
--------------------------------// The db.sqlite.js file contains the following contents
module.exports = {
path: '/etc/test.db'
}
// The db.mysql.js file contains the following contents
module.exports = {
database: 'test_db',
username: 'test_user',
password: 'test_pw',
host: 'localhost',
port: 2001
}
// The db.postgres.js is same as db.mysql.jsCommon-Restful
You can also use post and GET decorators directly
get-post
- file: index.ts
// the entry of project
import * as Koa from 'koa';
import * as Router from 'koa-router';
import { restfulBinder } from 'koa-decorator-resolve';
import * as serviceModules from './serviceModules';
const router = new Router();
restfulBinder(router,serviceModules);
app.use(router.routes());
app.listen(8080, () => {
console.log('server start on 8080');
});- file: serviceModules.ts
import {Get,Post} from 'koa-decorator-resolve';
// the restful modules
export class serviceModule {
@Get('/api/hello/:user')
func1(data, ctx){
return {user: data.user}
}
@Post('/api/hello2')
func2(data, ctx){
return {user: data.user}
}
}