Skip to content

Commit

Permalink
docs: feedback
Browse files Browse the repository at this point in the history
Feedback
  • Loading branch information
Yaapa Hage committed Apr 16, 2020
1 parent 6381101 commit 264d69e
Showing 1 changed file with 82 additions and 53 deletions.
135 changes: 82 additions & 53 deletions docs/site/LB3-vs-LB4-request-response-cycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ permalink: /doc/en/lb4/LB3-vs-LB4-request-response-cycle.html

The request/response cycle infrastructure and pathway are very different in
LoopBack 3 and LoopBack 4. Knowing the differences will help you migrate
LoopBack 3 apps to LoopBack 4 and implement new request/response related
LoopBack 3 applications to LoopBack 4 and implement new request/response related
features in LoopBack 4.

This document will guide you through the differences and show the LoopBack 4
Expand All @@ -19,39 +19,40 @@ equivalent, if there is any.
### Request/response infrastructure

The difference begins with the LoopBack application object itself. In
LoopBack 3, it is an instance of an Express app; in LoopBack 4, it is not.
Although LoopBack 4 uses Express as the HTTP server, it is not directly exposed
anymore.
LoopBack 3, it is an instance of an Express application; in LoopBack 4, it is
not. Although LoopBack 4 uses Express as the HTTP server, it is not directly
exposed anymore.

In LoopBack 3, Express middleware and routers, models, components, boot scripts,
and remote methods are the ways endpoints can be created on the app. Let's take
a look at how they have changed and how their functionality can be migrated in
LoopBack 4.
and remote methods are the ways endpoints can be created on the application.
Let's take a look at how they have changed and how their functionality can be
migrated in LoopBack 4.

#### Express middleware and routers

