Skip to content

Commit 73f9fb1

Browse files
committed
docs: migrate missing files from loopback.io
1 parent eb09a44 commit 73f9fb1

22 files changed

+1205
-251
lines changed

docs/site/Application.md

Lines changed: 15 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,17 @@ tasks as a part of your setup:
3232
import {Application} from '@loopback/core';
3333
import {RestComponent, RestServer} from '@loopback/rest';
3434
import {SamoflangeController, DoohickeyController} from './controllers';
35-
import {WidgetApi} from './apidef/';
3635

3736
export class WidgetApplication extends Application {
3837
constructor() {
3938
// This is where you would pass configuration to the base constructor
4039
// (as well as handle your own!)
41-
super();
40+
super({
41+
rest: {
42+
port: 8080
43+
}
44+
});
45+
4246
const app = this; // For clarity.
4347
// You can bind to the Application-level context here.
4448
// app.bind('foo').to(bar);
@@ -47,17 +51,6 @@ export class WidgetApplication extends Application {
4751
app.controller(DoohickeyController);
4852
}
4953

50-
async start() {
51-
// This is where you would asynchronously retrieve servers, providers and
52-
// other components to configure them before launch.
53-
const server = await app.getServer(RestServer);
54-
server.bind('rest.port').to(8080);
55-
server.api(WidgetApi);
56-
// The superclass start method will call start on all servers that are
57-
// bound to the application.
58-
return await super.start();
59-
}
60-
6154
async stop() {
6255
// This is where you would do whatever is necessary before stopping your
6356
// app (graceful closing of connections, flushing buffers, etc)
@@ -191,6 +184,15 @@ export class MyApplication extends RestApplication {
191184
## Tips for application setup
192185
Here are some tips to help avoid common pitfalls and mistakes.
193186

187+
### Extend from `RestApplication` when using `RestServer`
188+
If you want to use `RestServer` from our `@loopback/rest` package, we recommend you extend
189+
`RestApplication` in your app instead of manually binding `RestServer` or
190+
`RestComponent`. `RestApplication` already uses `RestComponent` and makes
191+
useful functions in `RestServer` like `handler()` available at the app level.
192+
This means you can call these `RestServer` functions to do all of your
193+
server-level setups in the app constructor without having to explicitly retrieve
194+
an instance of your server.
195+
194196
### Use unique bindings
195197
Use binding names that are prefixed with a unique string that does not overlap
196198
with loopback's bindings. As an example, if your application is built for

docs/site/Best-practices-with-Loopback-4.md

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,21 @@ permalink: /doc/en/lb4/Best-practices-with-Loopback-4.html
88
summary:
99
---
1010

11+
{% include important.html content="
12+
The API-first approach for building LoopBack
13+
applications is not yet fully supported. Therefore, some of the sections in this
14+
page are outdated and may not work out of the box. They will be revisited after
15+
our MVP release.
16+
" %}
17+
1118
LoopBack 4 is more than just a framework: It’s an ecosystem that encourages developers to follow best practices through predefined standards. This section will walk through some important guidelines by building an example API for a catalog of products.
1219

1320
Our best practice follows an "API first" and test-driven development approach:
1421

15-
1. [**Defining and validating the API**](./Defining-and-validating-the-API.md): This section guides you through constructing your API first before any internal logic is added.
16-
2. [**Testing the API**](./Testing-the-API.md): This section describes the process of writing smoke test for your API and its spec.
17-
3. [**Defining your testing strategy**](./Defining-your-testing-strategy.md): This section discusses the advantages and the process of building a strong testing suite.
18-
4. [**Implementing features**](./Implementing-features.md): This section demonstrates how the tests for each feature of your application should be written, and how to write the logic to make these tests pass. In the example, the tests for the controller, model, repository, data source, and sequence are written and then implemented.
19-
5. [**Preparing the API for consumption**](./Preparing-the-API-for-consumption.md): This section shows how the endpoints can be physically tested using the Swagger UI.
22+
1. **Defining the API**: There are two possible approaches to take in this section
23+
- [**Defining the API using code-first approach**](./Defining-the-API-using-code-first-approach.md): This section guides you through setting up a skeleton of your application so that its full OpenAPI specification can be automatically generated.
24+
- [**Defining the API using design-first approach**](./Defining-the-API-using-design-first-approach.md): This section guides you through constructing your API first before any internal logic is added. __*Not fully supported*__
25+
- [**Testing the API**](./Testing-the-API.md): This section describes the process of writing smoke test for your API and its spec. __*Not fully supported*__
26+
2. [**Defining your testing strategy**](./Defining-your-testing-strategy.md): This section discusses the advantages and the process of building a strong testing suite.
27+
3. [**Implementing features**](./Implementing-features.md): This section demonstrates how the tests for each feature of your application should be written, and how to write the logic to make these tests pass. In the example, the tests for the controller, model, repository, data source, and sequence are written and then implemented.
28+
4. [**Preparing the API for consumption**](./Preparing-the-API-for-consumption.md): This section shows how the endpoints can be physically tested using the Swagger UI.

docs/site/Booting-an-Application.md

Lines changed: 238 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,238 @@
1+
---
2+
lang: en
3+
title: 'Booting an Application'
4+
keywords: LoopBack 4.0, LoopBack 4
5+
tags:
6+
sidebar: lb4_sidebar
7+
permalink: /doc/en/lb4/Booting-an-Application.html
8+
summary:
9+
---
10+
11+
## What does Booting an Application mean?
12+
13+
A typical LoopBack application is made up of many artifacts in different files,
14+
organized in different folders. **Booting an Application** means:
15+
16+
* Discovering artifacts automatically based on a convention (a specific folder
17+
containing files with a given suffix)
18+
* Processing those artifacts (this usually means automatically binding them to the Application's Context)
19+
20+
`@loopback/boot` provides a Bootstrapper that uses Booters to automatically
21+
discover and bind artifacts, all packaged in an easy-to-use Mixin.
22+
23+
### What is an artifact?
24+
25+
An artifact is any LoopBack construct usually defined in code as a Class. LoopBack
26+
constructs include Controllers, Repositories, Models, etc.
27+
28+
## Usage
29+
30+
### @loopback/cli
31+
32+
New projects generated using `@loopback/cli` or `lb4` are automatically enabled
33+
to use `@loopback/boot` for booting the Application using the conventions
34+
followed by the CLI.
35+
36+
### Adding to existing project
37+
38+
See [Using the BootMixin](#using-the-bootmixin) to add Boot to your Project manually.
39+
40+
---
41+
42+
The rest of this page describes the inner workings of `@loopback/boot` for advanced use
43+
cases, manual usage or using `@loopback/boot` as a standalone package (with custom
44+
booters).
45+
46+
## BootMixin
47+
48+
Boot functionality can be added to a LoopBack 4 Application by mixing it with the
49+
`BootMixin`. The Mixin adds the `BootComponent` to your Application as well as
50+
convenience methods such as `app.boot()` and `app.booters()`. The Mixin also allows
51+
Components to set the property `booters` as an Array of `Booters`. They will be bound
52+
to the Application and called by the `Bootstrapper`.
53+
54+
Since this is a convention-based Bootstrapper, it is important to set a `projectRoot`,
55+
as all other artifact paths will be resolved relative to this path.
56+
57+
_Tip_: `application.ts` will likely be at the root of your project, so its path can be
58+
used to set the `projectRoot` by using the `__dirname` variable. _(See example below)_
59+
60+
### Using the BootMixin
61+
62+
`Booter` and `Binding` types must be imported alongside `BootMixin` to allow TypeScript
63+
to infer types and avoid errors. _If using `tslint` with the `no-unused-variable` rule,
64+
you can disable it for the import line by adding `// tslint:disable-next-line:no-unused-variable`
65+
above the import statement_.
66+
67+
```ts
68+
import {BootMixin, Booter, Binding} from "@loopback/boot";
69+
70+
class MyApplication extends BootMixin(Application) {
71+
constructor(options?: ApplicationConfig) {
72+
super(options);
73+
// Setting the projectRoot
74+
this.projectRoot = __dirname;
75+
// Set project conventions
76+
this.bootOptions: BootOptions = {
77+
controllers: {
78+
dirs: ['controllers'],
79+
extensions: ['.controller.js'],
80+
nested: true,
81+
}
82+
}
83+
}
84+
}
85+
```
86+
87+
Now just call `app.boot()` from `index.ts` before starting your Application using `app.start()`.
88+
89+
#### app.boot()
90+
91+
A convenience method to retrieve the `Bootstrapper` instance bound to the
92+
Application and calls its `boot` function. This should be called before an
93+
Application's `start()` method is called. _This is an `async` function and should
94+
be called with `await`._
95+
96+
```ts
97+
class MyApp extends BootMixin(Application) {}
98+
99+
async main() {
100+
const app = new MyApp();
101+
app.projectRoot = __dirname;
102+
await app.boot();
103+
await app.start();
104+
}
105+
```
106+
107+
#### app.booters()
108+
109+
A convenience method to manually bind `Booters`. You can pass any number of `Booter`
110+
classes to this method and they will all be bound to the Application using the
111+
prefix (`booters.`) and tag (`booter`) used by the `Bootstrapper`.
112+
113+
```ts
114+
// Binds MyCustomBooter to `booters.MyCustomBooter`
115+
// Binds AnotherCustomBooter to `booters.AnotherCustomBooter`
116+
// Both will have the `booter` tag set.
117+
app.booters(MyCustomBooter, AnotherCustomBooter);
118+
```
119+
120+
## BootComponent
121+
122+
This component is added to an Application by `BootMixin` if used. This Component:
123+
124+
* Provides a list of default `booters` as a property of the component
125+
* Binds the conventional Bootstrapper to the Application
126+
127+
_If using this as a standalone component without the `BootMixin`, you will need to
128+
bind the `booters` of a component manually._
129+
130+
```ts
131+
app.component(BootComponent);
132+
```
133+
134+
## Bootstrapper
135+
136+
A Class that acts as the "manager" for Booters. The Bootstrapper is designed to be
137+
bound to an Application as a `SINGLETON`. The Bootstrapper class provides a `boot()`
138+
method. This method is responsible for getting all bound `Booters` and running
139+
their `phases`. A `phase` is a method on a `Booter` class.
140+
141+
Each `boot()` method call creates a new `Context` that sets the `app` context
142+
as its parent. This is done so each `Context` for `boot` gets a new instance of
143+
`booters` but the same context can be passed into `boot` so selective `phases` can be
144+
run in different calls of `boot`.
145+
146+
The Bootstrapper can be configured to run specific booters or boot phases
147+
by passing in `BootExecOptions`. **This is experimental and subject to change. Hence,
148+
this functionality is not exposed when calling `boot()` via `BootMixin`**.
149+
150+
To use `BootExecOptions`, you must directly call `bootstrapper.boot()` instead of `app.boot()`.
151+
You can pass in the `BootExecOptions` object with the following properties:
152+
153+
| Property | Type | Description |
154+
| ---------------- | ----------------------- | ------------------------------------------------ |
155+
| `booters` | `Constructor<Booter>[]` | Array of Booters to bind before running `boot()` |
156+
| `filter.booters` | `string[]` | Names of Booter classes that should be run |
157+
| `filter.phases` | `string[]` | Names of Booter phases to run |
158+
159+
### Example
160+
161+
```ts
162+
import { BootMixin, Booter, Binding, Bootstrapper } from "@loopback/boot";
163+
164+
class MyApp extends BootMixin(Application) {}
165+
const app = new MyApp();
166+
app.projectRoot = __dirname;
167+
168+
const bootstrapper: Bootstrapper = await this.get(
169+
BootBindings.BOOTSTRAPPER_KEY
170+
);
171+
bootstrapper.boot({
172+
booters: [MyCustomBooter],
173+
filter: {
174+
booters: ["MyCustomBooter"],
175+
phases: ["configure", "discover"] // Skip the `load` phase.
176+
}
177+
});
178+
```
179+
180+
## Booters
181+
182+
A Booter is a class that is responsible for booting an artifact. A Booter does its
183+
work in `phases` which are called by the Bootstrapper. The following Booters are
184+
a part of the `@loopback/boot` package and loaded automatically via `BootMixin`.
185+
186+
### Controller Booter
187+
188+
This Booter's purpose is to discover [Controller](Controllers.md) type Artifacts and to bind
189+
them to the Application's Context.
190+
191+
You can configure the conventions used in your
192+
project for a Controller by passing a `controllers` object on `BootOptions` property
193+
of your Application. The `controllers` object supports the following options:
194+
195+
| Options | Type | Default | Description |
196+
| ------------ | -------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- |
197+
| `dirs` | `string \| string[]` | `['controllers']` | Paths relative to projectRoot to look in for Controller artifacts |
198+
| `extensions` | `string \| string[]` | `['.controller.js']` | File extensions to match for Controller artifacts |
199+
| `nested` | `boolean` | `true` | Look in nested directories in `dirs` for Controller artifacts |
200+
| `glob` | `string` | | A `glob` pattern string. This takes precendence over above 3 options (which are used to make a glob pattern). |
201+
202+
### Repository Booter
203+
204+
This Booter's purpose is to discover [Repository](Repositories.md) type Artifacts and to bind
205+
them to the Application's Context. The use of this Booter requires `RepositoryMixin`
206+
from `@loopback/repository` to be mixed into your Application class.
207+
208+
You can configure the conventions used in your
209+
project for a Repository by passing a `repositories` object on `BootOptions` property
210+
of your Application. The `repositories` object supports the following options:
211+
212+
| Options | Type | Default | Description |
213+
| ------------ | -------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- |
214+
| `dirs` | `string \| string[]` | `['repositories']` | Paths relative to projectRoot to look in for Repository artifacts |
215+
| `extensions` | `string \| string[]` | `['.repository.js']` | File extensions to match for Repository artifacts |
216+
| `nested` | `boolean` | `true` | Look in nested directories in `dirs` for Repository artifacts |
217+
| `glob` | `string` | | A `glob` pattern string. This takes precendence over above 3 options (which are used to make a glob pattern). |
218+
219+
### Custom Booters
220+
221+
A custom Booter can be written as a Class that implements the `Booter` interface. The Class
222+
must implement methods that corresponds to a `phase` name. The `phases` are called
223+
by the Bootstrapper in a pre-determined order (unless overridden by `BootExecOptions`).
224+
The next phase is only called once the previous phase has been completed for all Booters.
225+
226+
#### Phases
227+
228+
**configure**
229+
230+
Used to configure the `Booter` with its default options.
231+
232+
**discover**
233+
234+
Used to discover the artifacts supported by the `Booter` based on convention.
235+
236+
**load**
237+
238+
Used to bind the discovered artifacts to the Application.

docs/site/Command-line-interface.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ npm install -g @loopback/cli
2020

2121
## Generating LoopBack projects
2222

23-
{% include content/lb4-project-commands.html %}
23+
{% include_relative tables/lb4-project-commands.html %}
2424

2525
## Generating LoopBack artifacts
2626

27-
{% include content/lb4-artifact-commands.html %}
27+
{% include_relative tables/lb4-artifact-commands.html %}

docs/site/Context.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,7 @@ store along with the key. For example:
132132
// app level
133133
const app = new Application();
134134
app.bind('hello').to('world'); // ContextKey='hello', ContextValue='world'
135-
console.log(app.getSync('hello')); // => 'world'
135+
console.log(app.getSync<string>('hello')); // => 'world'
136136
```
137137

138138
In this case, we bind the 'world' string ContextValue to the 'hello' ContextKey.

docs/site/Decorators.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,7 +290,7 @@ Syntax: `@inject.tag(tag: string | RegExp)`.
290290
.bind('store.locations.sj')
291291
.to('San Jose')
292292
.tag('store:location');
293-
const store: Store = ctx.getSync('store');
293+
const store = ctx.getSync<Store>('store');
294294
// `store.locations` is now `['San Francisco', 'San Jose']`
295295
```
296296

@@ -305,13 +305,13 @@ Syntax: `@inject.context()`.
305305

306306
const ctx = new Context();
307307
ctx.bind('my-component').toClass(MyComponent);
308-
const component: MyComponent = ctx.getSync('my-component');
308+
const component = ctx.getSync<MyComponent>('my-component');
309309
// `component.ctx` should be the same as `ctx`
310310
```
311311

312312
**NOTE**: It's recommended to use `@inject` with specific keys for dependency injection if possible. Use `@inject.context` only when the code need to access the current context object for advanced use cases.
313313

314-
For more information, see the [Dependency Injection](Dependency-Injection.htm) section under [LoopBack Core Concepts](Concepts.md)
314+
For more information, see the [Dependency Injection](Dependency-Injection.md) section under [LoopBack Core Concepts](Concepts.md)
315315

316316
## Authentication Decorator
317317

0 commit comments

Comments
 (0)