Giter VIP home page Giter VIP logo

nest_base's Introduction

nest_base

nestjs 快速初始化

目录结构

├── @types 主要编写type类型  
├── README.md  
├── config 配置文件  
├── constants 全局常量  
├── entities 数据库实体  
├── env 环境变量  
├── error 自定义错误  
├── filter 过滤器全局错误捕获  
├── interceptor 这个是拦截器  
├── type typescript外部应用类型  
├── libs 生成libraries工具包  
├── package.json  
├── repository 数据库实体仓库  
├── src 工作目录  
├── tsconfig.build.json  
├── dto 数据传输对象
├── decorator 自定义装饰器  
├── tsconfig.json typescript文件配置  
└── utils 工具函数包

nestjs 生命周期

Incoming request
Globally bound middleware
Module bound middleware
Global guards
Controller guards
Route guards
Global interceptors (pre-controller)
Controller interceptors (pre-controller)
Route interceptors (pre-controller)
Global pipes
Controller pipes
Route pipes
Route parameter pipes
Controller (method handler)
Service (if exists)
Route interceptor (post-request)
Controller interceptor (post-request)
Global interceptor (post-request)
Exception filters (route, then controller, then global)
Server response


cli 命令集合

Usage: nest generate|g [options] <schematic> [name] [path]

Generate a Nest element.
  Available schematics:
    ┌───────────────┬─────────────┐
    │ name          │ alias       │
    │ application   │ application │
    │ class         │ cl          │
    │ configuration │ config      │
    │ controller    │ co          │
    │ decorator     │ d           │
    │ filter        │ f           │
    │ gateway       │ ga          │
    │ guard         │ gu          │
    │ interceptor   │ in          │
    │ interface     │ interface   │
    │ middleware    │ mi          │
    │ module        │ mo          │
    │ pipe          │ pi          │
    │ provider      │ pr          │
    │ resolver      │ r           │
    │ service       │ s           │
    │ library       │ lib         │
    │ sub-app       │ app         │
    └───────────────┴─────────────┘

Options:
  -d, --dry-run                      Report actions that would be taken without writing out results.
  -p, --project [project]            Project in which to generate files.
  --flat                             Enforce flat structure of generated element.
  --spec                             Enforce spec files generation. (default: true)
  --no-spec                          Disable spec files generation.
  -c, --collection [collectionName]  Schematics collection to use.
  -h, --help                         Output usage information.

初始化步骤和开发须知

1.npm init -y 初始化 npm
2.npm install @nestjs/cli -D 安装 cli
3.创建公共模块 npx nest g library common 然后输入@libs
4.使用 config 模块,在根目录上创建 config 的目录,npm install nestjs-config -S,然后引入如下代码。注:需要依赖环境变量,在根目录创建 env 文件夹

const ENV = process.env.NODE_ENV;
 ConfigModule.load(
      path.resolve(process.cwd(), 'config', '**', '!(*.d).{ts,js}'),
      {
        path: path.resolve(process.cwd(), 'env', !ENV ? '.env' : `.env.${ENV}`),
      },
    ),

5.往公共模块添加数据库@nestjs/typeorm mysql typeorm,添加实体,创建一个公共实体,然后每个实体文件都引入此公共实体,最后引入实体文件,然后公共模块导出,封装公共 repositry,然后自定义一些方法

 TypeOrmModule.forRootAsync({
      useFactory: (config: ConfigService) =>{
        console.log(config.get('database'))
        return  config.get('database')
      },
      inject: [ConfigService],
    }),
import { CreateDateColumn, UpdateDateColumn, DeleteDateColumn, Column } from 'typeorm';
//
export abstract class CommonEntity {
  @Column()
  create_at: number;
  @Column()
  update_at: number;
  @Column()
  delete_at: number;
}
//
import * as entities from 'entities';
const models = TypeOrmModule.forFeature([...Object.values(entities)]);

6.往公共模块添加 redis,首先添加 nestjs-redis 模块

npm install nestjs-redis -S
import { RedisModule } from 'nestjs-redis';
 RedisModule.forRootAsync({
      useFactory: (config: ConfigService) => config.get('redis'),
      inject: [ConfigService],
    }),
    //然后在commonService封装redis操作
    import { RedisService } from 'nestjs-redis';
    constructor(private readonly redis: RedisService) {}

7.添加密码框转换函数,新增 utils 文件夹,新增 passowrdtransformer 类,引入 bcrypt 加密类, npm install bcrypt -S,封装到 commomSerive 的静态方法里,全局可以调用

8.在 controller 添加 dto,这个时候要引入 class-validator,只要判断规则不通过,会 emit 出 error,这个时候需要捕获异常,在 app.modules 的 providers 里面引入 filter,捕获异常,这个时候还需要创建 error 文件夹,把所有的自定义错误在里面定义。

9.添加正常请求的拦截器,interceptor,首先添加 transform-data.interceptor.ts 文件,输入一下内容

import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';
@Injectable()
export class TransformDataInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      map(data => {
        return {
          time: +new Date(),
          data,
        };
      }),
    );
  }
}

10。让 utils 文件夹添加新的方法,自定义返回

export class CustomResponse {
  static success(data: any, msg: string = 'success') {
    return {
      data,
      msg: msg,
      code: 0,
    };
  }
  static fail(data: any, msg: string = '', code: number = -1) {
    return {
      data,
      msg,
      code,
    };
  }
}

