What is the best way of calling different repository at the main repository? I tried to use Services. For example
...
@injectable({scope: BindingScope.TRANSIENT})
export class ProjectService {
constructor(@repository(ProjectRepository) public projectRepository: ProjectRepository) { }
}
Here is my service code. When I define this service at another repoository, I am able to access projectRepository. But I am not sure this is the best way.
We can take a page from Relations [1] and utilize @repository.getter()
[2] to perform dependency injection in the main Repository:
import {Getter} from '@loopback/core';
import {DefaultCrudRepository, repository} from '@loopback/repository';
export class MainRepository() extends DefaultCrudRepository</*...*/>{
constructor(
@repository.getter(ProjectRepository)
private _projectRepositoryGetter: Getter<ProjectRepository>;
)
async yourFunction(): Promise<void> {
let projectRepository = await this._projectRepositoryGetter();
// `projectRepository` now contains an instance of ProjectRepository.
}
}
In the example above, we're utilizing constructor injection and retrieving the ProjectRepository
instance in an arbitrary function called yourFunction
. However, you can use any flavour of dependency injection [3] and retrieve the instance in any function within the same closure.
Why getters?
Getters to prevent circular dependencies. These are especially prevalent in Repositories as they may have Relations that interconnect between each other. Getters achieve this by delaying the binding resolution until explicitly requested by the LB4 application.
When to use Services?
Services can be considered a higher-level abstract than Repositories. They aren't expected to implement a standard CRUD or KV interface and aren't assumed to be linked to a DataSource. This is useful if you need logic that are out-of-scope of Repositories. For example, a Service may implement a function that adds a new database record and uploads a file to Amazon S3. This keeps a clear separation between the code that interfaces with the Datastore and those that don't, thereby ensuring that the Datastore logic is kept predictable, readable and easy to test.
[1] https://loopback.io/doc/en/lb4/HasMany-relation.html#configuring-a-hasmany-relation (archive)
[2] https://loopback.io/doc/en/lb4/apidocs.repository.repository.getter.html (git permalink)
[3] https://loopback.io/doc/en/lb4/Dependency-injection.html#flavors-of-dependency-injection (git permalink)