loopbackio / loopbackio/loopback-next
Support repository mixins when scaffolding repositories and rest-crud APIs
@jimmy1wu arbeitet bereits daran.
Seit 14.7.2020.
- Vorherrschende Sprache
- TypeScript
- Sterne
- 5.1k
- Forks
- 1.1k
- Ø Merge
- 2 T. 21 Std.
- Gemergte PRs (30 T.)
- 27
Beschreibung
## Suggestion
At the moment, we allow sharing of repository code via Repository Base Classes only. The command `lb4 repository` looks for `src/repositories/*.repository.base.ts` and treat them as repository base classes to offer in the prompt:
```
$ lb4 repository
? Please select the datasource DbDatasource
? Select the model(s) you want to generate a repository for Product
? Please select the repository base class (Use arrow keys)
DefaultCrudRepository (Legacy juggler bridge)
----- Custom Repositories -----
❯ AuditingRepository
```
While easy to use, Repository Base Classes have few shortcomings too.
1. JavaScript does not support multiple inheritance, thus it's not possible to combine behavior from multiple repository base classes in the same model-specific repository class.
2. Inheritance-based reuse is considered as an anti-pattern in Object Oriented Design, it's recommended to use composition instead ("prefer composition over inheritance").
Let's enhance `lb4 repository` and `lb4 rest-crud` commands to all allow the user to choose which Repository Mixins to apply.
## Examples
### Model-specific repository class:
```
$ lb4 repository
? Please select the datasource DbDatasource
? Select the model(s) you want to generate a repository for Product
? Please select the repository base class DefaultCrudRepository (Legacy juggler bridge)
? Select the mixin(s) you want to apply (Press to select, to toggle all, to invert
selection)
❯◉ AuditingMixin (src/mixins/auditing.repository-mixin.ts)
◯ TimeStampMixin (src/mixins/timestamp.repository-mixin.ts)
```
Emitted code:
```ts
// src/repositories/product.repository.ts
import {Constructor, inject} from '@loopback/core';
import {DefaultCrudRepository} from '@loopback/repository';
import {DbDataSource} from '../datasources';
import {AuditingRepositoryMixin} from '../mixins/auditing.repository-mixin';
import {Product, ProductRelations} from '../models';
export class ProductRepository extends AuditingRepositoryMixin<
Product,
Constructor<
DefaultCrudRepository<
Product,
typeof Product.prototype.id,
ProductRelations
>
>
>(DefaultCrudRepository) {
constructor(@inject('datasources.db') dataSource: DbDataSource) {
super(Product, dataSource);
}
}
```
### Model API booter (rest-crud)
```
$ lb4 rest-crud
? Please select the datasource DbDatasource
? Select the model(s) you want to generate a CRUD REST endpoint Category
? Select the mixin(s) you want to apply (Press to select, to toggle all, to invert
selection)
❯◉ AuditingMixin (src/mixins/auditing.repository-mixin.ts)
◯ TimeStampMixin (src/mixins/timestamp.repository-mixin.ts)
```
Emitted code:
```ts
// src/model-endpoints/category.rest-config.ts
import {ModelCrudRestApiConfig} from '@loopback/rest-crud';
import {AuditingRepositoryMixin} from '../mixins/auditing.repository-mixin';
import {Category} from '../models';
const config: ModelCrudRestApiConfig = {
model: Category,
pattern: 'CrudRest',
dataSource: 'db',
basePath: '/categories',
repositoryMixins: [
AuditingRepositoryMixin
],
};
module.exports = config;
```
(This will require us to enhance Model API booters to support the new config option `repositoryMixins`.)
## Acceptance criteria
- [ ] Documentation to show how to create repository mixins. At the moment, [Key concepts >> Mixins](https://loopback.io/doc/en/lb4/Mixin.html) does not provide any information specific to repositories. There are detailed instructions in our migration guide, see [Defining A Repository Mixin Class Factory Function](https://loopback.io/doc/en/lb4/migration-models-mixins.html#defining-a-repository-mixin-class-factory-function). It's time to reorganize and clean up this area of our docs.
- [ ] The API contract for repository mixins to allow them to be picked applied by our CLI. For repository base classes, the convention is that the class must accept the same generic parameters and constructor arguments as `DefaultCrudRepository`. We need to come up with a similar convention for repository mixins.
The tricky part is how to support mixins that rely on `Model` and `CrudRepository` features vs. mixins that require Entity-specific things. For the initial version, I think it's fine to support Entity-based mixins only.
- [ ] A new generator `lb4 repository-mixin` to scaffold a new repository mixin
- [ ] A new helper function in `packages/cli/lib` to find all repository mixins. I am proposing to use the following file naming convention:
- `src/mixins/{name}.repository-mixin.ts`
- [ ] Enhance `lb4 repository` to ask the user which mixins to apply and apply them in the scaffolded repository class.
- [ ] A new prompt in `lb4 rest-crud` to ask the user which mixins to apply and apply them in the scaffolded model-api config.
- Update the relevant documentation
- [ ] [Repository generator](https://loopback.io/doc/en/lb4/Repository-generator.html)
- [ ] [REST CRUD model endpoints generator](https://loopback.io/doc/en/lb4/Rest-Crud-generator.html)
- [ ] [Key concepts >> Mixins](https://loopback.io/doc/en/lb4/Mixin.html) should document the requirements on repository mixins and show how to use them with CLI.
Beitragsleitfaden
Erste Schritte
- Lies das ganze Issue und danach den Beitragsleitfaden des Projekts.
- Schreib ins Issue, dass du es übernimmst — das erspart doppelte Arbeit.
- Forke das Repository und arbeite in einem Branch.
- Öffne einen Pull Request, der die Issue-Nummer nennt.
Bewertung
Dieses Issue wurde noch nicht bewertet.