diff --git a/docs/site/LB3-vs-LB4-request-response-cycle.md b/docs/site/LB3-vs-LB4-request-response-cycle.md index 367f17ac9d49..a624e0d6be93 100644 --- a/docs/site/LB3-vs-LB4-request-response-cycle.md +++ b/docs/site/LB3-vs-LB4-request-response-cycle.md @@ -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 @@ -19,23 +19,23 @@ 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) @@ -43,15 +43,16 @@ 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 @@ -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 @@ -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. @@ -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()`. @@ -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 @@ -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 @@ -294,13 +295,14 @@ 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) @@ -308,7 +310,7 @@ 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 @@ -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: @@ -349,15 +351,27 @@ 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) @@ -365,14 +379,27 @@ LoopBack 3 models come with 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: @@ -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 @@ -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