loopback4-spring
v1.0.10
Published
Inspired by Spring framework
Downloads
299
Readme
loopback4-spring
Inspired by Spring Framework:
- @service()
- @transactional()
Installation
npm i -S loopback4-spring
Getting Started
Register SpringComponent
// Import here...
import {SpringComponent} from "loopback4-spring";
export class SpingLikedExampleApplication extends BootMixin(
ServiceMixin(RepositoryMixin(RestApplication)),
) {
constructor(options: ApplicationConfig = {}) {
super(options);
this.component(SpringComponent);
// Other codes...
}
}
Tag your data source as transactional
Relational database
// Import...
@bind({
tags: ['transactional']
})
export class MysqlDataSource extends juggler.DataSource {
static dataSourceName = 'mysql';
constructor(
@inject('datasources.config.mysql', {optional: true})
dsConfig: object = config,
) {
super(dsConfig);
}
}
Transaction on MongoDB replica set
npm i -S hoangleanhtu/loopback-connector-mongodb
npm i && npm run build
npm run migrate -- --rebuild
// Import here
import * as config from './mongo.datasource.json';
@bind({
tags: ['transactional']
})
export class MongoDataSource extends juggler.DataSource {
static dataSourceName = 'mongo';
constructor(
@inject('datasources.config.mongo', {optional: true})
dsConfig: object = config,
) {
super(dsConfig);
}
}
Create service
classes
- Create file with suffix
.service.ts
in foldersrc/services
- Class name must be suffix by
Service
, e.g:UserService
, then you can inject repository:
// Import here...
export class UserService {
constructor(
@repository(UserRepository)
private userRepository: UserRepository,
@repository(CustomerRepository)
private customerRepository: CustomerRepository
) {
}
// Other methods...
}
Apply transaction to method
- Add
@transactional()
to method - Append
options?: Options
to last parameter of method, it's automatically populated by@transactional()
- Pass
options
to repository method
// Import here...
import {IsolationLevel, transactional} from "loopback4-spring";
export class UserService {
constructor(
@repository(UserRepository)
private userRepository: UserRepository,
@repository(CustomerRepository)
private customerRepository: CustomerRepository
) {
}
@transactional({isolationLevel: IsolationLevel.READ_COMMITTED})
async create(
user: User,
customer: Customer,
throwError: boolean,
options?: Options // Options is populated by @transactional
): Promise<{user: User, customer: Customer}> {
// Must pass options to propagate transaction
await this.userRepository.create(user, options);
await this.customerRepository.create(customer, options);
if (throwError) {
throw new Error('Error after create user & customer. Transaction is rollback.')
}
return {user, customer};
}
@transactional()
async callCreateMethod(
user: User,
customer: Customer,
throwError: boolean,
options?: Object
): Promise<{user: User, customer: Customer}> {
await this.userRepository.create(user, options);
// Pass options here will propagate transaction as well
return this.create(user, customer, throwError, options);
}
}
Inject service in controller
// Other imports...
import {service} from "loopback4-spring";
export class UserController {
constructor(
@service(UserService)
private userService: UserService
) {
}
// OpenAPI annotation...
async createUserAndCustomer(
@requestBody() userAndCustomer: UserAndCustomer,
@param.query.boolean('throwError') throwError: boolean = false
) {
const {user, customer} = userAndCustomer;
return await this.userService.create(user, customer, throwError);
}
}