1.0.10 • Published 6 years ago
loopback4-spring v1.0.10
loopback4-spring
Inspired by Spring Framework:
- @service()
- @transactional()
Installation
npm i -S loopback4-springGetting 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.tsin 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?: Optionsto last parameter of method, it's automatically populated by@transactional() - Pass
optionsto 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);
}
}