# loopback4-spring

> Inspired by Spring framework

Latest version **1.0.10** (published 2019-07-13) · ISC license · 0 weekly downloads

## Install

```sh
npm install loopback4-spring
pnpm add loopback4-spring
yarn add loopback4-spring
bun add loopback4-spring
```

## Health

**Score 15/100 (F)** — status: abandoned.

Positive: no vulnerabilities.

Warnings: low downloads; no types; no esm support.

Negative: abandoned; low maintenance score.

## Facts

| | |
|---|---|
| Version | 1.0.10 |
| Published | 2019-07-13 |
| First published | 2019-05-03 |
| Weekly downloads | 0 |
| License | ISC |
| TypeScript types | none |
| Module format | CommonJS |
| Dependencies | 3 |
| Unpacked size | 47.5 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 9 |
| Author | hoangleanhtu@gmail.com |
| Maintainers | tu.hoang |

## Links

- npm: https://www.npmjs.com/package/loopback4-spring
- Repository: https://github.com/hoangleanhtu/loopback4-spring
- Homepage: https://github.com/hoangleanhtu/loopback4-spring#readme
- Issues: https://github.com/hoangleanhtu/loopback4-spring/issues
- npm.io page: https://npm.io/package/loopback4-spring

## Dependencies (3)

- [@loopback/boot](https://npm.io/package/@loopback/boot.md) ^1.4.4
- [@loopback/core](https://npm.io/package/@loopback/core.md) ^1.8.5
- [@loopback/repository](https://npm.io/package/@loopback/repository.md) ^1.8.2

## Recent versions

- 1.0.10 (latest) — 2019-07-13
- 1.0.9 — 2019-06-28
- 1.0.8 — 2019-06-07
- 1.0.7 — 2019-06-06
- 1.0.6 — 2019-06-03
- 1.0.5 — 2019-06-03
- 1.0.4 — 2019-06-03
- 1.0.3 — 2019-05-04
- 1.0.2 — 2019-05-03
- 1.0.1 — 2019-05-03
- 1.0.0 — 2019-05-03

## README

# loopback4-spring
Inspired by [Spring Framework](https://spring.io/):

* @service()
* @transactional()

# Installation

```
npm i -S loopback4-spring
```

# Getting Started

* [Example](./example)

## Register SpringComponent
```typescript
// 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
```typescript
// 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
```

```typescript
// 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
1. Create file with suffix `.service.ts` in folder `src/services`
2. Class name must be suffix by `Service`, e.g: `UserService`, then you can inject repository:

```typescript
// Import here...
export class UserService {

    constructor(
        @repository(UserRepository)
        private userRepository: UserRepository,
        @repository(CustomerRepository)
        private customerRepository: CustomerRepository
    ) {
    }
    
    // Other methods...
}
```

## Apply transaction to method

1. Add `@transactional()` to method
2. Append `options?: Options` to last parameter of method, it's automatically populated by `@transactional()`
3. Pass `options` to repository method

```typescript
// 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
```typescript
// 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);
    }
 
    
}
```

---
_Source: https://npm.io/package/loopback4-spring · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
