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(boot): Docs for @loopback/boot #631

Merged
merged 1 commit into from
Feb 28, 2018
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
4 changes: 4 additions & 0 deletions _data/sidebars/lb4_sidebar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,10 @@ children:
url: Dependency-injection.html
output: 'web, pdf'

- title: 'Booting an Application'
url: Booting-an-Application.html
output: 'web, pdf'

- title: 'Controllers'
url: Controllers.html
output: 'web, pdf'
Expand Down
238 changes: 238 additions & 0 deletions pages/en/lb4/Booting-an-Application.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,238 @@
---
lang: en
title: 'Booting an Application'
keywords: LoopBack 4.0, LoopBack 4
tags:
sidebar: lb4_sidebar
permalink: /doc/en/lb4/Booting-an-Application.html
summary:
---

## What does Booting an Application mean?

A typical LoopBack application is made up of many artifacts in different files,
organized in different folders. **Booting an Application** means:

* Discovering artifacts automatically based on a convention (a specific folder
containing files with a given suffix)
* Processing those artifacts (this usually means automatically binding them to the Application's Context)

`@loopback/boot` provides a Bootstrapper that uses Booters to automatically
discover and bind artifacts, all packaged in an easy-to-use Mixin.

### What is an artifact?

An artifact is any LoopBack construct usually defined in code as a Class. LoopBack
constructs include Controllers, Repositories, Models, etc.

## Usage

### @loopback/cli

New projects generated using `@loopback/cli` or `lb4` are automatically enabled
to use `@loopback/boot` for booting the Application using the conventions
followed by the CLI.

### Adding to existing project

See [Using the BootMixin](#using-the-bootmixin) to add Boot to your Project manually.

---

The rest of this page describes the inner workings of `@loopback/boot` for advanced use
cases, manual usage or using `@loopback/boot` as a standalone package (with custom
booters).

## BootMixin

Boot functionality can be added to a LoopBack 4 Application by mixing it with the
`BootMixin`. The Mixin adds the `BootComponent` to your Application as well as
convenience methods such as `app.boot()` and `app.booters()`. The Mixin also allows
Components to set the property `booters` as an Array of `Booters`. They will be bound
to the Application and called by the `Bootstrapper`.

Since this is a convention-based Bootstrapper, it is important to set a `projectRoot`,
as all other artifact paths will be resolved relative to this path.

_Tip_: `application.ts` will likely be at the root of your project, so its path can be
used to set the `projectRoot` by using the `__dirname` variable. _(See example below)_

### Using the BootMixin

`Booter` and `Binding` types must be imported alongside `BootMixin` to allow TypeScript
to infer types and avoid errors. _If using `tslint` with the `no-unused-variable` rule,
you can disable it for the import line by adding `// tslint:disable-next-line:no-unused-variable`
above the import statement_.

```ts
import {BootMixin, Booter, Binding} from "@loopback/boot";

class MyApplication extends BootMixin(Application) {
constructor(options?: ApplicationConfig) {
super(options);
// Setting the projectRoot
this.projectRoot = __dirname;
// Set project conventions
this.bootOptions: BootOptions = {
controllers: {
dirs: ['controllers'],
extensions: ['.controller.js'],
nested: true,
}
}
}
}
```

Now just call `app.boot()` from `index.ts` before starting your Application using `app.start()`.

#### app.boot()

A convenience method to retrieve the `Bootstrapper` instance bound to the
Application and calls its `boot` function. This should be called before an
Application's `start()` method is called. _This is an `async` function and should
be called with `await`._

```ts
class MyApp extends BootMixin(Application) {}

async main() {
const app = new MyApp();
app.projectRoot = __dirname;
await app.boot();
await app.start();
}
```

#### app.booters()

A convenience method to manually bind `Booters`. You can pass any number of `Booter`
classes to this method and they will all be bound to the Application using the
prefix (`booters.`) and tag (`booter`) used by the `Bootstrapper`.

```ts
// Binds MyCustomBooter to `booters.MyCustomBooter`
// Binds AnotherCustomBooter to `booters.AnotherCustomBooter`
// Both will have the `booter` tag set.
app.booters(MyCustomBooter, AnotherCustomBooter);
```

## BootComponent

This component is added to an Application by `BootMixin` if used. This Component:

* Provides a list of default `booters` as a property of the component
* Binds the conventional Bootstrapper to the Application

_If using this as a standalone component without the `BootMixin`, you will need to
bind the `booters` of a component manually._

```ts
app.component(BootComponent);
```

## Bootstrapper

A Class that acts as the "manager" for Booters. The Bootstrapper is designed to be
bound to an Application as a `SINGLETON`. The Bootstrapper class provides a `boot()`
method. This method is responsible for getting all bound `Booters` and running
their `phases`. A `phase` is a method on a `Booter` class.

Each `boot()` method call creates a new `Context` that sets the `app` context
as its parent. This is done so each `Context` for `boot` gets a new instance of
`booters` but the same context can be passed into `boot` so selective `phases` can be
run in different calls of `boot`.

The Bootstrapper can be configured to run specific booters or boot phases
by passing in `BootExecOptions`. **This is experimental and subject to change. Hence,
this functionality is not exposed when calling `boot()` via `BootMixin`**.

To use `BootExecOptions`, you must directly call `bootstrapper.boot()` instead of `app.boot()`.
You can pass in the `BootExecOptions` object with the following properties:

| Property | Type | Description |
| ---------------- | ----------------------- | ------------------------------------------------ |
| `booters` | `Constructor<Booter>[]` | Array of Booters to bind before running `boot()` |
| `filter.booters` | `string[]` | Names of Booter classes that should be run |
| `filter.phases` | `string[]` | Names of Booter phases to run |

### Example

```ts
import { BootMixin, Booter, Binding, Bootstrapper } from "@loopback/boot";

class MyApp extends BootMixin(Application) {}
const app = new MyApp();
app.projectRoot = __dirname;

const bootstrapper: Bootstrapper = await this.get(
BootBindings.BOOTSTRAPPER_KEY
);
bootstrapper.boot({
booters: [MyCustomBooter],
filter: {
booters: ["MyCustomBooter"],
phases: ["configure", "discover"] // Skip the `load` phase.
}
});
```

## Booters

A Booter is a class that is responsible for booting an artifact. A Booter does its
work in `phases` which are called by the Bootstrapper. The following Booters are
a part of the `@loopback/boot` package and loaded automatically via `BootMixin`.

### Controller Booter

This Booter's purpose is to discover [Controller](http://loopback.io/doc/en/lb4/Controllers.html) type Artifacts and to bind
them to the Application's Context.

You can configure the conventions used in your
project for a Controller by passing a `controllers` object on `BootOptions` property
of your Application. The `controllers` object supports the following options:

| Options | Type | Default | Description |
| ------------ | -------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- |
| `dirs` | `string \| string[]` | `['controllers']` | Paths relative to projectRoot to look in for Controller artifacts |
| `extensions` | `string \| string[]` | `['.controller.js']` | File extensions to match for Controller artifacts |
| `nested` | `boolean` | `true` | Look in nested directories in `dirs` for Controller artifacts |
| `glob` | `string` | | A `glob` pattern string. This takes precendence over above 3 options (which are used to make a glob pattern). |

### Repository Booter

This Booter's purpose is to discover [Repository]() type Artifacts and to bind
them to the Application's Context. The use of this Booter requires `RepositoryMixin`
from `@loopback/repository` to be mixed into your Application class.

You can configure the conventions used in your
project for a Repository by passing a `repositories` object on `BootOptions` property
of your Application. The `repositories` object supports the following options:

| Options | Type | Default | Description |
| ------------ | -------------------- | -------------------- | ------------------------------------------------------------------------------------------------------------- |
| `dirs` | `string \| string[]` | `['repositories']` | Paths relative to projectRoot to look in for Repository artifacts |
| `extensions` | `string \| string[]` | `['.repository.js']` | File extensions to match for Repository artifacts |
| `nested` | `boolean` | `true` | Look in nested directories in `dirs` for Repository artifacts |
| `glob` | `string` | | A `glob` pattern string. This takes precendence over above 3 options (which are used to make a glob pattern). |

### Custom Booters

A custom Booter can be written as a Class that implements the `Booter` interface. The Class
must implement methods that corresponds to a `phase` name. The `phases` are called
by the Bootstrapper in a pre-determined order (unless overridden by `BootExecOptions`).
The next phase is only called once the previous phase has been completed for all Booters.

#### Phases

**configure**

Used to configure the `Booter` with its default options.

**discover**

Used to discover the artifacts supported by the `Booter` based on convention.

**load**

Used to bind the discovered artifacts to the Application.
34 changes: 18 additions & 16 deletions pages/en/lb4/Concepts.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,22 +10,24 @@ summary:

LoopBack 4 introduces some new concepts that are important to understand:

- [**Application**](Application.html): In LoopBack 4, the Application class is
the central class for setting up all of your module’s components, controllers,
servers and bindings. The Application class extends [Context](Context.html), and
provides the controls for starting and stopping itself and its associated
servers.
- [**Server**](Server.html): Represents implementation for inbound transports and/or protocols such as REST over http, gRPC over http2, and graphQL over https. It typically listens for requests on a specific port, handle them, and return appropriate responses.
- [**Context**](Context.html): An abstraction of all state and dependencies in your application, that LoopBack uses to “manage” everything. It's a global registry for everything in your app (configurations, state, dependencies, classes, and so on).
- [**Dependency Injection**](Dependency-injection.html): Technique that separates the construction of dependencies of a class or function from its behavior, to keep the code loosely coupled.
- [**Controller**](Controllers.html): Class that implements operations defined by application’s REST API. It implements an application’s business logic and acts as a bridge between the HTTP/REST API and domain/database models. A Controller operates only on processed input and abstractions of backend services / databases.
- [**Route**](Routes.html): Mapping between your API specification and an Operation (JavaScript implementation). It tells LoopBack which function to invoke() given an HTTP request.
- [**Sequence**](Sequence.html): A stateless grouping of [Actions](Sequence.html#actions) that control how a Server responds to requests.
- [**Model**](Model.html): Represents the definition of a model in LoopBack, with respect to the datasource juggler. The `@loopback/repository` module provides special decorators for adding metadata to TypeScript/JavaScript classes to use them with the legacy implementation of Datasource Juggler. In addition, `@loopback/repository-json-schema` module uses the decorators' metadata to build a matching JSON Schema.
- [**Repository**](Repositories.html): Type of Service that represents a collection of data within a DataSource.
- [**Decorator**](Decorators.html): Enables you to annotate or modify your class declarations and members with metadata.
- **Component**: A package that bundles one or more Loopback extensions.
- See [Using components](Using-components.html) and [Creating components](Creating-components.html) for more information.
* [**Application**](Application.html): In LoopBack 4, the Application class is
the central class for setting up all of your module’s components, controllers,
servers and bindings. The Application class extends [Context](Context.html), and
provides the controls for starting and stopping itself and its associated
servers.
* [**Server**](Server.html): Represents implementation for inbound transports and/or protocols such as REST over http, gRPC over http2, and graphQL over https. It typically listens for requests on a specific port, handle them, and return appropriate responses.
* [**Context**](Context.html): An abstraction of all state and dependencies in your application, that LoopBack uses to “manage” everything. It's a global registry for everything in your app (configurations, state, dependencies, classes, and so on).
* [**Dependency Injection**](Dependency-injection.html): Technique that separates the construction of dependencies of a class or function from its behavior, to keep the code loosely coupled.
* [**Booting an Application**](Booting-an-Application.html): A convention-based
bootstrapper that can find and bind artifacts such as Controllers, Repositories, etc.
* [**Controller**](Controllers.html): Class that implements operations defined by application’s REST API. It implements an application’s business logic and acts as a bridge between the HTTP/REST API and domain/database models. A Controller operates only on processed input and abstractions of backend services / databases.
* [**Route**](Routes.html): Mapping between your API specification and an Operation (JavaScript implementation). It tells LoopBack which function to invoke() given an HTTP request.
* [**Sequence**](Sequence.html): A stateless grouping of [Actions](Sequence.html#actions) that control how a Server responds to requests.
* [**Model**](Model.html): Represents the definition of a model in LoopBack, with respect to the datasource juggler. The `@loopback/repository` module provides special decorators for adding metadata to TypeScript/JavaScript classes to use them with the legacy implementation of Datasource Juggler. In addition, `@loopback/repository-json-schema` module uses the decorators' metadata to build a matching JSON Schema.
* [**Repository**](Repositories.html): Type of Service that represents a collection of data within a DataSource.
* [**Decorator**](Decorators.html): Enables you to annotate or modify your class declarations and members with metadata.
* **Component**: A package that bundles one or more Loopback extensions.
* See [Using components](Using-components.html) and [Creating components](Creating-components.html) for more information.

{% include note.html title="Review Note" content="_Perhaps this should include some of the material in <a href='Thinking-in-LoopBack.html'> Thinking in LoopBack</a>_.
" %}