Prisma1: Introducing a new @edge Type attribute

Created on 8 Oct 2017  路  11Comments  路  Source: prisma/prisma1

Proposal: the @edge Type attribute

Background

You can define a relationship between two Types using the @relation attribute. But defining a relation like this has limited functionality. If you want to add additional information to the relation, you need to create an intermediate Type to store this information. This intermediate type would have two relations to each of the Types you want to connect.

Graph terminology

The solution to create an intermediate Type is a well known one. It's used in almost every RDBMS database, both to model many-to-many relationships, and to add additional information to a relationship. However, it doesn't really translate well to a Graph. In a Graph, this additional information belongs to the _edge_ between two nodes. The Relay endpoint uses that concept.

node vs edge

The @edge attribute

This is where the @edge attribute comes in. It can be used to decorate an intermediate Type. Doing so will change the way the schema is translated for the Relay endpoint. All the scalar fields on a Type move to the edge, and the node connects directly to the Type on the other end of the intermediate Type.

Benefits

The resulting endpoint will more naturally follow the Graph principles, and will effectively bridge the gap between the database oriented Graphcool schema structure, and the Graph oriented Relay endpoint.

Challenges

Using the @edge attribute will mean additional validation is needed on the intermediate Type. If the intermediate Type contains exactly two relation fields, it's easy to determine what the 'edge' is. If it contains additional relation fields (for example, a lookup field to another Type), it might be needed to specify the fields on the attribute. The added benefit from that is that it would allow you to specify the direction of the relationship.

Example schema

type Car {
   owner: CarOwner! @relation(name: 'Car')
}

type CarOwner @edge(from: 'car', to: 'owner') {
   car: Car! @relation(name: 'Car')
   owner: User! @relation(name: 'Owner')
   since: DateTime!
}

type User {
   cars: [CarOwner!]! @relation(name: 'Owner')
}

Example Relay API query

_TODO_

kindiscussion rf0-needs-spec

Most helpful comment

@marktani will there be any movement on this? I would (of course) be open to helping out.

All 11 comments

Does edge have any concept about ordering?
I need to capture ordered relationships too.

@baerrach order, or position, would simply be a field to add on the intermediate Type, like you would already do now if you want to achieve ordering. What this proposal does, is add that information where it belongs, on the edge.

@marktani will there be any movement on this? I would (of course) be open to helping out.

I'm also interested about this feature +1

Just chiming in to see if there's been any work on this. Weighted graphs & the ability to store relationship metadata would extremely useful

Is there a clearly documented FAQ on this? The purported FAQ link in another issue (https://github.com/prismagraphql/prisma/issues/116) is broken as well as a link to another issue. This is something that is must for me but I can't find an example of a satisfactory workaround. Very interested in seeing this materialize!

Same. FAQ 404's and edges (or a slick workaround pattern) ~are almost~ were a deal breaker for us... :(

~Open to a PR for introducing the @edge proposal? (it's nice)~ (not interested anymore)

+1. Currently building a many-to-many relation with extra column is a disaster. This @edge proposal would be a life saver~!

I was a bit concerned about choosing Prisma because of the lack of extra columns in many-to-many relations. It will be amazing to have this feature 馃憤馃拵

+1 for that feature.

This issue has been superseded by #3406.

Note that this original issue was created under the assumption that Prisma's GraphQL API will be consumed by frontend applications, which is no longer the case (as Prisma's GraphQL API is now mostly an implementation detail for the Prisma client).

With #3406 it will be possible to either explicitly control when to use many-to-many tables or simply create an intermediate type which contains relations to both sides and stores additional fields/columns.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

schickling picture schickling  路  3Comments

nikolasburk picture nikolasburk  路  3Comments

jannone picture jannone  路  3Comments

tbrannam picture tbrannam  路  3Comments

MitkoTschimev picture MitkoTschimev  路  3Comments