11.创建guard守卫,判断是否有权限或者是否已登录,并且给上下文添加用户信息

import { Injectable, CanActivate, ExecutionContext } from '@nestjs/common';
import { CommonService } from '@libs/common';
import { LoginException } from 'error';
import { RoleService } from 'apps/api/src/role/role.service';
import _ = require('lodash');

@Injectable()
export class AuthGuard implements CanActivate {
  constructor(
    private readonly commonService: CommonService,
    private readonly roleService: RoleService,
  ) {

  }
  async canActivate(context: ExecutionContext): Promise<boolean> {
    let req = context.switchToHttp().getRequest();
    let authorization = req.headers.authorization;
    if (authorization) {
      let [key, value] = authorization.split(' ');
      if (value != '') {
        const accessToken = await this.commonService.getToken(value);
        if (accessToken) {
          req.tokenValue = JSON.parse(accessToken);
          req.tokenValue.role = _.map(await this.roleService.getRoleByUser(req.tokenValue.user.id), 'name');
          console.log(req.tokenValue)
          // await this.roleService.getRoleByUser(req.tokenValue.user.id))
          return true;
        }
        throw new LoginException();
      }
      throw new LoginException();
    }
    throw new LoginException();
  }
}

12.创建装饰器decorator目录,把在守卫里添加上下文的对象通过装饰器引用引入到controller中,例如

import { createParamDecorator, ExecutionContext, SetMetadata } from '@nestjs/common';
export const TokenValue = createParamDecorator(
  (data: string, ctx: ExecutionContext) => {
    try {
      const req = ctx.switchToHttp().getRequest();
      const tokenValue = req.tokenValue;
      return data ? tokenValue && tokenValue[data] : tokenValue;
    } catch (error) {
      console.log('TokenValue-error', error);
      return '';
    }
  },
);

export const Roles = (...roles: string[]) => SetMetadata('roles', roles);

一些问题描述

如果不需要自动生成 spec 文件,在 nest-cli.json 添加一下代码,或者生成代码的时候添加 --spec false

"generateOptions": {
    "spec": false
  },

mysql实体设置,关系设置,以博客为例


一对一关系 user=>user_github

//主要是转换,
import {
    Entity,
    Column,
    PrimaryGeneratedColumn,
    PrimaryColumn,
    ValueTransformer,
    OneToMany,
    OneToOne,
    JoinColumn
} from 'typeorm';
import { CommonEntity } from './common';
import { PasswordTransformer } from 'utils/password.transformer';
import { UserGithub } from './user_github';
@Entity('user')
export class User extends CommonEntity {
    @PrimaryGeneratedColumn()
    id: number;
    @Column({
        default: "",
        nullable: false,
    })
    mobile: string
    @Column({
        select: false,
        transformer: new PasswordTransformer()
    })
    password: string
    @Column({
        default: 0,
        select: false,
    })
    github_id!: number
    @OneToOne(type => UserGithub)
    @JoinColumn({
        name: "github_id",
    })
    githubMeta: UserGithub
}
//user_github 
import {
    Entity,
    Column,
    PrimaryGeneratedColumn,
} from 'typeorm';
@Entity('user_github')
export class UserGithub {
    @PrimaryGeneratedColumn()
    id: number;
    @Column({
        default: ""
    })
    name: number
}

多对一和多对多,多个文章对应一个类型,一种类型拥有多个文章,多个文章有多个标签,多个标签属于多个文章

import {
    Entity,
    Column,
    PrimaryGeneratedColumn,
    PrimaryColumn,
    ValueTransformer,
    OneToMany,
    OneToOne,
    ManyToOne,
    JoinColumn,
    ManyToMany,
    JoinTable
} from 'typeorm';
import { CommonEntity } from './common';
import { Category } from './category';
import { Tag } from './tag'
@Entity('article')
export class Article extends CommonEntity {
    @PrimaryGeneratedColumn()
    id: number;
    @Column()
    user_id: string
    @Column()
    title: string
    @Column()
    description: string
    @Column({
        select: false
    })
    category_id: number
    @ManyToOne(type => Category)
    @JoinColumn({
        name: 'category_id'
    })
    category: Category
    @ManyToMany(type => Tag)
    @JoinTable({
        name: 'article_tag',
        joinColumn: {
            name: "article_id",
            referencedColumnName: 'id',
        },
        inverseJoinColumn: {
            name: "tag_id",
            referencedColumnName: 'id',
        }
    })
    tags: Tag[]
}
///Tag
import {
    Entity,
    Column,
    PrimaryGeneratedColumn,
    PrimaryColumn,
    ValueTransformer,
    OneToMany,
    OneToOne,
    ManyToOne,
    ManyToMany,
    JoinTable
} from 'typeorm';
import { CommonEntity } from './common';
import { Article } from './article';
@Entity('tag')
export class Tag extends CommonEntity {
    @PrimaryGeneratedColumn()
    id: number;
    @Column()
    name: string
    @ManyToMany(type => Article)
    articles: Article[]
}
// category
import {
    Entity,
    Column,
    PrimaryGeneratedColumn,
    PrimaryColumn,
    ValueTransformer,
    OneToMany,
    OneToOne,
    ManyToOne
} from 'typeorm';
import { CommonEntity } from './common';
@Entity('category')
export class Category extends CommonEntity {
    @PrimaryGeneratedColumn()
    id: number;
    @Column()
    name: string
}

nest_base's People

Contributors

guojianlan avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.