prisma1 icon indicating copy to clipboard operation
prisma1 copied to clipboard

Support union types

Open wereHamster opened this issue 8 years ago • 37 comments

union SearchResult = Human | Droid | Starship

http://graphql.org/learn/schema/#union-types

http://graphql.org/graphql-js/type/#graphqluniontype

https://medium.com/the-graphqlhub/graphql-tour-interfaces-and-unions-7dd5be35de0d

wereHamster avatar Apr 11 '17 06:04 wereHamster

This would be awesome. My current use case:

union AccessNode = Story | Document

type AccessList {
  id: ID!
  createdAt: DateTime!
  updatedAt: DateTime!
  collaborators: [User!]! @relation(name: "CollaboratorOnAccessList")
  spectators: [User!]! @relation(name: "AccessListOnUser")
  node: AccessNode
}

It should be pretty self-explanatory, but the gist is that I'd like to use the AccessList to control access to different types of entities without having several relations (like in the example above having a story and document relation field.

altschuler avatar Apr 26 '17 23:04 altschuler

I can identify these use cases for union types, are there more?

  • union type for relations (@altschuler's use case)
  • union type for queries - I believe that would be a nice combination with interfaces, imagine a query that returns all nodes of a particular interface

marktani avatar May 09 '17 14:05 marktani

Yes! Unions and interfaces would definitely rock!

checkmatez avatar May 19 '17 21:05 checkmatez

I have a similar usecase as altschuler, where I want to create Blogposts, who have a content that is a list of several contentElement types such as Text, Quote, Image, Map, ...

see also https://github.com/graphcool/feature-requests/issues/83

MrLoh avatar Jun 04 '17 16:06 MrLoh

Another use case: sorting against several different types that are related in an external context.

My use case: I have a Person type; a user can create Notes about the person; when the user sends the person a message it also logs an Interaction. I'd like to union Timeline = Note | Interaction and query against it with the usual sorting and pagination techniques.

cameronk avatar Jun 18 '17 00:06 cameronk

@marktani do you have any color on the likelihood of this getting implemented?

maxcan avatar Aug 02 '17 20:08 maxcan

This will likely be pushed out together with interface types #83. However, there's no clear timeline yet. Thanks for your feedback everyone 🙏

marktani avatar Aug 25 '17 12:08 marktani

Great to hear. Will it be released to beta users initially?

On Fri, Aug 25, 2017 at 05:00 Nilan Marktanner [email protected] wrote:

This will likely be pushed out together with interface types #83 https://github.com/graphcool/feature-requests/issues/83. However, there's no clear timeline yet. Thanks for your feedback everyone 🙏

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/graphcool/feature-requests/issues/165#issuecomment-324899000, or mute the thread https://github.com/notifications/unsubscribe-auth/AAneTGnj6c8lcM_icd-wleRd-78CsvMPks5sbrd1gaJpZM4M5qPz .

maxcan avatar Aug 25 '17 15:08 maxcan

Here's a concrete example for union queries if that helps.

We have 3 tables, all which have different data, but in a particular screen, they need to be sorted across all three and paginated together.

type Announcement implements Node {
...etc...
  title: String!
  associatedDate: DateTime!
}

type Event implements Node {
...etc...
  title: String!
  associatedDate: DateTime!
}

type Conversation implements Node {
...etc...
  name: String!
  responseRequiredBy: DateTime!
}

In SQL we could just union the things and give them a unified structure, then ORDER BY whatever we called the date filed. In graph.cool right now we've created another record that relates to all 3 so we can execute this query, but it'd be much nicer to construct this with a view rather than by needing an actual new node that denormalises the data in order to feed what shows in one screen while the rest of the nodes are actually quite distinct.

thekevinbrown avatar Aug 31 '17 13:08 thekevinbrown

I use union types for every product category as they possess different properties.

union Product = Shoes | Dress | TShirt | Suit | ...

Without union types or interfaces I can't make a type Order as the list may contain only values of one particular type:

type Order {
  ...
  products: [Product!]! @relation(name: "ProductsInOrder")
  ...
}

It also helps if with union types you'll introduce a @relation directive which can be used with all types of the union or interface:

type Shoes {
  ...
  orders: [Order!]! @relation(name: "ProductsInOrder")
  ...
}

type Dress {
  ...
  orders: [Order!]! @relation(name: "ProductsInOrder")
  ...
}

type TShirt {
  ...
  orders: [Order!]! @relation(name: "ProductsInOrder")
  ...
}

type Suit {
  ...
  orders: [Order!]! @relation(name: "ProductsInOrder")
  ...
}

welf avatar Oct 12 '17 12:10 welf

Are there any chances it'll be included in 1.0? @marktani

pie6k avatar Jan 09 '18 12:01 pie6k

Also hoping for support of unions in the near future!

joelaguero avatar Jan 13 '18 19:01 joelaguero

Any news on union/interface types?

notadamking avatar Feb 14 '18 20:02 notadamking

We are planning to add support for interfaces in the near future. We haven't started the implementation work yet, so it is too early to give a concrete timeline. Does interfaces as described in https://github.com/graphcool/prisma/issues/83 solve all your use cases?

sorenbs avatar Feb 14 '18 22:02 sorenbs

Yes, but my team also shares many of the use cases described in this thread for union types, specifically https://github.com/graphcool/prisma/issues/165#issuecomment-336125858

notadamking avatar Feb 15 '18 22:02 notadamking

+1

couturecraigj avatar Feb 25 '18 23:02 couturecraigj

Suggesting a workaround for this at https://medium.com/@tibotiber/graphql-interfaces-and-union-types-with-prisma-and-yoga-7224f9e1d9ad. Happy to get any feedback.

tibotiber avatar Apr 02 '18 01:04 tibotiber

+1

PatrickStrz avatar Apr 12 '18 14:04 PatrickStrz

How about support for unions on enums

enum BaseballType {
    SOFTBALL_PITCH
    EXIT_VELOCITY
    INFIELDER_GLOVE_TO_GLOVE
    CATCHER_POP_TIME
    HOME_TO_FIRST_RUN
    FIVE_TEN_FIVE
    TWENTY_YARD_DASH
    FORTY_YARD_DASH
    SIXTY_YARD_DASH
    NONE
}

enum BasketballType {
    FREE_THROW_RELEASE_ANGLE
    INBOUND_TIME
    REBOUND_HEIGHT
    JUMP_HEIGHT
    WINGSPAN
    FULL_COURT_RUN
    NONE
}

union HighlightType = BaseballType | BasketballType

willbenmitch avatar Apr 12 '18 14:04 willbenmitch

+1 this would be really helpful

alexbudure avatar Aug 13 '18 20:08 alexbudure

+1 I would love to see this implemented !

louismerlin avatar Sep 21 '18 06:09 louismerlin

@marktani Has there been any progress on this?

williamluke4 avatar Sep 26 '18 06:09 williamluke4

I have just published a spec that touches on this topic. We would love to hear your feedback on this one.

mavilein avatar Nov 01 '18 13:11 mavilein

I just realized that you can't even write things as simple as

type Process {
  events: [Event!]!
}

union Event = Message | Completion

type Message {
  message: String!
}

type Completion {
  exitCode: Int!
}

Because prisma complains:

$ prisma deploy
Deploying service `kumo` to stage `dev` to server `prisma-us1` 50ms

Errors:

  Process
    ✖ The field `events` has the type `[Event!]!` but there's no type or enum declaration with that name.

Deployment canceled. Please fix the above errors to continue deploying.
Read more about deployment errors here: https://bit.ly/prisma-force-flag

samuela avatar Nov 11 '18 22:11 samuela

@samuela - I'm curious if you already took a look at the spec posted by @mavilein above. It describes how we intend to implement polymorphic relations based on interfaces and union types. It would be helpful if you could let us know if this design would satisfy your needs. Thanks!

sorenbs avatar Nov 17 '18 13:11 sorenbs

Out of curiosity, why downvotes on my previous comment?

@sorenbs Thanks for sending along the spec! I wasn't aware of that. I just came across this thread after a bit of googling.

Overall, the spec looks decent and I think it would satisfy our use case. Ultimately all that I really want are algebraic data types. I don't need interfaces and unions. I just want a clean way to represent algebraic data types. In graphql/prisma that seems to be via unions. In terms of the specifics, I'm a bit confused why @discriminator is introduced. Prisma could easily handle this automatically without burdening the user.

samuela avatar Nov 18 '18 03:11 samuela

@samuela : Prisma will handle it without burdening the user. The spec says that the @discriminator directive is optional. We have the directive in there because we want to also support existing databases that will likely diverge from our defaults for mapping to the database.

mavilein avatar Nov 19 '18 09:11 mavilein

Hey @mavilein, Been waiting on this for quite a while, so happy to see some movement. Do you have any idea when we could expect this? 😄

williamluke4 avatar Nov 23 '18 19:11 williamluke4

Hi, I was wondering if there are any updates on this ?

unixisking avatar Mar 12 '19 01:03 unixisking

On scale of 1 to 10, how much progress were made? 1= not even started, 10=completed

tanekim88 avatar Mar 15 '19 05:03 tanekim88