Repository navigation
From model definition to REST API with no custom repository/controller classes #2036
Description
In LoopBack 3, it was very easy to get a fully-featured CRUD REST API with very little code: a model definition describing model properties + a model configuration specifying which datasource to use.
Let's provide the same simplicity to LB4 users too.
- User creates a model class and uses decorators to define model properties. (No change here.)
- User declaratively defines what kind of data-access patterns to provide (CRUD, KeyValue, etc.) and what datasource to use under the hood.
@loopback/bootprocesses this configuration and registers appropriate repositories & controllers with the app.
For example, to create a Product model, attach it to a db datasources and expose a CRUD REST API, all that the developer needs is to add the following two files to their project (plus any npm packages that implement this functionality):
models/product.ts:
@model()
export class Product extends Entity {
@property()
name: string;
}public-models/product.json:
{
"model": "Product",
"pattern": "Crud",
"dataSource": "db",
}Note: having config for multiple models in a single JSON file, as we do in LB 3.x, can quickly become a maintenance nightmare - see strongloop/loopback#1316. It will be better to have one config file per model.
An example file for a model using KeyValue pattern (not CRUD) - public-models/cache-entry.json:
{
"model": "CacheEntry",
"pattern": "KeyValue",
"dataSource": "redis"
}See also
-
Include related models in "GET /mymodels" results #1889:
provide a set of extensions in order to keep the simplicity of LB3, without the needed to creat e repository, controller for default CRUD actions (only if we need custom actions) ?
/cc @GuillaumeJasmin
-
Declarative Support #565 Declarative Support
Acceptance criteria
-
A new extension (npm package living in loopback-next monorepo) providing CrudController class. See [WIP] [RFC] feat: Add REST mapping for repository interfaces #740 for inspiration. --> SEE Extension: CrudRestController #2736
-
Propose how to configure public models in such way that there is one JSON file for each model, we also need to consider how to access this file from transpiled output (
distvssrc). Discuss with the wider @strongloop/loopback-next team and get an agreement. --> SEE Spike: Booter for creating REST APIs from model files #2738 (spike) -
Implement TestSandbox.writeTextFile --> SEE Implement TestSandbox.writeTextFile #3731
-
Improve
defineCrudRestControllerto create a named controller class --> SEE ImprovedefineCrudRestControllerto create a named controller class #3732 -
Add
defineCrudRepositoryClass- a helper to create a named repository class --> SEE AdddefineCrudRepositoryClass- a helper to create a named repository class #3733 -
Model API booter & builder --> SEE Model API booter & builder #3736
-
Add CrudRestApiBuilder to
@loopback/rest-crud--> SEE Add CrudRestApiBuilder to@loopback/rest-crud#3737 -
Example app showing CrudRestApiBuilder --> SEE Example app showing CrudRestApiBuilder #3738
-
A new CLI command that will ask the user for an existing model, an existing datasource, and then generate the corresponding
public-models.jsonentry. Ideally, the pattern (crud vs key-value) should be automatically inferred from the datasource config (connector type). --> SEE CLI command to expose REST API of a Model with no custom classes #2739 -
Documentation for application developers (consuming this feature) and extension developers (building custom controller/repository classes) --> SEE Docs for exposing REST API of a Model with no custom classes #2740
-
Blog post - let's write it as part of this GH issue, once all other work is done, but before the Epic is called done.
Out of scope
-
A new extension providing KeyValueController class --> SEE Extension: KeyValueRestController #2737
-
Relations, see [EPIC] From relation definition to REST API with auto-generated repository/controller classes #2483
-
Hooks and customization (both levels - controller & repository). If the behavior provided by CrudController/KeyValueController and DefaultCrudRepository/DefaultKeyValueRepository is no longer enough, then developers should migrate the model from
public-model.jsonto custom repository & controller class. -
Exposing custom methods contributed by individual connectors on top of the default CRUD/KeyValue REST API. See Expose custom remote methods contributed by CRUD connectors on top of DAO methods #2482
Activity
[-]From model definition to REST API without custom repository/controller classes[/-][+]From model definition to REST API with no repository/controller classes[/+]bajtos commentedon Dec 4, 2018
Sure, that's an option too!
However, if the model is defined in a YAML/JSON file, then there are no type definitions available and as a result, the compiler cannot check types in code using the generated model & repository - typically acceptance/integration tests using JS/TS API to setup and clean the database between the tests.
raymondfeng commentedon Dec 7, 2018
@gczobel-f5 We already have
lb4 openapicommand that generates corresponding artifacts from OpenAPI specs.To allow a set of OpenAPI specs in a folder to be discovered, we probably need to do the following:
app.boot(up to certain stage) at build time to perform code generation.npm run build:codegen.bajtos commentedon Feb 12, 2019
Cross-posting #1889 (comment)
Yes please! It's our design goal to keep LoopBack 4+ extensible and allow the community to experiment with different styles of project layout. We don't have bandwidth to implement and maintain all such extensions ourselves, but we are happy to help anybody willing to step up and write such extension themselves.
As for repositories, it's already possible to use
DefaultCrudRepositorywithout creating per-model repository classes.In #740, @raymondfeng has proposed an extension providing REST API via a base controller class
CrudControllerthat provides usual querying and CRUD operations, similar to what the controllers scaffolded bylb4 controllerdo (but without the scaffolding step).With these two buildings blocks, I imagine one can write a small piece of code accepting a model class an exposing it via REST API, see the mock-up implementation below. It's just an illustration to show what I mean, it will probably not work out of the box and may require cleanup.
[-]From model definition to REST API with no repository/controller classes[/-][+]From model definition to REST API with no 'visible' repository/controller classes[/+][-]From model definition to REST API with no 'visible' repository/controller classes[/-][+]From model definition to REST API with no repository/controller classes[/+]emonddr commentedon Mar 19, 2019
@bajtos , we need some clarification please. The title mentions the need for "no repository or controller" classes, yet controller classes are mention a few times.
9 remaining items
bajtos commentedon May 13, 2019
Moved this Epic from Q2 to Q3 because most of the stories (see my previous comment) are already assigned to Q3.
[-]From model definition to REST API with no custom repository/controller classes[/-][+][EPIC] From model definition to REST API with no custom repository/controller classes[/+][-][EPIC] From model definition to REST API with no custom repository/controller classes[/-][+]From model definition to REST API with no custom repository/controller classes[/+]dhmlau commentedon Sep 17, 2019
The tasks we've targeted for 2019Q3 is done. Moving this epic to 2019Q4 for the remaining items.
nabdelgadir commentedon Apr 14, 2020
Blog post is ready to publish; closing this EPIC as done 👍