Skip to content

Latest commit

 

History

History
194 lines (155 loc) · 3.65 KB

File metadata and controls

194 lines (155 loc) · 3.65 KB
title
Unions

A union type represents a set of object types. It is very similar to an interface, except that there is no requirement for common fields between the specified types.

type TextContent {
  text: String!
}

type ImageContent {
  imageUrl: String!
  height: Int!
}

union PostContent = TextContent | ImageContent

Clients can query fields returning a union like the following.

{
  postContent {
    ... on TextContent {
      text
    }
    ... on ImageContent {
      imageUrl
    }
  }
}

Learn more about unions here.

Usage

Unions can be defined like the following.

We can use a marker interface to define object types as part of a union.

[UnionType("PostContent")]
public interface IPostContent
{
}

public class TextContent : IPostContent
{
    public string Text { get; set; }
}

public class ImageContent : IPostContent
{
    public string ImageUrl { get; set; }

    public int Height { get; set; }
}

public class Query
{
    public IPostContent GetContent()
    {
        // Omitted code for brevity
    }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddGraphQLServer()
            .AddQueryType<Query>()
            .AddType<TextContent>()
            .AddType<ImageContent>();
    }
}
public class TextContent
{
    public string Text { get; set; }
}

public class TextContentType : ObjectType<TextContent>
{
}

public class ImageContent
{
    public string ImageUrl { get; set; }

    public int Height { get; set; }
}

public class ImageContentType : ObjectType<ImageContent>
{
}

public class PostContentType : UnionType
{
    protected override void Configure(IUnionTypeDescriptor descriptor)
    {
        descriptor.Name("PostContent");

        // The object types that belong to this union
        descriptor.Type<TextContentType>();
        descriptor.Type<ImageContentType>();
    }
}

public class Query
{
    public object GetContent()
    {
        // Omitted code for brevity
    }
}


public class QueryType : ObjectType<Query>
{
    protected override void Configure(IObjectTypeDescriptor<Query> descriptor)
    {
        descriptor
            .Field(f => f.GetContent(default))
            .Type<PostContentType>();
    }
}

Since the types are already registered within the union, we do not have to register them again in our Startup class.

We can use a marker interface, as in the annotation-based approach, to type our union definition: UnionType<IMarkerInterface>

public class TextContent
{
    public string Text { get; set; }
}

public class ImageContent
{
    public string ImageUrl { get; set; }

    public int Height { get; set; }
}

public class Startup
{
    public void ConfigureServices(IServiceCollection services)
    {
        services
            .AddGraphQLServer()
            .AddDocumentFromString(@"
                type Query {
                  content: PostContent
                }

                type TextContent {
                  text: String!
                }

                type ImageContent {
                  imageUrl: String!
                  height: Int!
                }

                union PostContent = TextContent | ImageContent
            ")
            .BindComplexType<TextContent>()
            .BindComplexType<ImageContent>()
            .AddResolver("Query", "content", (context) =>
            {
                // Omitted code for brevity
            });
    }
}