Loopback-next: [EPIC] From relation definition to REST API with auto-generated repository/controller classes

Created on 26 Feb 2019  路  13Comments  路  Source: strongloop/loopback-next

In LoopBack 3, it is very easy to get a fully-featured relational REST API with very little code: a model definition describing model relations + a model configuration specifying which datasource to use.

Let's enhance the solution provided by #2036 to include support for relations too.

  • User creates a model class and uses decorators to define model relations. (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 - will be provided by #2036
  • @loopback/boot processes this configuration and registers appropriate repositories & controllers with the app.

Acceptance criteria

  • [ ] Enhance the solution implemented in #2036 to support all relations implemented in LB4 at the time of implementation. For example:

    • HasMany
    • BelongsTo
    • HasOne
    • HasMany through
    • ReferencesMany
  • [ ] When an unknown relation is encountered while processing model definition, we should print a descriptive warning or throw an error to abort the application.

  • [ ] For each relation not supported yet, update the existing GH issue or create a new GH issue to ensure that when we implement a new relation type, then we also implement support for declarative flavor of building the REST API.

  • [ ] Documentation

  • [ ] Blog post

Boot Migration Relations blocked epic feature feature parity needs grooming

All 13 comments

This story may need a spike to figure out how to map the relational paths to REST endpoints.

Reference story:
Hierarchical resource locator: https://github.com/strongloop/loopback-next/issues/802

/Users/{id}/orders

  • delegate to user controller
  • user controller interprets the /orders, resolve the url
  • delegate to order controller

Proposal:
Delegate the url resolve to controller, instead of defining the path pattern in relation controller

@jannyHou will create a spike.

@jannyHou, could you please create a spike? (I thought I've created one but might've mixed it up with something else). Thanks.

We should be using the same approach we already have in place for relations, where a new controller class is created for every relation. E.g. UserOrdersController to handle all endpoints in /Users/{id}/orders path space.

Per the discussion during the estimation meeting yesterday, @raymondfeng suggested to make this task as an epic and start off with one relation first.
@bajtos, if you agree with this approach, @agnes512 can make this as epic and create a task with hasMany or belongsTo as the first one to tackle.

cc @agnes512

+1 to convert this task into an epic.

Let's start with a _spike tasks_ first. Based on the work done so far, I am not sure at all about the final design, I am anticipating several obstacles that we will have to research a solution for.

@agnes512, could you please take care of that? ^^ Thanks!

Added one spike task #3896 [SPIKE] HasMany relation definition to REST API with auto-generated repository/controller classes to get the ball rolling.

Once we figure out what needs to be done with the hasMany relation, it should give us a pretty good understanding of the work required for the other relations.

@dhmlau , @bajtos . Please let me know your thoughts. thx.

@emonddr for #2855 and #3896
I think we only need one spike, yours focuses on picking one relation type as the starting point, mine focuses on figuring out a solution for the path resolving.
Let me merge mine to #3896, then discuss and find a solution for the "hasMany" relational endpoints.

Added one spike task #3896 [SPIKE] HasMany relation definition to REST API with auto-generated repository/controller classes to get the ball rolling.

Once we figure out what needs to be done with the hasMany relation, it should give us a pretty good understanding of the work required for the other relations.

馃憤 馃挴

Ping back from https://stackoverflow.com/a/64859564/69868, cross-posting my answer:

Essentially, there are two parts of the problem:

  1. Create repository artifacts for navigating to related models.

    This is IMO the easier part, since all you need to do is take the class constructor created by defineCrudRepositoryClass for the model you are trying to expose via REST API and create a subclass that will call methods like createHasManyRepositoryFactoryFor and registerInclusionResolver from the constructor.

  2. Define a controller class implementing relation-specific REST API endpoints.

    This is slightly more involved as you need to implement function that will define a new controller class with dynamically generated OpenAPI metadata for each model relation you want to expose via REST API. I would start with copy and paste of defineCrudRestController function and then reworking individual endpoints to provide navigational API for your relation. You should probably create multiple define{relation}Controller functions, one for each relation type (e.g. defineHasManyController).

Was this page helpful?
0 / 5 - 0 ratings