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

Feature Request: Relationship CRUD #14

Open
5 of 9 tasks
KennethGomez opened this issue Aug 18, 2022 · 3 comments · May be fixed by #17
Open
5 of 9 tasks

Feature Request: Relationship CRUD #14

KennethGomez opened this issue Aug 18, 2022 · 3 comments · May be fixed by #17
Assignees
Labels
kind/enhancement Feature requests or enhancements to Alchemy

Comments

@KennethGomez
Copy link
Member

KennethGomez commented Aug 18, 2022

Preliminary checklist

  • I understand that all communication must be in English
  • I read the Documentation
  • I read the Contributing guide
  • I agree to follow the Code of Conduct
  • I searched the issues and discussions but couldn't find anything (or linked relevant results below)

Problem

Right now there's no way to actually create, read, update and delete relationships for existing entities.

Solution

The solution for this issue is implementing new dynamic queries and mutations based on the database structure. Depending on the relationship type different solutions are provided.

Progress

  • One to one
  • One to many
  • Many to one
  • Many to many

One to one

Example: on this example there's an entity being Department, and another being Manager, and a relationship one to one between those two entities called DepartmentManager.

Structure

  • Entities:
    • Department
    • DepartmentManager
  • Relationships:
    • Department to DepartmentManager | NOTE: With the current system the edge name resulting from the creation through the meta API would be department_department_managers which is not accurate. To avoid these names we would have to do some kind of special namings for edges, prompting it to the user, for example, he would set from and the to collections on the meta API, if there's overlapping on the name, we would remove the overlapped word, making the resulting edge name: department _department _manager → department_managers

Edge definitions

Manager property on Department entity

{
  "name": "manager",
  "edge": "department_managers",
  "from": "departments",
  "to": "managers",
  "type": "one_to_one",
  "direction": "inbound"
}

Department property on Manager entity

{
  "name": "department",
  "edge": "department_managers",
  "from": "managers",
  "to": "departments",
  "type": "one_to_one",
  "direction": "outbound"
}

New types

type DepartmentManagerRelationship {
    _from: Department!
    _to: DepartmentManager!
}

New queries

type Query {
    getDepartmentManagerRel(where: { from: DepartmentIndexFilter!, to: DepartmentManagerIndexFilter! }): DepartmentManagerRelationship!
    getDepartmentsManagersRels(where: { from: DepartmentBoolExp!, to: DepartmentManagerBoolExp! }): [DepartmentManagerRelationship!]!
}

New mutations

type Mutation {
    # This would throw error if one of the entities already has a relationship (this is handled by ArangoDB indices),
    # because it's only one to one
    createDepartmentManagerRel(object: { from: DepartmentIndexFilter!, to: DepartmentManagerIndexFilter! }): DepartmentManagerRelationship!
    # If from is empty on _set, then the where has to have a filter on from because we're only changing one part of the 
    # relationship, otherwise, if to is empty on _set, then the where has to have a filter on to. If both are filled at least one 
    # of the filters both of the filters has to exist as they cannot have duplicates. In case both are empty throw an exception.
    updateDepartmentManagerRel(_set: { from: DepartmentIndexFilter, to: DepartmentManagerIndexFilter }, where: { from: DepartmentIndexFilter, to: DepartmentManagerIndexFilter }): DepartmentManagerRelationship!
    # At least one of the params has to be filled, in case they're not, throw an exception.
    removeDepartmentManagerRel(where: { from: DepartmentBoolExp, to: DepartmentManagerBoolExp }): DepartmentManagerRelationship!
}

Notes

  • All the unique field validation MUST be handled by ArangoDB.
  • Add validation when adding or updating a relationship to check whether the entity on from or to exists

TODO: Expand this on the issue conversation with other relationship types procedurally when implementation gets completed.

Alternatives

No response

Contribution

Yes, I will work on a PR

Keywords

graphql, relationships, integration

@KennethGomez KennethGomez added the kind/enhancement Feature requests or enhancements to Alchemy label Aug 18, 2022
@itsezc
Copy link
Member

itsezc commented Aug 18, 2022

Can you provide an example type (in GraphQL) for the Manager and Department, I'm interested to see how it would look with the relationship fields and how filtering would work between these.

@KennethGomez
Copy link
Member Author

Can you provide an example type (in GraphQL) for the Manager and Department, I'm interested to see how it would look with the relationship fields work and how filtering would work between these.

This would be, for example:

type Department {
    name: String!,
    ...
    manager: DepartmentManager
}

type DepartmentManager {
    name: String!,
    ...
    department: Department
}

Of course there's no filtering available for this as both are unique entity relationships. In case Department to DepartmentManager was OneToMany it would be like this:

type Department {
    name: String!,
    ...
    manager(where: DepartmentManagerBoolExp, limit: Int): [DepartmentManager!]
}

type DepartmentManager {
    name: String!,
    ...
    department: Department
}

@KennethGomez
Copy link
Member Author

NOTE: With the current system the edge name resulting from the creation through the meta API would be department_department_managers which is not accurate. To avoid these names we would have to do some kind of special namings for edges, prompting it to the user, for example, he would set from and the to collections on the meta API, if there's overlapping on the name, we would remove the overlapped word, making the resulting edge name: department _department _manager → department_managers

In addition to this, the resulting edge names will have __edge as suffix to prevent overlapping with existing collections, in this example, department_managers (the edge) would overlap with the entity.

So with this changes these are the new relationship definitions:

Manager property on Department entity

{
  "name": "manager",
  "edge": "department_managers__edge",
  "from": "departments",
  "to": "department_managers",
  "type": "one_to_one",
  "direction": "inbound"
}

Department property on Manager entity

{
  "name": "department",
  "edge": "department_managers__edge",
  "from": "department_managers",
  "to": "departments",
  "type": "one_to_one",
  "direction": "outbound"
}

@KennethGomez KennethGomez linked a pull request Sep 2, 2022 that will close this issue
1 task
@KennethGomez KennethGomez linked a pull request Sep 2, 2022 that will close this issue
1 task
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement Feature requests or enhancements to Alchemy
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants