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

docs: add model to rest api docs #4976

Merged
merged 1 commit into from
Mar 27, 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
192 changes: 189 additions & 3 deletions docs/site/Creating-CRUD-REST-apis.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,198 @@
lang: en
title: 'Creating CRUD REST APIs from a model'
keywords: LoopBack 4.0, LoopBack 4
layout: readme
source: loopback-next
file: packages/rest-crud/README.md
sidebar: lb4_sidebar
permalink: /doc/en/lb4/Creating-crud-rest-apis.html
summary:
Use `@loopback/rest-crud` module to create CRUD REST APIs from a model and a
datasource
---

Starting with a [model class](Model.md) and [datasource](DataSources.md),
LoopBack 4 allows you to easily use CRUD REST APIs by convention through
[`@loopback/rest-crud`](https://github.com/strongloop/loopback-next/tree/master/packages/rest-crud).
The package allows the application to use a default CRUD repository and
controller class without creating a custom class for either.

The
[`rest-crud` example](https://github.com/strongloop/loopback-next/tree/master/examples/rest-crud)
is a simplified version of the
[`Todo` example](https://github.com/strongloop/loopback-next/tree/master/examples/todo)
that uses `@loopback/rest-crud`. To see the `rest-crud` example, use the
following command:

```sh
lb4 example rest-crud
```

## Use

To use this functionality, you must already have:

- A LoopBack 4 application (e.g. `ExampleApplication`)
- At least one model class (e.g. `Product`)
- At least one datasource (e.g. `db`)

### Model Configuration Options

The
[`ModelCrudRestApiConfig`](https://loopback.io/doc/en/lb4/apidocs.rest-crud.modelcrudrestapiconfig.html)
interface provides some options to define and customize the REST API:

<table>
<thead>
<tr>
<th>Option</th>
<th>Description</th>
<th>Example</th>
</tr>
</thead>

<tbody>
<tr>
<td><code>model</code></td>
<td>Name of the model class</td>
<td><code>Product</code></td>
</tr>
<tr>
<td><code>pattern</code></td>
<td>Name of data-access pattern</td>
<td>Always use <code>CrudRest</code></td>
</tr>
<tr>
<td><code>dataSource</code></td>
<td>Name of the datasource</td>
<td><code>db</code></td>
</tr>
<tr>
<td><code>basePath</code></td>
<td>Base path for the REST API</td>
<td><code>/products</code></td>
</tr>
</tbody>
</table>

Using the example attributes above, a model configuration file would be defined
as follows:

{% include code-caption.html content="/src/model-endpoints/product.rest-config.ts" %}

```ts
import {ModelCrudRestApiConfig} from '@loopback/rest-crud';
import {Product} from '../models';

module.exports = <ModelCrudRestApiConfig>{
model: Product,
pattern: 'CrudRest', // make sure to use this pattern
dataSource: 'db',
basePath: '/products',
};
```

### CLI Command

LoopBack 4 offers a CLI command to generate the CRUD REST API:

```sh
lb4 rest-crud [options]
```

For example to create CRUD REST API for `Product` and `db`:

```sh
lb4 rest-crud --datasource db --model Product
```

You can also create it for multiple models at the same time. For more
information on the command, see the
[Rest Crud generator](Rest-Crud-generator.md).

This will generate a model configuration file and add the `CrudRestComponent` to
the application file. For more details, see the following section,
[under the hood](#Under-the-hood).

## Under the Hood

The CLI command installs the `@loopback/rest-crud` dependency. Then, from
`@loopback/rest-crud`, the
[`CrudRestComponent`](https://loopback.io/doc/en/lb4/apidocs.rest-crud.crudrestcomponent.html)
is added to the application class, as it enables the functionality of creating
the CRUD REST APIs from the model and datasource. For example:

{% include code-caption.html content="/src/application.ts" %}

```ts
// adds the following import
import {CrudRestComponent} from '@loopback/rest-crud';

export class ExampleApplication extends BootMixin(
RepositoryMixin(RestApplication),
) {
constructor(options: ApplicationConfig = {}) {
// other code

// adds the following line
this.component(CrudRestComponent);
}
}
```

Then it takes the model class and datasource and creates a model configuration
file. For example:

{% include code-caption.html content="/src/model-endpoints/product.rest-config.ts" %}

```ts
import {ModelCrudRestApiConfig} from '@loopback/rest-crud';
import {Product} from '../models';

module.exports = <ModelCrudRestApiConfig>{
model: Product,
pattern: 'CrudRest',
dataSource: 'db',
basePath: '/products',
};
```

Under the hood, a default CRUD controller and repository are created using
[`defineCrudControllerClass`](https://loopback.io/doc/en/lb4/apidocs.rest-crud.definecrudrestcontroller.html)
and
[`defineCrudRepositoryClass`](https://loopback.io/doc/en/lb4/apidocs.rest-crud.definecrudrepositoryclass.html),
respectively. These two functions can also be used at the application level. For
example:

```ts
export class ExampleApplication extends BootMixin(
RepositoryMixin(RestApplication),
) {
constructor(options: ApplicationConfig = {}) {
// ...
}

async boot(): Promise<void> {
await super.boot();

const ProductRepository = defineCrudRepositoryClass(Product);
const repoBinding = this.repository(ProductRepository);

inject('datasources.db')(ProductRepository, undefined, 0);

const ProductController = defineCrudRestController<
Product,
typeof Product.prototype.id,
'id'
>(Product, {basePath: '/products'});

inject(repoBinding.key)(ProductController, undefined, 0);
this.controller(ProductController);
}
}
```

Creating it in the application file allows you to create your own repository and
only use the default CRUD controller, for example.

## Limitations

Currently, the module doesn't support service-oriented datasources such as REST
or SOAP.
132 changes: 132 additions & 0 deletions docs/site/Extending-Model-API-builder.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
---
lang: en
title: 'Extending Model API builder'
keywords: LoopBack 4.0, LoopBack 4
sidebar: lb4_sidebar
permalink: /doc/en/lb4/Extending-Model-API-builder.html
---

The
[`@loopback/model-api-builder`](https://github.com/strongloop/loopback-next/tree/master/packages/model-api-builder)
package provides types and helpers for packages contributing Model API builders.
From a model class, this module can be used to define a contract to create a
corresponding repository and controller. An example Model API builder is the
[`CrudRestApiBuilder`](https://loopback.io/doc/en/lb4/apidocs.rest-crud.crudrestapibuilder.html)
which is used to create a CRUD REST repository and controller. You can see more
details in [Creating CRUD REST APIs](Creating-crud-rest-apis.md).

`@loopback/model-api-builder` helps create a configuration for the repository
and controllers and
[`@loopback/boot`](https://github.com/strongloop/loopback-next/tree/master/packages/boot)
processes this configuration and registers appropriate repositories and
controllers with the app.

To create your own API builder, you need to install the
`@loopback/model-api-builder` dependency:

```sh
npm install --save @loopback/model-api-builder
```

Then you can define class to define your builder. For example:

{% include code-caption.html content="sample.api-builder.ts" %}

```ts
import {ModelApiBuilder} from '@loopback/model-api-builder';

export class SampleApiBuilder implements ModelApiBuilder {}
```

Then bind the builder with
[`@asModelApiBuilder`](https://loopback.io/doc/en/lb4/apidocs.model-api-builder.asmodelapibuilder.html)
so it can be used as an API builder option.

```ts
import {bind} from '@loopback/core';
import {asModelApiBulder, ModelApiBuilder} from '@loopback/model-api-builder';

@bind(asModelApiBuilder)
export class SampleApiBuilder implements ModelApiBuilder {}
```

Since the builder implements `ModelApiBuilder`, the `build` function must be
defined:

```ts
import {bind} from '@loopback/core';
import {
asModelApiBuilder,
ModelApiBuilder,
ModelApiConfig,
} from '@loopback/model-api-builder';
import {ApplicationWithRepositories} from '@loopback/repository';
import {Model} from '@loopback/rest';

@bind(asModelApiBuilder)
export class SampleApiBuilder implements ModelApiBuilder {
readonly pattern: string = 'Sample'; // put the name of your builder here

build(
application: ApplicationWithRepositories,
modelClass: typeof Model & {prototype: Model},
cfg: ModelApiConfig,
): Promise<void> {
// here you can define how the repository and controller classes are built
}
}
```

Additionally, you can add configuration options to be used:

```ts
// imports

export interface SampleApiConfig extends ModelApiConfig {
// add configuration options here
}

@bind(asModelApiBuilder)
export class SampleApiBuilder implements ModelApiBuilder {
// other code here
}
```

After the builder is created, it must be exported as a component in order for it
to be selected by
[`ModelApiBooter`](https://loopback.io/doc/en/lb4/apidocs.boot.modelapibooter.html)
and to then be used in an application. Create a class for the component to
export the builder:

{% include code-caption.html content="sample.component.ts" %}

```ts
import {Component, createBindingFromClass} from '@loopback/core';
import {SampleApiBuilder} from './sample.api-builder';

export class SampleComponent implements Component {
bindings = [createBindingFromClass(SampleApiBuilder)];
}
```

To use the component, add it to your application class:

{% include code-caption.html content="sample.api-builder.ts" %}

```ts
// other imports

// add an import for your component
import {SampleComponent} from '../sample.component';

export class ExampleApplication extends BootMixin(
RepositoryMixin(RestApplication),
) {
constructor(options: ApplicationConfig = {}) {
// other code

// add the following line
this.component(SampleComponent);
}
}
```
2 changes: 1 addition & 1 deletion docs/site/Using-components.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ LoopBack ships the following components:

- [@loopback/rest-explorer](Self-hosted-REST-API-Explorer.md)

### CruRestComponent
### CrudRestComponent

- [@loopback/rest-crud](Creating-CRUD-REST-apis.md)

Expand Down
4 changes: 4 additions & 0 deletions docs/site/sidebars/lb4_sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -320,6 +320,10 @@ children:
url: Extending-OpenAPI-specification.html
output: 'web, pdf'

- title: 'Extending Model API builder'
url: Extending-Model-API-builder.html
output: 'web, pdf'

- title: 'Testing your extension'
url: Testing-your-extension.html
output: 'web, pdf'
Expand Down