In LoopBack 3 you could add routes and load custom middleware using `app.get()`,
`app.post()`, `app.use()`, etc., just like how you do in Express.
In LoopBack 4, you cannot do it yet. However, you can
[mount a LoopBack 4](https://loopback.io/doc/en/lb4/express-with-lb4-rest-tutorial.html)
on an Express app, which would allow you to still use the familiar routing
methods.
[mount a LoopBack 4 application](./express-with-lb4-rest-tutorial.md)
on an Express application, which would allow you to still use the familiar
routing methods.

{% include tip.html content="Follow our GitHub issues
[#1293](https://github.com/strongloop/loopback-next/issues/1293)
and
[#2035](https://github.com/strongloop/loopback-next/issues/2035)
to track the progress on supporting Express middlweware in LoopBack 4." %}

If you want to mount a Express router, you can use the
If you want to mount an Express router in a LoopBack 4 application, you can use
the
[RestApplication.mountExpressRouter()](https://loopback.io/doc/en/lb4/apidocs.rest.restapplication.mountexpressrouter.html)
API.

Using [Controllers](https://loopback.io/doc/en/lb4/Controllers.html) is the
recommended way for creating custom (and REST) endpoints on your app. Its
support for
[dependency injection](https://loopback.io/doc/en/lb4/Dependency-injection.html)
and [Interceptors](https://loopback.io/doc/en/lb4/Interceptors.html) makes it a
Using [Controllers](./Controllers.md) is the
recommended way for creating custom (and REST) endpoints on your application.
Its support for
[dependency injection](./Dependency-injection.md)
and [Interceptors](./Interceptors.md) makes it a
very powerful extension mechanism.

In LoopBack 4
Expand All @@ -64,22 +65,21 @@ In LoopBack 3, models files automatically create the corresponding REST API
endpoints and the database query machinery (using the configured datasource).
In LoopBack 4, model files are limited only to describing the properties of the
data. You will have to create a corresponding
[Repository](https://loopback.io/doc/en/lb4/Repositories.html)
[Repository](./Repositories.md)
for database connectivity, and
[controllers](https://loopback.io/doc/en/lb4/Controllers.html)
[controllers](./Controllers.md)
for creating the REST API endpoint.

The fact that you have to create two more artifacts along with the model to
get a REST endpoint working might seem overly tedious at first. However, the
separation of concerns and decoupling the functionality makes the codebase
cleaner, easier to maintain, and much easier to customize functionality at
various levels. This can be better appreciated as the complexity of your app
grows.
various levels. This can be better appreciated as the complexity of your
application grows.

For those who are uncomfortable with the concept of having to creating a
repository and a controller for a model, we have a component
[@loopback/rest-crud
](https://loopback.io/doc/en/lb4/Creating-crud-rest-apis.html)
[@loopback/rest-crud](./Creating-crud-rest-apis.md)
; with a little bit of configuration, a model file is all you will need to
create the REST endpoints. Once your requirements outgrow what
`@loopback/rest-crud` provides, you can implement your REST endpoints the
Expand All @@ -94,12 +94,13 @@ In LoopBack 3, a
[component](https://loopback.io/doc/en/lb3/LoopBack-components.html)
is a simple Node.js module which exports a function with the signature
`function(app, options)`. In LoopBack 4, a
[component](https://loopback.io/doc/en/lb4/Creating-components.html)
[component](./Creating-components.md)
is a TypeScript class which can add
[servers](https://loopback.io/doc/en/lb4/Server.html),
[observers](https://loopback.io/doc/en/lb4/Life-cycle.html),
[providers](https://loopback.io/doc/en/lb4/Creating-components.html#providers),
and controllers to the app using dependency injection.
[servers](./Server.md),
[observers](./Life-cycle.md),
[providers](./Creating-components.md#providers),
and [controllers](./Controllers.md) to the application
using dependency injection.

LoopBack 3 components adding routes can be migrated to LoopBack 4 by moving the
functionality to the controller of a LoopBack 4 component.
Expand Down Expand Up @@ -156,7 +157,7 @@ in LoopBack 4 anymore.

#### Boot scripts

If you used LoopBack 3 boot scripts for adding routes to the app, it
If you used LoopBack 3 boot scripts for adding routes to the application, it
should now be moved to a standalone controller, a component, or implemented
using `app.mountExpressRouter()`.

Expand Down Expand Up @@ -187,7 +188,7 @@ export class HelloController {

{% include tip.html content="For details about migrating LoopBack 3 boot scripts
refer to
[Migrating boot scripts](https://loopback.io/doc/en/lb4/migration-boot-scripts.html)
[Migrating boot scripts](./migration-boot-scripts.md)
." %}

#### Remote methods
Expand Down Expand Up @@ -251,9 +252,9 @@ The request/response architecture has undergone a drastic change in LoopBack 4.
LoopBack 3's
[phase-based middleware routing system](https://loopback.io/doc/en/lb3/Routing.html)
is now replaced by a
[sequence handler](https://loopback.io/doc/en/lb4/apidocs.rest.defaultsequence.html)
[sequence handler](https://loopback.io/doc/en/lb4/apidocs.rest.defaultsequence.md)
that sits infront of a
[routing table](https://loopback.io/doc/en/lb4/apidocs.rest.routingtable.html).
[routing table](https://loopback.io/doc/en/lb4/apidocs.rest.routingtable.md).

In LoopBack 3, middleware are added using Express APIs and via phases in
`middleware.json` or using
Expand Down Expand Up @@ -294,21 +295,22 @@ The REST API middleware is added in the `routes` phase and error handlers in the
`final` and `final:after` phases.

The REST API middleware is responsible for creating REST API endpoints out of
the models in the app. It then uses the configured datasource for connecting
and querying the undelying database for the corresponding REST requests.
the models in the application. It then uses the configured datasource for
connecting and querying the undelying database for the corresponding REST
requests.

In LoopBack 4, the [sequence](https://loopback.io/doc/en/lb4/Sequence.html) is
the gatekeeper of all requests to the app. Every request to the app must pass
through the sequence. It identifies the responsible handler for the requested
endpoint and passes on the request to the handler.
In LoopBack 4, the [sequence](./Sequence.md) is
the gatekeeper of all requests to the application. Every request to the
application must pass through the sequence. It identifies the responsible
handler for the requested endpoint and passes on the request to the handler.

![LoopBack 4 request/response components](./imgs/lb4-req-res.png)

Unlike LoopBack 3, models in LoopBack 4 do not create REST endpoints. Use the
`lb4 controller` command to quickly generate the REST endpoints for a model.

For more details, refer to the LoopBack 4
[request/response cycle](https://loopback.io/doc/en/lb4/Request-response-cycle.html)
[request/response cycle](./Request-response-cycle.md)
doc.

#### Access to the request/response object
Expand All @@ -321,11 +323,11 @@ routers loaded using the
[app.mountExpressRouter() ](https://loopback.io/doc/en/lb4/apidocs.rest.restapplication.mountexpressrouter.html)
method, using the familiar Express middleware signature.

Controllers, services, and repositories are LoopBack 4 components that
[Controllers](./Controllers.md), [services](./Services.md),
and [repositories](./Repositories.md) are LoopBack 4 artifacts that
participate in the request/response cycle. The request and response objects can
be made available to them via
[dependency injection](https://loopback.io/doc/en/lb4/Dependency-injection.html)
.
[dependency injection](./Dependency-injection.md).

Example of accesssing the request and response object in a Controller:

Expand All @@ -349,30 +351,55 @@ export class ExampleController {

Similarly, the request and response objects can be injected into services
and respositories along with other objects from the
[context](https://loopback.io/doc/en/lb4/Context.html).
[context](./Context.md).

{% include tip.html content="It may be tempting to use an Express router
(because of familiarity) instead of a controller to add custom endpoints to the
app, but bear it in mind that controllers are way more powerful and capable than
Express routers because of their support for dependency injection and access to
the application context." %}
It may be tempting to use an Express router (because of familiarity) instead of
a controller to add custom endpoints to the application, but bear it in mind
that controllers are way more powerful and capable than Express routers because
of the following reasons:

#### Data validation
1. Support for dependency injection
2. Access to the application context
3. In-built support for parsing and validating submitted data based on the
endpoint's OpenAPI spec
4. Controller routes are included in the auto-generated OpenAPI spec document

[Interceptors](./Interceptors.md) can intercept execution of controller methods,
thus have access to the request and response objects.

#### Data coercion and validation

{% include note.html content="For a detailed explanation about validation in
LoopBack 4, refer to the
[validation doc](./Validation.md)." %}

LoopBack 3 models come with
[validation methods](https://loopback.io/doc/en/lb3/Validating-model-data.html)
. The validation rules are derived from the model definition files or are
applied by calling the validation methods in the model's JavaScript file.

In LoopBack 4, models are defined as classes whose properties decorated with the
[@property()](https://loopback.io/doc/en/lb4/Model.html#property-decorator)
[@property()](./Model.md#property-decorator)
decorator become the model's properties. Request body to an endpoint is
validated against the attributes specified in the `@property()` decorator of the
corresponding model.

Model validation methods like `validatesLengthOf()`,
`validatesLengthOf()`, etc., from LoopBack 3 can be implemented in LoopBack 4
by specifying the `jsonSchema` property in a model's property definition.
Validation methods like `validatesLengthOf()`,
`validatesLengthOf()`, etc., in LoopBack 3 can be implemented in LoopBack 4
at the REST layey by specifying the `jsonSchema` property in a model's property
definition.

{% include note.html content="
`jsonSchema` property is not a direct replacement for Model validation methods
in LoopBack 3. The former performs the validation at the REST API layer, while
the later performs the validation at the data access layer; that means, the data
validation of `jsonSchema` will not be applied if data is modifiued using
repository methods.

We are working on
[supporting data validation at the data access layer](https://github.com/strongloop/loopback-next/issues/1872)
in LoopBack 4.
" %}

Here is an example of enforcing the string length of a model property in
LoopBack 4:
Expand Down Expand Up @@ -402,6 +429,8 @@ a lot more powerful in LoopBack 4. Refer to the
[ajv documentation](https://github.com/epoberezkin/ajv#validation-keywords)
for all the possible validations for different data types." %}

#### Access to data before writing to the databases

In LoopBack 3, the `before save`
[operation hook](https://loopback.io/doc/en/lb3/Operation-hooks.html)
enable users to access the model data before it is written to the
Expand Down Expand Up @@ -437,7 +466,7 @@ Similarly, various other repository methods in LoopBack 4 can be overriden to
access the model data in the context of their operation.

{% include tip.html content="
[Interceptors](https://loopback.io/doc/en/lb4/Interceptors.html)
[Interceptors](./Interceptors.md)
may also be used to access the user submitted data in some cases." %}

## Summary
Expand Down

0 comments on commit 264d69e

Please sign in to comment.