Skip to content
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
218 changes: 206 additions & 12 deletions docs/site/Model.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,30 +157,28 @@ class MyFlexibleModel extends Entity {
### Model Decorator

The model decorator can be used without any additional parameters, or can be
passed in a
passed in a ModelDefinitionSyntax:

<!-- should be replaced with a lb4 example when possible -->

[ModelDefinitionSyntax](https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html)
object which follows the general format provided in LoopBack 3:
<!-- according to https://github.com/strongloop/loopback-datasource-juggler/blob/master/lib/model-builder.js#L283 and the legacy juggler file-->

```ts
@model({
name: 'Category',
properties: {
// define properties here.
},
settings: {
// etc...
},
// define properties by @property decorator below
})
class Category extends Entity {
// etc...
@property({type: 'number'})
categoryId: number;
}
```

However, the model decorator already knows the name of your model class, so you
can omit it.
The model decorator already knows the name of your model class, so you can omit
it.

```ts
@model()
Expand All @@ -190,9 +188,197 @@ class Product extends Entity {
}
```

Additionally, the model decorator is able to build the properties object through
the information passed in or inferred by the property decorators, so the
properties key value pair can also be omitted.
However, the model decorator in LoopBack 4 is not exactly the same as what it is
in LoopBack 3. For example, in
[lb3](https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html) we can
pass in a model definition syntax in the model decorator, such as properties,
options, relation etc. But not all these entries are available in lb4 model
decorator:

<!-- Please modify this part when options is available -->

NOTICE: in LoopBack 4 we only support `settings` in the ModelDefinitionSyntax
for now. Those `top-level properties` in lb3 now are passed in `settings`.

- `properties` now are defined in `@property` decorator (see below for more
information).
- [`options`](https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#options)
in lb3 doesn't have the mapping feature in LB4 yet. (see
[issue #2142](https://github.com/strongloop/loopback-next/issues/2142) for
further discussion.)

As for entries in `settings`, LoopBack 4 supports these built-in entries for
now:

#### Supported Entries of Settings

<!-- These entries might need to update once we've made some changes:
- description [in lb3 we support array or string, but here we documented it as string only]
these two don't seem work in lb4. Moved them to unsupported table.
-->

<table>
Comment thread
agnes512 marked this conversation as resolved.
<thead>
<tr>
<th width="160">Property</th>
<th width="100">Type</th>
<th>Default</th>
<th>Description</th>
</tr>
</thead>

<tbody>

<tr>
<td><code>description</code></td>
<td>String</td>
<td>None</td>
<td>
Optional description of the model. We only support string type for now. (see <a href="https://github.com/strongloop/loopback-next/issues/3428">issue #3428</a> for more discussion.)
Comment thread
agnes512 marked this conversation as resolved.
</td></tr>

<tr>
<td><code>forceId</code></td>
<td>Boolean</td>
<td><code>true</code></td>
<td>
If true, prevents clients from setting the auto-generated ID value manually.
</td>
</tr>

<tr>
<td><code>strict</code></td>
<td>Boolean or String</td>
<td><code>true</code>.<br/></td>
<td>
In LB4, the default for this entry is set to be <code>true</code>.<br/>
Specifies whether the model accepts only predefined properties or not. One of:
<ul>
<li><code>true</code>: Only properties defined in the model are accepted. Use if you want to ensure the model accepts only predefined properties.
If you try to save a model instance with properties that are not predefined, LoopBack throws a ValidationError.
</li>
<li><code>false</code>: The model is an open model and accepts all properties, including ones not predefined in the model.
This mode is useful to store free-form JSON data to a schema-less database such as MongoDB.
</li>
<li><code>"filter"</code>: Only properties defined in the model are accepted.
If you load or save a model instance with properties that are not predefined, LoopBack will ignore them. This is particularly useful when dealing with old data that you wish to lose without a migration script.
</li>
</ul>
</td>
</tr>

<tr>
<td><code>idInjection</code></td>
<td>Boolean</td>
<td><code>true</code></td>
<td>
Whether to automatically add an <code>id</code> property to the model:
<ul>
<li><code>true</code>: <code>id</code> property is added to the model automatically. This is the default.</li>
<li><code>false</code>: <code>id</code> property is not added to the model</li>
</ul>
See <a href="#id-properties">ID properties</a> for more information. The <code>idInjection</code> property in <code>options</code> (if present) takes precedence.
</td>
</tr>

<tr>
<td><code>name</code></td>
<td>String</td>
<td>None</td>
<td>Name of the model.</td>
</tr>

<tr>
<td><code>scopes</code></td>
<td>Object</td>
<td>N/A</td>
<td>See <a href="https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#scopes">Scopes</a> in lb3 docs.</td>
Comment thread
agnes512 marked this conversation as resolved.
</tr>

</tbody>

</table>

#### Unsupported Entries of Settings

<!-- Please update the OPTIONS, ACLS field when they are available -->

<table>
<thead>
<tr>
<th width="160">Property</th>
<th>Description</th>
</tr>
</thead>

<tbody>

<tr>
<td><code>acls</code></td>
<td>
(TBD)
</td>
</tr>

<tr>
<td><code>base</code></td>
<td>This entry is no longer being used. This is done by the typical Js/Tsc classes inheritance way in LB4:
<pre><code>@model() class MySuperModel extends MyBaseModel {...}</code>
</pre></td>
</tr>

<tr>
<td><code>excludeBaseProperties</code></td>
<td>(TBD)</td>
</tr>

<tr>
<td><code>http</code></td>
<td> This entry affects HTTP configuration in LB3. Since in LB4 http configurations are inferred from controller members and the rest server, this field is not applicable.</td>
</tr>

<tr>
<td><code>options</code></td>
<td>
(TBD) see <a href="https://github.com/strongloop/loopback-next/issues/2142">issue #2142</a> for further discussion.
</td>
</tr>

<tr>
<td><code>plural</code></td>
<td>This entry is part of HTTP configuration in LB3. So it's not applicable for the same reason as <code>http</code> above.</td>
</tr>

<tr>
<td><code>properties</code></td>
<td>This entry is no longer being used as we introduced <code>@property</code> decorator in LB4. See <code>@property</code> decorator below to discover moer about how to define properties for your models.</td>
</tr>

<tr>
<td><code>relations</code></td>
<td>
With the introduction of <a href="https://loopback.io/doc/en/lb4/Repositories.html">repositories</a>, now <code>relations</code> are defined by <code>relations decorators</code> in LB4.
See <a href="https://loopback.io/doc/en/lb4/Relations.html">Relations</a> for more details.
</td>
</tr>
<tr>
<td><code>remoting.<br/>normalizeHttpPath</code></td>
<td>
This entry is part of HTTP configuration in LB3. So it's not applicable for the same reason as <code>http</code> above.
</td>
</tr>

<tr>
<td><code>replaceOnPUT</code></td>
Comment thread
agnes512 marked this conversation as resolved.
<td>This entry is no longer supported as LB4 controllers scaffolded by LB4 controller, PUT is always calling replaceById. Users are free to change the generated code to call <code>patchById</code> if needed.</td>
</tr>
</tbody>
</table>

To discover more about `Model Decorator` in LoopBack 4, please check
[legacy-juggler-bridge file](https://github.com/strongloop/loopback-next/blob/2fa5df67181cdcd23a5dce90c9c640fe75943cb8/packages/repository/src/repositories/legacy-juggler-bridge.ts)
and
[model-builder file](https://github.com/strongloop/loopback-datasource-juggler/blob/master/lib/model-builder.js).

#### Hidden properties

Expand Down Expand Up @@ -221,6 +407,8 @@ class MyUserModel extends Entity {

### Property Decorator

<!-- Property decorator can reuse lb3 docs -->
Comment thread
agnes512 marked this conversation as resolved.

The property decorator takes in the same arguments used in LoopBack 3 for
individual property entries:

Expand All @@ -233,6 +421,12 @@ class Product extends Entity {
type: 'string',
})
public name: string;

@property({
type: 'number',
id: true,
})
id: number;
}
```

Expand Down
37 changes: 37 additions & 0 deletions packages/repository/DEVELOPING.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
## LB4 vs. LB3

### How LoopBack 4 creates/handles models. [2019 July 24]

In `lb4`, we introduce the concept of
[`repository`](https://loopback.io/doc/en/lb4/Repositories.html). In order to
implement this new feature `repository`, we are using legacy juggler bridge as a
(temporary) solution. Each model has two **parallel classes**:

- The class defined by the app developers using decorators and
`class MyModel extends Entity` syntax.
- The "implementation" class created by legacy-juggler-bridge, this class is
inheriting from juggler's Model `base class`.

If you take a deep look into it, you would find that LB4 model handles some data
before it hands the model to Juggler. That's why `lb4` has some differences
compared to `lb3` when generating models.

For example, you might notice that some entries in `@model` decorator are not
available/supported by lb4 even they both run the same lines of code in Juggler.
For instance, the default values for the `strict` entry in `@model decorator`
are different:

| | [in LB3](https://loopback.io/doc/en/lb3/Model-definition-JSON-file.html#top-level-properties) | [in LB4](https://loopback.io/doc/en/lb4/Model.html#model-decorator) |
| --------- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `default` | `false` | `true` |
| code | [defined here](https://github.com/strongloop/loopback-datasource-juggler/blob/2b8c1ebaeec3d8be87da38236db3d8210bca6230/lib/model-builder.js#L130) | [defined here](https://github.com/strongloop/loopback-next/blob/ba3f3894ef7e102b0fcd8b9b7a1f1d221bbbf4a4/packages/repository/src/repositories/legacy-juggler-bridge.ts#L160) |

Hope this example shows the idea that even they both use the `base model` from
Juggler, LB4 model doesn't use, or even have access to some fields/entries in
the Juggler model!

As mentioned before, we are using the legacy juggler bridge as a temporary
solution. This may change in the future since the Juggler is pretty.. you know,
legacy. However, it's important to realize how LB4 deals with models.

Happy coding :D