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: Merge two directional relationships #243

Open
mikaelmattsson opened this issue Aug 22, 2022 · 5 comments
Open

Feature Request: Merge two directional relationships #243

mikaelmattsson opened this issue Aug 22, 2022 · 5 comments

Comments

@mikaelmattsson
Copy link

In our project every relationship can be accessed from both nodes, which creates a lot of extra relationships in the graph that are actually the same relationships. Ideally the relationship should be represented by arrows on both sides, or no arrows, and connected to the correct property.

A problem with this is probably that there is no way to know this by just looking at the introspection. Just because there are multiple relationships between two nodes does not mean that they are the same. A solution to this could be to add it to the description in some way, like this:

type Book {
    """
    The author. (connects to: books)
    """
    writtenBy: Author!
}

type Author {
    """
    Books the author has written. (connects to: writtenBy)
    """
    books: [Book!]!
}
@LunaticMuch
Copy link
Collaborator

Logically, you have books and authors to be cross-linked, but physically, you have a field that points to a type.
In a bigger schema with many types, fields and obviously connection, that could become complicate to navigate IMO.

@mikaelmattsson
Copy link
Author

mikaelmattsson commented Aug 24, 2022

We use Voyager to communicate to consumers and I think it is a very good use case for it.
Right now we have a schema that is 30+ types and it will grow a lot more. Looking at it now there are a lot of relationship lines everywhere and I think this could clean it up and make it easier to navigate.

Simplification of what it looks like now:
Screenshot 2022-08-24 at 11 10 09

What I would like it to look like:
Screenshot 2022-08-24 at 11 10 12

Yes in GraphQL you have a field that points to a type and thats it. But in a graph relationships sometimes have names/types that define them too. Right now there is no way to represent the name/type of the relationship by looking at it in Voyager, but if we could it would be a nice way to communicate to the consumers what the relationship actually mean. Not just communicating the GraphQL specification but also the data model underneath. Looking at the data (for example in a graph database) a relationship between two nodes is just one line and not two.

We also have a couple of these cases in our schema:
Screenshot 2022-08-24 at 11 55 10

That would better to represent like this:
Screenshot 2022-08-24 at 11 55 12

@LunaticMuch
Copy link
Collaborator

I am not disagreeing with the principle, but the tool represents your physical schema/solution, not your business (would say domain) model.
I have 1000+ types around, it's true that's messy in some cases, but it also depends on what you want to communicate and to whom. The approach I use is to use a different model, my domain model, for communicating with everybody, and voyager solves for the current technical implementation of the domain. I would not consider to collapse them in a single model anytime.

Looking at the data (for example in a graph database) a relationship between two nodes is just one line and not two.

yes and also no. Entity relationship still link, physically, fields, not table. Logically you link tables. GraphQL is not a graph database, actually has an own idea of the graph because it does not correctly (or fully) render edges, as opposed to a graph database where you have a clear notion of the edge.

@mikaelmattsson
Copy link
Author

Our API is almost CRUD and the Data model and GraphQL are pretty much seamless. But I understand that this does not feel like the purpose of this plugin. Its a shame because this plugin is pretty awesome and and I can't find any other plugin that i could use to solve this. Maybe I will create a fork in the future for this purpose.

And there is no chance that you could make the the component more pluggable in a way that could solve this?
I wish there was more options to that you could use on the component so it could be customised more.

A little of topic, but I also had to manually remove some types and properties from the introspection that I didn't want to show.

return {
  data: {
    __schema: filterIntrospection(result.data.__schema),
  },
};

And my PO wanted me to change the color/opacity on some types.

Feels like all of these could be solved with injectable callbacks, like this.

  <Voyager
    workerURI={`${process.env.PUBLIC_URL}/voyager.worker.js`}
    displayOptions={{
      hideRoot: true,
    }}
    introspection={introspectionProvider}
    typeFilter={(type: IntrospectionOutputTypeRef) => !(type.kind === 'OBJECT' && myHiddenTypes.includes(type.name))}
    fieldFilter={(field: IntrospectionField) => !myHiddenFields.includes(field.name)}
    relationshipMap={(relationship, node1, node2, schema) => { /* Return modified relationship with updated anchorsm, name, color, etc. */ }}
    typeMap={(type, schema) => { /* Return modified type with updated name, color, etc. */ }}
  />

@LunaticMuch
Copy link
Collaborator

Our API is almost CRUD and the Data model and GraphQL are pretty much seamless.

Which technically is not the right pattern. I do not think Voyager should change because an anti pattern does not get rendered well. Voyager renders as GraphQL is defined and supposed to be used, so field points to a type.

The messy set of arrows is possible even following the pattern, but in that case is intended.
Moreover, while a big model can be difficult to navigate, and this does not depend on Voyager itself, there're architectural patterns for working at different levels. Voyager renders the GraphQL schema, which is the physical solution in place.

And my PO wanted me to change the color/opacity on some types.

I will test this, I am quite curious.

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

No branches or pull requests

2 participants