Q00 / Api_server_boilerplate
Programming Languages
Projects that are alternatives of or similar to Api server boilerplate
Welcome to api_server_boilerplate 👋
easy to use typescript express boilerplate. You can use board api, user api, error tracking etc..
Homepage
🏠Install
yarn install
# after put your env flie
yarn db:dev sync # development environment
# or
yarn db:sync # production environment
Usage
yarn dev # development environment
yarn start # production environment
Run tests
yarn prepare
yarn build
yarn test
Or you can use debug with vscode
code
model
There are base models. You can extend this base models.
Base model
export abstract class BaseModel {
@IsInt()
@Generated('increment')
@PrimaryColumn({ type: 'bigint', transformer: [bigIntTransformer] })
id!: number;
@IsDate()
@CreateDateColumn()
createdAt!: Date;
@IsDate()
@UpdateDateColumn()
updatedAt!: Date;
@IsDate()
@Column({ nullable: true, type: 'date', default: null })
deletedAt?: Date | null;
}
Also There are base board, base comment model.
Base board model
// you can extends this class making child board and add user
export abstract class BaseBoard extends BaseModel {
@Column({ length: 50 })
@IsString()
title!: string;
@IsString()
@Column({ type: 'text' })
content!: string;
@IsInt()
@Column({ default: 0 })
reportCount!: number;
}
Base comment model
// you can extends this class making child comment and add user
export abstract class BaseComment extends BaseModel {
@Column({ length: 50 })
@IsString()
@MaxLength(50)
comment!: string;
@Column({ default: 0 })
@IsInt()
reportCount!: number;
}
service
Threr are base services. You can extend this base services to other child service.
Base service
// you can extends this BaseService to use common method
export abstract class BaseService<T extends BaseModel> {
protected genericRepository: Repository<T>;
private repo: ObjectType<T>;
constructor(repo: ObjectType<T>) {
this.genericRepository = getConnection().getRepository(repo);
this.repo = repo;
}
}
And then you just call super call with your using repository
constructor() {
super(RepoName);
}
Base board service
@Service()
export abstract class BaseBoardService<T extends BaseBoard> extends BaseService<
T
> {
constructor(repo: ObjectType<T>) {
super(repo);
}
}
This service is base board service. In this service, there are common method about board. You can extend this service to other child board service.
Base comment service
export abstract class BaseCommentService<
T extends BaseComment
> extends BaseService<T> {
constructor(repo: ObjectType<T>) {
super(repo);
}
}
This service is base comment service. This service is very similar to base board service.
Provider
This module makes OAUTH logic. You can use base provider to extends other OAUTH.
export abstract class BaseProvider {
protected accessToken: string;
protected instance: AxiosInstance | null;
constructor() {
this.accessToken = '';
this.instance = null;
}
setToken(accessToken: string) {
this.accessToken = accessToken;
}
setInstance(url: string, headers: object) {
this.instance = apiClient(url, headers);
this.instance.interceptors.response.use(
(response) => response,
(err) => Promise.reject(err),
);
}
getInstance() {
return this.instance;
}
async generateToken(userId: number) {
return `Bearer ${Authentication.generateToken(userId)}`;
}
}
Auth Conroller use this provider to make JWT token.
Controller
There are BaseAuthController, BaseCommentController and Other Controller. This project use routing-controllers and typedi. Thier README help you understand this architecture.
Base Auth Controller
export class BaseAuthController<T extends BaseProvider> extends BaseController {
// this can be used in child class (ExampleAuthController)
protected userAccountService: UserAccountService;
protected userService: UserService;
constructor(protected provider: T) {
super();
this.provider = provider;
this.userAccountService = Container.get(UserAccountService);
this.userService = Container.get(UserService);
}
}
Base Comment Controller
export abstract class BaseCommentController<
U extends BaseComment,
T extends BaseCommentService<U>
> extends BaseController {
protected service: T;
constructor(service: T) {
super();
this.service = service;
}
}
If you want to extends this controller, you should call super with service like below.
@JsonController('/example_board_comment')
export class ExampleBoardCommentController extends BaseCommentController<
ExampleBoardComment,
ExampleBoardCommentService
> {
//this private service automaticaly injected by typedi
constructor(private exampleBoardCommentService: ExampleBoardCommentService) {
super(exampleBoardCommentService);
}
}
DTO
To make request schema, this project use class-validator. This request schema will be shown in swagger ui or Redoc.
Interceptor
This module use routing-controllers interceptor
Middleware
This module use routing-controllers Middleware
Database
This project use typeorm and connect with Postgres.
Naming Strategy
using snake case.
export class NamingStrategy extends DefaultNamingStrategy {
tableName(targetName: string, userSpecifiedName: string | undefined): string {
return plural(snakeCase(userSpecifiedName || targetName));
}
relationName(propertyName: string): string {
return snakeCase(propertyName);
}
columnName(propertyName: string, customName: string) {
return snakeCase(customName || propertyName);
}
joinColumnName(relationName: string, referencedColumnName: string) {
return snakeCase(`${relationName}_${referencedColumnName}`);
}
joinTableColumnName(
tableName: string,
propertyName: string,
columnName: string,
) {
return snakeCase(`${tableName}_${columnName || propertyName}`);
}
}
config
const typeOrmConfig: PostgresConnectionOptions = {
type: 'postgres',
host: process.env.DB_HOST,
namingStrategy: new NamingStrategy(),
port: Number(process.env.DB_PORT),
username: process.env.DB_USER,
password: process.env.DB_PW,
database: process.env.DATABASE,
synchronize: false,
logging: false,
entities: [`${path.join(__dirname, '..', 'model')}/**.[tj]s`],
migrations: [`${path.join(__dirname, '..', 'model')}/migration/**.[tj]s`],
};
Env variable
DB_HOST=
DB_USER=
DB_PW=
PORT= # your server port
DB_PORT=
DATABASE= # database name
TEST_TOKEN= # jwt token to use in testing
SENTRY_DSN= # sentry dsn
Author
👤 Q00 [email protected]
- Website: https://velog.io/@q00
- Github: @Q00
🤝 Contributing
Contributions, issues and feature requests are welcome!
Feel free to check issues page.
If you want to contribute this repo, check contribute page
🔍 Relase note && Change log
Release note and change log are exist in CHANGELOG
Show your support
Give a ⭐️ if this project helped you!
This README was generated with ❤️ by readme-md-generator