Skip to content

Commit

Permalink
docs: first draft of Component Migration - general aspects
Browse files Browse the repository at this point in the history
Signed-off-by: Miroslav Bajtoš <[email protected]>
  • Loading branch information
bajtos committed May 5, 2020
1 parent 221bd6b commit ded442b
Show file tree
Hide file tree
Showing 7 changed files with 338 additions and 102 deletions.
47 changes: 47 additions & 0 deletions docs/site/migration/components/current-context.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
---
lang: en
title: 'Migrating access to current context'
keywords: LoopBack 4, LoopBack 3, Migration, Extensions, Components
sidebar: lb4_sidebar
permalink: /doc/en/lb4/migration-extensions-current-context.html
---

{% include tip.html content="
Missing instructions for your LoopBack 3 use case? Please report a [Migration docs issue](https://github.com/strongloop/loopback-next/issues/new?labels=question,Migration,Docs&template=Migration_docs.md) on GitHub to let us know.
" %}

It's often desirable to share contextual data between different parts of an
application. For example, a REST connector calling a backend web service may
want to forward transaction (correlation) id provided in a HTTP header of the
incoming request, or perhaps an auditing component wants to access the
information about the user making the request to store it in the log.

LoopBack 3 offers three approaches:

1. The recommended solution is to explicitly pass any contextual information via
`options` argument. Most LoopBack APIs accept (and forward) this argument and
there are means how to initialize the `options` value based on the incoming
request.

2. Code working at REST layer can access and store contextual information on the
HTTP request object.

3. An experimental component
[`loopback-context`](https://github.com/strongloop/loopback-context) uses
continuation-local-storage to provide static per-request storage that can be
accessed from anywhere inside a LoopBack application (an Express middleware,
a model method, a connector, etc.).

In LoopBack 4, extensions should use `@inject` decorators to access contextual
information. For example:

- `@inject(key)` and `@inject.getter(key)` to receive values from the context
- `@inject.setter(key)` to obtain a setter function for writing values to the
context

To keep the contextual data per-request (as opposed to per-application), the
`TRANSIENT` binding scope should be used.

Components can keep using the old `options`-based approach where it makes more
sense than Dependency Injection, typically when working with existing
`options`-based code like Repository APIs.
48 changes: 48 additions & 0 deletions docs/site/migration/components/mixins.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
---
lang: en
title: 'Migrating components contributing Model mixins'
keywords: LoopBack 4, LoopBack 3, Migration, Extensions, Components, Mixins
sidebar: lb4_sidebar
permalink: /doc/en/lb4/migration-extensions-mixins.html
---

{% include tip.html content="
Missing instructions for your LoopBack 3 use case? Please report a [Migration docs issue](https://github.com/strongloop/loopback-next/issues/new?labels=question,Migration,Docs&template=Migration_docs.md) on GitHub to let us know.
" %}

In LoopBack 3, a component contributes mixins by providing files exporting mixin
functions, for example:

```js
// lib/my-mixin.js
module.exports = myMixin(Model, options) {
// modify the target model provided in `Model`
// apply configuration as specified in `options`
};
```

In LoopBack 4, models are architecturally decoupled into 3 entities (a model, a
repository and a controller), as further explained in
[Migrating models](../models/overview.md) and
[Migrating custom model methods](../models/methods.md). As a result, most
LoopBack 3 mixins become a set of multiple mixins in LoopBack 4.

To migrate a mixin from a LoopBack 3 component to a LoopBack 4 component:

1. Follow the steps described in
[Migrating model mixins ](https://loopback.io/doc/en/lb4/migration-models-mixins.html)
to convert your mixin implementation to LB4 style. We recommend to put the
new files to `src/mixins` directory in your LB4 component project.

2. Modify your LB4 component to export the mixins - add `export` statements to
components `src/index.ts` file. For example:

```ts
// src/index.ts
export * from './mixins/my-mixin';
```

3. Update your documentation to show how to apply the new mixins in LoopBack 4
applications, use the content provided in
[Migrating model mixins ](https://loopback.io/doc/en/lb4/migration-models-mixins.html)
for inspiration.
79 changes: 79 additions & 0 deletions docs/site/migration/components/overview.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
---
lang: en
title: 'Migrating components and extensions'
keywords: LoopBack 4, LoopBack 3, Migration, Extensions, Components
sidebar: lb4_sidebar
permalink: /doc/en/lb4/migration-extensions-overview.html
redirect_from: /doc/en/lb4/migration-extensions.html
---

{% include tip.html content="
Missing instructions for your LoopBack 3 use case? Please report a [Migration docs issue](https://github.com/strongloop/loopback-next/issues/new?labels=question,Migration,Docs&template=Migration_docs.md) on GitHub to let us know.
" %}

{% include note.html content="
This is a placeholder page, the task of adding content is tracked by the
following GitHub issue:
[loopback-next#3955](https://github.com/strongloop/loopback-next/issues/3955)
" %}

In LoopBack 3, a component is essentially a function that extends and/or patches
the target application.

LoopBack 3 components can contribute:

- additional models
- new REST API endpoints (Express routes)
- mixin to be used by application models

They can also modify application's models to

- register new
[Operation Hooks](https://loopback.io/doc/en/lb3/Operation-hooks.html)
- register new [Remote Hooks](https://loopback.io/doc/en/lb3/Remote-hooks.html)
- define new relations

In LoopBack 4, a component is typically a class providing artifacts it wants to
contribute to the application. It is responsibility of the target application to
import those artifacts.

LoopBack 4 components can contribute:

- [Model and Entity classes](../../Model.md)
- [Mixins](../../Mixin.md)
- [Decorators](../../Creating-decorators.md)
- [Sequence Actions](../../Sequence.md#actions)
- [Controllers](../../Controllers.md)
- [Life cycle observers](../../Extension-life-cycle.md)
- [Repositories](../../Repositories.md)
- [Service proxies](../../Calling-other-APIs-and-Web-Services.md)
- [Servers](../../Creating-servers.md)
- [HTTP request parsers](../../Extending-request-body-parsing.md)
- Extensions for [Extension Points](../../Extension-point-and-extensions.md)
- [Booters](../../Booting-an-Application.md#custom-booters)
- [Model API builders](../../Extending-Model-API-builder.md)
- Extensions for Extension Points defined by 3rd-party component
- Any other values to be bound in `Application`'s context:
- [Classes](../../Binding.md#a-class)
- [Providers](../../Binding.md#a-provider)
- [Arbitrary bindings](../../Binding.md) (instances of `Binding` class)

As the last resort, LoopBack 4 components can also modify the target application
directly by calling `Application` APIs (this is similar to LoopBack 3 approach).

To make the migration guide easier to navigate, we split component-related
instructions into several sub-sections.

1. [Migrating component project layout](./project-layout.md) describes how to
migrate your LoopBack 3 extension project infrastructure to LoopBack 4 style
and how to update the instructions for using your component.

1. [Migrating access to current context](./current-context.md) describes how to
migrate code accessing contextual information shared by different parts of a
LoopBack application.

1. [Migrating components contributing Model mixins](./mixins) explains how to
migrate a component that's contributing Model mixins.

1. _More sections will be created as part of
[loopback-next#3955](https://github.com/strongloop/loopback-next/issues/3955)._
116 changes: 116 additions & 0 deletions docs/site/migration/components/project-layout.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
---
lang: en
title: 'Migrating component project layout'
keywords: LoopBack 4, LoopBack 3, Migration, Extensions, Components
sidebar: lb4_sidebar
permalink: /doc/en/lb4/migration-extensions-project-layout.html
---

{% include tip.html content="
Missing instructions for your LoopBack 3 use case? Please report a [Migration docs issue](https://github.com/strongloop/loopback-next/issues/new?labels=question,Migration,Docs&template=Migration_docs.md) on GitHub to let us know.
" %}

The first step on the component migration journey is to reorganize the project
files, change component's entry point and documentation for adding the component
to the target application.

## LoopBack 3 component layout & mounting

A LB3 component is implemented as a function accepting the target app object and
the configuration options.

A minimal component consists of a single `index.js` file with the following
content:

```ts
module.exports = function initializeComponent(loopbackApplication, options) {
// implementation
};
```

A component is typically added to a LB3 application by creating a new entry in
`server/component-config.json`, see
[LoopBack components](https://loopback.io/doc/en/lb3/LoopBack-components.html).

For example:

```json
{
"loopback-explorer": {
"mountPath": "/explorer"
}
}
```

This allows the component to receive configuration. App developers can provide
environment-specific configuration by using `component-config.{env}.json` files.

## LoopBack 4 layout

As explained in [Creating components](../../Creating-Components.md) and
[Using components](../../Using-components.md), a typical LoopBack 4 component is
an npm package exporting a Component class.

The component class is usually implemented inside
`src/{component-name}.component.ts` file, for example
[src/metrics.component.ts](https://github.com/strongloop/loopback-next/blob/38f10b240551227d2d030c2fe8ee206880c9e029/extensions/metrics/src/metrics.component.ts):

```ts
import {Application, Component, CoreBindings} from '@loopback/core';
import {bind, config, ContextTags, inject} from '@loopback/context';
import {MetricsBindings} from './keys';
import {DEFAULT_METRICS_OPTIONS, MetricsOptions} from './types';

@bind({tags: {[ContextTags.KEY]: MetricsBindings.COMPONENT}})
export class MetricsComponent implements Component {
constructor(
@inject(CoreBindings.APPLICATION_INSTANCE)
private application: Application,
@config()
options: MetricsOptions = DEFAULT_METRICS_OPTIONS,
) {
// ...
}
// ...
}
```

The code snippet above also shows how a LoopBack 4 component can receive
configuration and the target application object.

## Usage instructions

LoopBack 4 components are added to applications inside application constructor.

First, the application file needs to import the component class:

```ts
import {MetricsComponent} from '@loopback/extension-metrics';
```

Then in the constructor, add the component to your application:

```ts
this.component(MetricsComponent);
```

Finally, the application can configure the component by adding the following
code to its constructor:

```ts
this.configure(MetricsBindings.COMPONENT).to({
// the configuration
});
```

## Migration steps

It is not feasible to migrate a LoopBack 3 component project to a LoopBack 4
component project in a series of incremental changes done within the same
repository. We recommend to create a new project using
[`lb4 extension`](../../Extension-generator.md) CLI command and then
incrementally migrate artifacts from the original LoopBack 3 component to the
new project.

{% include note.html content="The extension project template used by `lb4 extension` is a bit outdated now, please refer to [loopback-next#5336](https://github.com/strongloop/loopback-next/issues/5336) for more details.
" %}
17 changes: 0 additions & 17 deletions docs/site/migration/extensions.md

This file was deleted.

17 changes: 15 additions & 2 deletions docs/site/sidebars/lb4_sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,7 @@ children:
url: Access-databases.html
output: 'web, pdf'
children:

- title: 'Working with data'
url: Working-with-data.html
output: 'web, pdf'
Expand Down Expand Up @@ -864,8 +864,21 @@ children:
output: 'web, pdf'

- title: 'Components and extensions'
url: migration-extensions.html
url: migration-extensions-overview.html
output: 'web, pdf'
children:

- title: 'Project layout'
url: migration-extensions-project-layout.html
output: 'web, pdf'

- title: 'Current context'
url: migration-extensions-current-context.html
output: 'web, pdf'

- title: 'Mixins'
url: migration-extensions-mixins.html
output: 'web, pdf'

- title: 'Clients (API consumers)'
url: migration-clients.html
Expand Down
Loading

0 comments on commit ded442b

Please sign in to comment.