Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(docs): refactor docs to create artifacts at runtime #6732

Merged
merged 1 commit into from
Nov 9, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions docs/site/Creating-artifacts-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
lang: en
title: 'Creating Artifacts at Runtime'
keywords: LoopBack 4.0, LoopBack 4, Node.js, TypeScript, OpenAPI
sidebar: lb4_sidebar
permalink: /doc/en/lb4/Creating-artifacts-runtime.html
summary: Create LoopBack artifacts at runtime
---

Besides using the [command-line interface](Command-line-interface.md) to
generate LoopBack artifacts, you can also create the artifacts below at runtime:

- [Model](Creating-model-runtime.md)
- [DataSource](Creating-datasource-runtime.md)
- [Repository](Creating-repository-runtime.md)
35 changes: 35 additions & 0 deletions docs/site/Creating-datasource-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
lang: en
title: 'Creating DataSources at Runtime'
keywords: LoopBack 4.0, LoopBack 4, Node.js, TypeScript, OpenAPI, DataSource
sidebar: lb4_sidebar
permalink: /doc/en/lb4/Creating-datasource-runtime.html
summary: Create LoopBack DataSources 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
the connection details.

```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);
```

For details about datasource options, refer to the [DataSource
documentation])(https://apidocs.strongloop.com/loopback-datasource-juggler/#datasource)
.

Attach the newly created datasource to the app by calling `app.dataSource()`.

{% include note.html content="
The `app.datasource()` method is available only on application classes
with `RepositoryMixin` applied.
" %}
52 changes: 52 additions & 0 deletions docs/site/Creating-model-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
---
lang: en
title: 'Creating Models at Runtime'
keywords: LoopBack 4.0, LoopBack 4, Node.js, TypeScript, OpenAPI, Model
sidebar: lb4_sidebar
permalink: /doc/en/lb4/Creating-model-runtime.html
summary: Create LoopBack Models at runtime
---

Models can also 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`), followed by a `ModelDefinition` object
as shown in the example below.

```ts
const bookDef = new ModelDefinition('Book')
.addProperty('id', {type: 'number', id: true})
.addProperty('title', {type: 'string'});
const BookModel = defineModelClass<typeof Entity, {id: number; title?: string}>(
Entity, // Base model
bookDef, // ModelDefinition
);
```

You will notice that we are specifying generic parameters for the
`defineModelClass()` function. The first parameter is the base model, the second
one is an interface providing the TypeScript description for the properties of
the model we are defining. If the interface is not specified, the generated
class will have only members inherited from the base model class, which
typically means no properties.

In case you need to use an existing Model as the base class, specify the Model
as the base class instead of `Entity`.

```ts
// Assuming User is a pre-existing Model class in the app
import {User} from './user.model';
import DynamicModelCtor from '@loopback/repository';
const StudentModel = defineModelClass<
typeof User,
// id being provided by the base class User
{university?: string}
>(User, studentDef);
```

If you want make this new Model available from other parts of the app, you can
call `app.model(StudentModel)` to create a binding for it.

{% include note.html content="
The `app.model()` method is available only on application classes with
`RepositoryMixin` applied.
" %}
79 changes: 79 additions & 0 deletions docs/site/Creating-repository-runtime.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
lang: en
title: 'Creating Repositories at Runtime'
keywords: LoopBack 4.0, LoopBack 4, Node.js, TypeScript, OpenAPI, Repository
sidebar: lb4_sidebar
permalink: /doc/en/lb4/Creating-repository-runtime.html
summary: Create LoopBack 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);
```

{% include note.html content="
The `app.repository()` method is available only on application classes
with `RepositoryMixin` applied.
" %}
29 changes: 2 additions & 27 deletions docs/site/DataSource.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,9 @@ export class DbDataSource extends juggler.DataSource {
}
```

### Creating a DataSource at Runtime
### Common Tasks

A datasource can be created at runtime by creating an instance of
`juggler.DataSource`. It requires a name for the datasource, the connector, and
the connection details.

```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);
```

For details about datasource options, refer to the [DataSource
documentation])(https://apidocs.strongloop.com/loopback-datasource-juggler/#datasource)
.

Attach the newly created datasource to the app by calling `app.dataSource()`.

{% include note.html content="
The `app.datasource()` method is available only on application classes
with `RepositoryMixin` applied.
" %}
- [Create DataSource at runtime](Creating-datasource-runtime.md)

### Connector

Expand Down
54 changes: 3 additions & 51 deletions docs/site/Model.md
Original file line number Diff line number Diff line change
Expand Up @@ -143,58 +143,10 @@ export class Customer {
}
```
### Defining a Model at Runtime
## Common Tasks
Models can also 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`), followed by a `ModelDefinition` object
as shown in the example below.

```ts
const bookDef = new ModelDefinition('Book')
.addProperty('id', {type: 'number', id: true})
.addProperty('title', {type: 'string'});
const BookModel = defineModelClass<typeof Entity, {id: number; title?: string}>(
Entity, // Base model
bookDef, // ModelDefinition
);
```
You will notice that we are specifying generic parameters for the
`defineModelClass()` function. The first parameter is the base model, the second
one is an interface providing the TypeScript description for the properties of
the model we are defining. If the interface is not specified, the generated
class will have only members inherited from the base model class, which
typically means no properties.

In case you need to use an existing Model as the base class, specify the Model
as the base class instead of `Entity`.

```ts
// Assuming User is a pre-existing Model class in the app
import {User} from './user.model';
import DynamicModelCtor from '@loopback/repository';
const StudentModel = defineModelClass<
typeof User,
// id being provided by the base class User
{university?: string}
>(User, studentDef);
```
If you want make this new Model available from other parts of the app, you can
call `app.model(StudentModel)` to create a binding for it.
{% include note.html content="
The `app.model()` method is available only on application classes with
`RepositoryMixin` applied.
" %}
### Model Discovery
Instead of creating models from scratch, LoopBack can automatically generate
model definitions by discovering the schema of your database. See
[Discovering models](Discovering-models.md) for more details and a list of
connectors supporting model discovery.
- [Define models at runtime](Creating-model-runtime.md)
- [Discover models from databases](DIscovering-models.md)
## Model Metadata
Expand Down
77 changes: 4 additions & 73 deletions docs/site/Repository.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ as a dependency in your application.
You can then install your favorite connector by saving it as part of your
application dependencies.

## Common Tasks

- [Creating Repository at runtime](Creating-repository-runtime.md)

## Repository Mixin

`@loopback/repository` provides a mixin for your Application that enables
Expand Down Expand Up @@ -301,79 +305,6 @@ 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);
```

{% include note.html content="
The `app.repository()` method is available only on application classes
with `RepositoryMixin` applied.
" %}

## Access KeyValue Stores

We can now access key-value stores such as [Redis](https://redis.io/) using the
Expand Down
14 changes: 14 additions & 0 deletions docs/site/sidebars/lb4_sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,20 @@ children:
url: Using-openapi-to-graphql.html
output: 'web, pdf'

- title: 'Creating Artifacts at Runtime'
url: Creating-artifacts-runtime.html
output: 'web, pdf'
children:
- title: 'Creating Model at Runtime'
url: Creating-model-runtime.html
output: 'web, pdf'
- title: 'Creating DataSource at Runtime'
url: Creating-datasource-runtime.html
output: 'web, pdf'
- title: 'Creating Repositories at Runtime'
url: Creating-repository-runtime.html
output: 'web, pdf'

- title: 'Building frontend applications'
output: 'web, pdf'
children:
Expand Down