Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Spike] How to do relation traversal #1952

Closed
3 tasks
dhmlau opened this issue Oct 31, 2018 · 3 comments
Closed
3 tasks

[Spike] How to do relation traversal #1952

dhmlau opened this issue Oct 31, 2018 · 3 comments
Assignees
Labels
Relations Model relations (has many, etc.) spike

Comments

@dhmlau
Copy link
Member

dhmlau commented Oct 31, 2018

Timebox to 5 days.

Description / Steps to reproduce / Feature proposal

Originated from #1352

Cross posting the description from @bajtos (#1352 (comment)):

I think we need a spike to determine how to actually implement relation traversal, because right now, a repository for source model does not necessarily know how to obtain an instance of a repository for accessing the target model.

Acceptance Criteria

Investigate how to implement relation traversal. Implementation of the following DefaultCrudRepository methods to correctly support inclusion of related models as configured via filter.include property.

  • find
  • findOne
  • findById
@dhmlau dhmlau added spike Relations Model relations (has many, etc.) labels Oct 31, 2018
@bajtos
Copy link
Member

bajtos commented Nov 6, 2018

I have posted a comment in the other issue with a proposal how to implement inclusion of related models at Repository level, see #1352 (comment)

@jannyHou
Copy link
Contributor

Thanks for all the feedback!

I understand that the best outcome of a spike is a concrete solution, but I am afraid the inclusion story is more complicated than we expect, and it would be better to create separate stories to explorer different potential approaches.

Like what @raymondfeng points out, GraphQL's query system has two features we could borrow:

  • use resolver to describe a complicated object and calculate its value
  • use different query types to describe the filter of a model

And a overall design question to consider (from @bajtos ) :

How are we going to generate JSON Schema and OpenAPI schema for payloads containing both model properties (Customer's id, name, email) and data of related model (Customer's orders, addresses, etc.). At the moment, we are leveraging @Property metadata. If we choose a different approach for describing model+relations in TypeScript, then we also need a new way how to obtain JSON Schema for such new types.

Here is a proposal of the next steps:

  • Explorer the approach "Define relation property as a resolver"
    • The prototype would be:
         import { TodoList } from './TodoList';
         class Todo extends Entity {
            @inclusion()
            TodoList: ()=>TodoList
          }
  • Explorer the approach "Use a type wrapper to prevent the circular reference problem"
    • The prototype would be:
          export type Related<T> = T | undefined;
          class Todo extends Entity {
            // ...
            todoList: Related<TodoList>;
          }
          class TodoList extends Entity {
           // ...
            todos: Related<Todo>;
          }
  • Explorer "Generate decorator based filter types"
    • Inspired by the query/mutation type in GraphQL, I am trying to define different partial model types described by decorators
    • The prototype:
          // model.ts file
         class Todo extends Entity {
           @property({name: 'id', type: 'string'})
           id: string,
           @property({name: 'desc', type: 'string'})
           desc?: string
           @inclusion()
           TodoList: ()=>TodoList
         }
         // model.query.ts file
         type TodoMutation = Pick<Todo, a union of properties decorated by @property except id>
         type TodoQuery = TodoMutation & Inclusion<Todo>
  • Explorer the approach "Define multiple model classes for different purpose"
    • Prototype:
        class Customer extends Entity {
          // ...
        }
      
        class CustomerWithRelations extends Customer {
         orders?: Order[]
        }

@jannyHou
Copy link
Contributor

closing this story and let's explorer different approaches in the follow-up story:
#2152

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Relations Model relations (has many, etc.) spike
Projects
None yet
Development

No branches or pull requests

3 participants