packaged @mvx/model
This repo is for distribution on npm
. The source for this module is in the
main repo.
@mvx/model
is Decorator, Ioc, AOP MVC frameworker. base on ioc @tsdi
. help you develop your project easily.
Install
You can install this package either with npm
npm
npm install @mvx/mvc
Documentation
create application
import { MvcApplication, DefaultMvcMiddlewares, MvcModule, MvcServer } from '@mvx/mvc';
MvcApplication.run();
@MvcModule({
imports: [
],
debug: true
})
class MvcApi {
constructor() {
console.log('boot application');
}
}
@MvcModule({
imports: [
],
middlewares: DefaultMvcMiddlewares,
})
class MvcApi {
}
MvcApplication.run(MvcApi);
@MvcModule({
imports: [
],
debug: true
})
class MvcApi {
constructor() {
console.log('boot application');
}
static main() {
console.log('run mvc api...');
MvcApplication.run(MvcApi);
}
}
Define Model
- third ORM Model: Configuration ModelOptions in your config file. like:
{
...
modelParser?: Token<IModelParser>;
...
}
import { Model, Field } from '@mvx/mvc';
@Model
export class User {
@Field
name: string;
@Field
sex: string;
@Field
age: number;
}
@Model
export class AccountUser extends User {
@Field
account: string;
@Field
passwd: string;
}
@Model
export class ShoppingCart{
@Field
owner: User;
....
}
Define Middlewares
default setting load middlewares in your project folder
/middlewares
import { Middleware, IMiddleware, IContext, MvcMiddleware, ForbiddenError } from '@mvx/mvc';
import { IContainer, Injectable } from '@tsdi/core';
@Middleware({
name: 'log-test',
after: MiddlewareTypes.BodyParser
})
export class Logger implements IMiddleware {
constructor() {
}
async execute (ctx, next) {
let start = Date.now();
await next();
const ms = Date.now() - start;
console.log(`mylog: ${ctx.method} ${ctx.url} - ${ms}ms`);
let end = new Date();
}
}
@Middleware({ name: 'rightCheck', scope: 'route' })
export class RoleRightCheck extends MvcMiddleware {
async execute(ctx: IContext, next: () => Promise<void>): Promise<void> {
console.log('check user right.......');
let hasRight = true;
if (hasRight) {
await next();
} else {
throw new ForbiddenError();
}
}
}
Auth use @Authorization
pointcut
- aop pointcut to to dynamic check the controller with
@Authorization
decorator, use your custom auth validation. eg.
@Aspect
export class YourSecrityAspect {
@Before(AuthorizationPointcut, 'authAnnotation')
sessionCheck(authAnnotation: AuthorizationMetadata[], joinPoint: Joinpoint) {
}
}
Define Controller
default setting load controllers in your project folder
/controllers
- Each Controller action should return type
ResultValue
, also you can return base type or object, it deal with JsonResult. - The action can be
async
or sync
. Have provide FileResult
, JsonResult
,
RedirectResult
, ViewResult
or mvc Middleware. - Also, you can extend with
BaseController
, it has implements some mothod to create the ResultValue
types. - Model can auto create in action, it auto load value from request body.
- Restfull params or Query String params can auto set to Controller action(Controller method) via the name of param matched.
- Cors by
@Cors
decorator in class or method. - Your can set some special middlewares for route via decorator:
@Controller
, @Put
, @Post
, @Get
, @Delete
, @Patch
, @Head
, @Route
.
define as:
import { Controller, Get, Post, IContext, ContextToken, RequestMethod, Model, Field, Cors } from '@mvx/mvc';
import { Inject } from '@tsdi/core';
import { Mywork } from '../bi/Mywork';
import { User } from '../models';
@Cors
@Controller('/users')
export class UserController {
constructor(private work: Mywork) {
}
@Get('')
index() {
console.log('home index invorked', this.work);
return this.work.workA();
}
@Authorization()
@Post('/add', ['your-auth-middleware', 'rightCheck'])
async addUser(user: User, @Inject(ContextToken) ctx: IContext) {
console.log('user:', user);
console.log('request body', ctx.request.body);
return this.work.save(user);
}
@Get('/sub')
sub() {
return this.work.workB();
}
@Cors
@Get('/:name')
getPerson(name: string) {
return this.work.find(name);
}
@Get('/find/:name')
find(@Inject(ContextToken) ctx, name: string) {
console.log(ctx);
return this.work.find(name);
}
@Get('/query')
query(key: string, role: string, age?: number) {
return { key: key, age: age, role: role }
}
@Get('/test/:id')
parmtest(id: number) {
if (id === 1) {
return this.work.workA();
} else if (id === 2) {
return this.work.workB();
} else {
return 'notFound';
}
}
@Post('/posttest/:id', ['rightAuth'])
postTest(id: number) {
return {
id: id
}
}
}
@Controller('/')
export class HomeController extends BaseController {
constructor() {
super();
}
@Get('')
index(): ResultValue {
return this.view('index.html');
}
@Get('/index2')
home2(): ResultValue {
return this.view('index2.html');
}
@Post('/goto/:pageName')
gotoPage(pageName: string): ResultValue {
return this.redirect( '/' + pageName);
}
}
startup extension Service
imports class extends StartupService
, will inovke your configure service code.
socket.io sample.
@Singleton
export class RealtimeService extends StartupService<MvcContext> {
io: Server;
@Inject(RootMessageQueueToken)
queue: MessageQueue<MessageContext>;
constructor() {
super();
}
async configureService(ctx: MvcContext): Promise<void> {
let logger = ctx.logManager.getLogger();
logger.info('create socket server...');
this.io = SockerServer(ctx.httpServer);
this.io.on('connection', sock => {
logger.info('socket client connected', sock.id);
});
}
}
@MvcModule({
imports: [
IdentityModule,
TypeOrmModule,
RealtimeService
]
})
class MvcApp {
constructor() {
console.log('boot application');
}
}
MvcApplication.run(MvcApp);
configuration
- default use config file
./config.ts
or ./config.js
.
export interface MvcConfiguration extends RunnableConfigure {
keys?: Keygrip | string[];
httpsOptions?: ServerOptions;
hostname?: string;
port?: number;
session?: SessionConfig;
contents?: string[];
routePrefix?: string;
subSites?: SubSite[];
setting?: ObjectMap;
connections?: IConnectionOptions;
corsOptions?: CorsOptions;
loadMiddlewares?: string | string[];
loadControllers?: string | string[];
aop?: string | string[];
usedAops?: Type[];
views?: string;
viewsOptions?: IViewOptions;
models?: string[] | Type[];
debug?: boolean;
logConfig?: LogConfigure | Type<LogConfigure>;
}
export interface IConfiguration extends MvcConfiguration {
}
Define Model
-
third ORM Model: register yourself module parser extends ModelParser
.
-
typeorm model use : @tsdi/typeorm-adapter
-
default load module in ./models
folder, with exp ['.\/models\/**\/*{.js,.ts}', '!.\/**\/*.d.ts']
-
default load repositories in ./repositories
folder, with exp ['.\/repositories\/**\/*{.js,.ts}', '!.\/**\/*.d.ts']
import { Model, Field } from '@mvx/mvc';
@Model
export class User {
@Field
name: string;
@Field
sex: string;
@Field
age: number;
}
@Model
export class AccountUser extends User {
@Field
account: string;
@Field
passwd: string;
}
@Model
export class ShoppingCart{
@Field
owner: User;
....
}
Define AOP
Auto load Aspect service from folder /aop
in your project.
see simple demo
import { Aspect, Around, Joinpoint, Before } from '@tsdi/aop';
@Aspect
export class DebugLog {
@Around('execution(*Controller.*)')
log(joinPoint: Joinpoint) {
console.log('aspect append log, method name:', joinPoint.fullName, ' state:', joinPoint.state, ' Args:', joinPoint.args , ' returning:', joinPoint.returning, ' throwing:', joinPoint.throwing);
}
@Before(/Controller.\*$/)
Beforlog(joinPoint: Joinpoint) {
console.log('aspect Befor log:', joinPoint.fullName);
}
}
Simples
see simples
Documentation
Documentation is available on the
License
MIT © Houjun