Skip to content

GraphQL Union Types — Polymorphic Responses Without Shared Fields

DodaTech Updated 2026-06-28 3 min read

In this tutorial, you will learn about Graphql Union Types. We cover key concepts, practical examples, and best practices to help you master this topic.

GraphQL union types allow a field to return one of several different object types, enabling polymorphic responses where the returned types may have no fields in common.

What You'll Learn

  • Defining union types
  • Querying unions with inline fragments
  • Implementing __resolveType for unions

Why It Matters

Unions enable flexible search results, notification systems, and event feeds where different types of data can appear in the same field.

Code Examples

# Union type definitions
union SearchResult = User | Post | Comment | Product
union Notification = EmailNotification | PushNotification | SMSNotification
union MediaItem = Image | Video | Audio | Document

type Query {
  search(term: String!): [SearchResult!]!
  notifications(userId: ID!): [Notification!]!
  mediaLibrary: [MediaItem!]!
}
# Querying unions with inline fragments
query {
  search(term: "graphql") {
    ... on User {
      name
      email
    }
    ... on Post {
      title
      content
      author { name }
    }
    ... on Comment {
      text
      post { title }
    }
    ... on Product {
      name
      price
    }
  }
}
// Union resolver with __resolveType
const typeDefs = `
  union SearchResult = User | Post | Comment

  type User {
    id: ID!
    name: String!
    email: String!
  }

  type Post {
    id: ID!
    title: String!
    content: String!
  }

  type Comment {
    id: ID!
    text: String!
  }
`;

const resolvers = {
  SearchResult: {
    __resolveType(parent) {
      if (parent.name) return 'User';
      if (parent.title) return 'Post';
      if (parent.text) return 'Comment';
      return null; // GraphQL Error
    }
  }
};
# Python union type with Strawberry
import strawberry
from typing import Union

@strawberry.type
class User:
    id: strawberry.ID
    name: str

@strawberry.type
class Post:
    id: strawberry.ID
    title: str

SearchResult = strawberry.union(
    "SearchResult",
    (User, Post)
)

@strawberry.type
class Query:
    @strawberry.field
    def search(self, term: str) -> list[SearchResult]:
        results = []
        results.extend(search_users(term))
        results.extend(search_posts(term))
        return results

Common Mistakes

1. Using Unions When Interfaces Would Work Better

If types share common fields, use interfaces instead of unions.

2. Not Handling Unknown Types in __resolveType

Return null for unknown types to trigger clear GraphQL errors.

3. Forgetting That Unions Cannot Have Fields

Unions are just lists of possible types. They do not declare any fields.

4. Creating Overly Large Unions

Keep unions focused. A SearchResult with 20 types is hard to query.

5. Not Using Descriptive Union Names

Name unions by their purpose: SearchResult, Notification, MediaItem.

Practice Questions

  1. How do you define a union type?
  2. How do union types differ from interface types?
  3. How do you query type-specific fields on a union?
  4. What does __resolveType return for unions?
  5. Can a union include types from different services?

Answers:

  1. With the union keyword: union SearchResult = Type1 | Type2.
  2. Unions have no shared fields; interfaces define common fields.
  3. Use inline fragments with ... on TypeName.
  4. The name of the concrete object type as a string.
  5. Yes, in federated graphs, unions can span multiple services.

Challenge: Design a union type for a social media feed that can return Post, Image, Video, SharedLink, and Poll types. Implement __resolveType and write complex queries using inline fragments.

FAQ

Can a union include types that implement the same interface?

Yes. Union members can implement interfaces independently. The union does not care about interfaces.

How do I add a new type to an existing union?

Add it to the union definition: union SearchResult = User | Post | Product. Existing queries continue to work.

Can I use unions with subscriptions?

Yes. Subscription fields can return union types for events that have different payload structures.

How do unions affect code generation?

Code generators create discriminated unions or visitor patterns for union types.

Should I use unions or nullable fields?

Use unions when the type itself varies. Use nullable fields when the data is optional.

Mini Project

Build a feed system with a FeedItem union type that can return Post, Ad, Suggestion, Activity, and Announcement types. Implement the resolver with __resolveType, write queries that display each type differently, and add a new type to the union.

What's Next

Learn about input types for structured mutation arguments, then explore arguments deep dive for field arguments.

Built by the developers of DodaTech

Doda Browser, DodaZIP & Durga Antivirus Pro