diff --git a/docs/site/Controllers.md b/docs/site/Controllers.md index a811e09f7476..358f07d84a98 100644 --- a/docs/site/Controllers.md +++ b/docs/site/Controllers.md @@ -269,3 +269,34 @@ export class HelloController { } } ``` + +## Creating Controllers at Runtime + +A controller can be created for a model at runtime using the +`defineCrudRestController` helper function from the `@loopback/rest-crud` +package. It accepts a Model class and a `CrudRestControllerOptions` object. +Dependency injection for the controller has to be configured by applying +the `inject` decorator manually as shown in the example below. + +```ts +const basePath = '/' + bookDef.name; +const BookController = defineCrudRestController(BookModel, {basePath}); +inject(repoBinding.key)(BookController, undefined, 0); +``` + +The controller is then attached to the app by calling the `app.controller()` +method. + +```ts +app.controller(BookController); +``` + +The new CRUD REST endpoints for the model will be available on the app now. + +If you want a customized controller, you can create a copy of +`defineCrudRestController`'s +[implementation](https://github.com/strongloop/loopback-next/blob/00917f5a06ea8a51e1f452f228a6b0b7314809be/packages/rest-crud/src/crud-rest.controller.ts#L129-L269) +and modify it according to your requirements. + +For details about `defineCrudRestController` and `CrudRestControllerOptions`, +refer to the [@loopback/rest-crud API documentation](./apidocs/rest-crud.html). diff --git a/docs/site/DataSources.md b/docs/site/DataSources.md index 5216b0e30165..4fae5996129e 100644 --- a/docs/site/DataSources.md +++ b/docs/site/DataSources.md @@ -52,3 +52,25 @@ export class DbDataSource extends juggler.DataSource { } } ``` + +### Creating a DataSource at Runtime + +A datasource can be created at runtime by creating an instance of +`juggler.DataSource`. It requires a name for the datasource, the connector, and +a connection url as shown below. + +```ts +import { juggler } from '@loopback/repository'; +const dsName = 'bookstore-ds'; +const bookDs = new juggler.DataSource({ + name: dsName, + connector: require('loopback-connector-mongodb'), + url: 'mongodb://sysop:moon@localhost', +}); +await bookDs.connect(); +app.dataSource(bookDs, dsName); +``` + +To use the newly created datasource, call its `.connect()` method and attach it +to the app using `app.dataSource()` method. Note, this method will be available +only on `RepositoryMixin` apps. diff --git a/docs/site/Model.md b/docs/site/Model.md index 9476c0039810..06e0c7b5bdbb 100644 --- a/docs/site/Model.md +++ b/docs/site/Model.md @@ -112,6 +112,32 @@ export class Customer { } ``` +## Defining a Model at runtime + +Models can be created at runtime using the `defineModelClass()` helper function +from the `@loopback/repository` class. It expects a base model to extend +(typically `Model` or `Entity`), folowed by the model definition object as +shown in the example below. + +```ts +const BookModel = defineModelClass( + Entity, + bookDef, +); +``` + +In case you need to use an existing Model as the base class, specify the Model +as the base class instead of `Entity`. + +```ts +import DynamicModelCtor from '@loopback/repository'; +// Assuming User is a pre-existing Model class in the app +const StudentModel = defineModelClass< + typeof User, + {id: number; university?: string} +>(User, studentDef); +``` + ## Model Discovery LoopBack can automatically create model definitions by discovering the schema of diff --git a/docs/site/Repositories.md b/docs/site/Repositories.md index 6e8f6cdcf377..bc706f791dcd 100644 --- a/docs/site/Repositories.md +++ b/docs/site/Repositories.md @@ -300,6 +300,77 @@ Please See [Testing Your Application](Testing-your-application.md) section in order to set up and write unit, acceptance, and integration tests for your application. +## Creating Repositories at Runtime + +Repositories can be created at runtime using the `defineCrudRepositoryClass` +helper function from the `@loopback/rest-crud` package. It creates +`DefaultCrudRepository`-based repository classes by default. + +```ts +const BookRepository = defineCrudRepositoryClass< + Book, + typeof Book.prototype.id, + BookRelations +>(BookModel); +``` + +In case you want to use a non-`DefaultCrudRepository` repository class or you +want to create a custom repository, use the `defineRepositoryClass()` helper +function instead. Pass a second parameter to this function as the base class for +the new repository. + +There are two options for doing this: + +#### 1. Using a base repository class + +Create a base repository with your custom implementation, and then specify this +repository as the base class. + +```ts +class MyRepoBase< + E extends Entity, + IdType, + Relations extends object +> extends DefaultCrudRepository { + // Custom implementation +} + +const BookRepositoryClass = defineRepositoryClass< + typeof BookModel, + MyRepoBase +>(BookModel, MyRepoBase); +``` + +#### 2. Using a Repository mixin + +Create a repository mixin with your customization as shown in the " +[Defining A Repository Mixin Class Factory Function](https://loopback.io/doc/en/lb4/migration-models-mixins.html#defining-a-repository-mixin-class-factory-function) +" example, apply the mixin on the base repository class (e.g. +`DefaultCrudRepository`) then specify this combined repository as the base class +to be used. + +```ts +const BookRepositoryClass = defineRepositoryClass< + typeof BookModel, + DefaultCrudRepository< + BookModel, + typeof BookModel.prototype.id, + BookRelations + > & + FindByTitle +>(BookModel, FindByTitleRepositoryMixin(DefaultCrudRepository)); +``` + +Dependency injection has to be configured for the datasource as shown below. + +```ts +inject(`datasources.${dsName.name}`)(BookRepository, undefined, 0); +const repoBinding = app.repository(BookRepository); +``` + +Note, the `app.repository()` method will be available only on `RepositoryMixin` +apps + ## Access KeyValue Stores We can now access key-value stores such as [Redis](https://redis.io/) using the