Skip to content

Commit

Permalink
docs: dynamic datasource, model, repository, and controller
Browse files Browse the repository at this point in the history
Describe how to create datasources, models, repositories, and
controllers at runtime.
  • Loading branch information
Yaapa Hage committed Jun 1, 2020
1 parent 5db5863 commit dd4ead4
Show file tree
Hide file tree
Showing 4 changed files with 150 additions and 0 deletions.
31 changes: 31 additions & 0 deletions docs/site/Controllers.md
Original file line number Diff line number Diff line change
Expand Up @@ -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).
22 changes: 22 additions & 0 deletions docs/site/DataSources.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
26 changes: 26 additions & 0 deletions docs/site/Model.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<typeof Entity, {id: number; title?: string}>(
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
Expand Down
71 changes: 71 additions & 0 deletions docs/site/Repositories.md
Original file line number Diff line number Diff line change
Expand Up @@ -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<E, IdType, Relations> {
// Custom implementation
}

const BookRepositoryClass = defineRepositoryClass<
typeof BookModel,
MyRepoBase<BookModel, typeof BookModel.prototype.id, BookRelations>
>(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>
>(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
Expand Down

0 comments on commit dd4ead4

Please sign in to comment.