Skip to content

feat(repository): introduce resolver and hasMany key inferrence with belongsTo decorator AND add belongsTo repository#1618

Closed
shimks wants to merge 6 commits intomasterfrom
belongsTo
Closed

feat(repository): introduce resolver and hasMany key inferrence with belongsTo decorator AND add belongsTo repository#1618
shimks wants to merge 6 commits intomasterfrom
belongsTo

Conversation

@shimks
Copy link
Copy Markdown
Contributor

@shimks shimks commented Aug 17, 2018

1st and 2nd commit: Type resolver and keyTo inferrence

There is an issue with relation and decorators where model resolution doesn't occur properly. A short example to illustrate the problem:

class Customer {
id: number;
@hasMany(Order) orders: Order[];
}
// in another file
class Order {
@belongsTo(Customer) customerId: number;
}

When Customer is being defined, Order will be read and be attempted to be defined. As Order is being defined, it comes across Customer which has yet to be defined, so the metadata being stored by the decorators is incomplete at the time it's being stored.

The work around for this is to introduce a resolver; a resolver is a function that would return the given model when called. So instead of passing in the Models themselves these decorators, you would pass in their resolver instead: @hasMany(() => Order) and @belongsTo(() => Customer).

Another feature included in these commits is automatic building of hasMany metadata based on existing metadata on belongsTo. More specifically, keyTo is inferred from the name of the property key in which belongsTo metadata exists.

In summary, this PR introduces:

  • logic to detect circular dependency (only with @hasMany and @property.array)
  • keyTo inference from the key decorated by @belongsTo

3rd commit: belongsTo repository

There is a problem where if belongsTo and hasMany relations are defined on the repositories, our context system will throw an error due to the cyclic dependence the relations create. To illustrate the example in a dirty dirty code snippet:

// ... customer repo constructor
constructor(@repository(OrderRepository) orderRepo)
// ... order repo constructor
constructor(@repository(CustomerRepository) customerRepo)

Take an event where customer repository needs to be instantiated. An injection on orderRepo will attempted to be made and an order repository will be instantiated. When an order repository is being instantiated, a customer repository needs to be injected, and therefore a circular dependency is established.

The solution to solving the dependency is to use a resolver like we did for the commits before. Take a look at this code snippet and this to see how the UX would look like. I'll probably work on introducing a decorator that won't promisify the repositories here.

related to #1361

Things that have not been done:

  • Create a decorator to replace @inject.getter usage in our relation repositories
  • Extraction of common code between hasMany and belongsTo
  • Extensive test coverage
  • License headers
  • Docs and TSDocs

Checklist

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants