<olclass="chapter"><liclass="affix"><ahref="../index.html">Introduction</a></li><liclass="affix"><ahref="../quickstart.html">Quickstart</a></li><liclass="affix"><ahref="../types/index.html">Type System</a></li><li><ahref="../types/objects/defining_objects.html"><strongaria-hidden="true">1.</strong> Defining objects</a></li><li><olclass="section"><li><ahref="../types/objects/complex_fields.html"><strongaria-hidden="true">1.1.</strong> Complex fields</a></li><li><ahref="../types/objects/using_contexts.html"><strongaria-hidden="true">1.2.</strong> Using contexts</a></li><li><ahref="../types/objects/error_handling.html"><strongaria-hidden="true">1.3.</strong> Error handling</a></li></ol></li><li><ahref="../types/other-index.html"><strongaria-hidden="true">2.</strong> Other types</a></li><li><olclass="section"><li><ahref="../types/enums.html"><strongaria-hidden="true">2.1.</strong> Enums</a></li><li><ahref="../types/interfaces.html"><strongaria-hidden="true">2.2.</strong> Interfaces</a></li><li><ahref="../types/input_objects.html"><strongaria-hidden="true">2.3.</strong> Input objects</a></li><li><ahref="../types/scalars.html"><strongaria-hidden="true">2.4.</strong> Scalars</a></li><li><ahref="../types/unions.html"class="active"><strongaria-hidden="true">2.5.</strong> Unions</a></li></ol></li><li><ahref="../schema/schemas_and_mutations.html"><strongaria-hidden="true">3.</strong> Schemas and mutations</a></li><li><ahref="../servers/index.html"><strongaria-hidden="true">4.</strong> Adding A Server</a></li><li><olclass="section"><li><ahref="../servers/official.html"><strongaria-hidden="true">4.1.</strong> Official Server Integrations</a></li><li><olclass="section"><li><ahref="../servers/warp.html"><strongaria-hidden="true">4.1.1.</strong> Warp</a></li><li><ahref="../servers/rocket.html"><strongaria-hidden="true">4.1.2.</strong> Rocket</a></li><li><ahref="../servers/iron.html"><strongaria-hidden="true">4.1.3.</strong> Iron</a></li><li><ahref="../servers/hyper.html"><strongaria-hidden="true">4.1.4.</strong> Hyper</a></li></ol></li><li><ahref="../servers/third-party.html"><strongaria-hidden="true">4.2.</strong> Third Party Integrations</a></li></ol></li><li><ahref="../advanced/index.html"><strongaria-hidden="true">5.</strong> Advanced Topics</a></li><li><olclass="section"><li><ahref="../advanced/introspection.html"><strongaria-hidden="true">5.1.</strong> Introspection</a></li><li><ahref="../advanced/non_struct_objects.html"><strongaria-hidden="true">5.2.</strong> Non-struct objects</a></li><li><ahref="../advanced/implicit_and_explicit_null.html"><strongaria-hidden="true">5.3.</strong> Implicit and explicit null</a></li><li><ahref="../advanced/objects_and_generics.html"><strongaria-hidden="true">5.4.</strong> Objects and generics</a></li><li><ahref="../advanced/multiple_ops_per_request.html"><strongaria-hidden="true">5.5.</strong> Multiple operations per request</a></li><li><ahref="../advanced/dataloaders.html"><strongaria-hidden="true">5.6.</strong> Dataloaders</a></li><li><ahref="../advanced/subscriptions.html"><strongaria-hidden="true">5.7.</strong> Subscriptions</a></li></ol></li></ol>
<buttonid="sidebar-toggle"class="icon-button"type="button"title="Toggle Table of Contents"aria-label="Toggle Table of Contents"aria-controls="sidebar">
<inputtype="search"name="search"id="searchbar"name="searchbar"placeholder="Search this book ..."aria-controls="searchresults-outer"aria-describedby="searchresults-header">
<p>From the server's point of view, <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL unions</a> are somewhat similar to <ahref="https://spec.graphql.org/June2018/#sec-Interfaces">interfaces</a> - the main difference is that they don't contain fields on their own.</p>
<p>The most obvious and straightforward way to represent a <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> in Rust is enum. However, we also can do so either with trait or a regular struct. That's why, for implementing <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL unions</a> Juniper provides:</p>
<p>Most of the time, we just need a trivial and straightforward Rust enum to represent a <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a>.</p>
<p>In some rare situations we may want to omit exposing an enum variant in the GraphQL schema.</p>
<p>As an example, let's consider the situation where we need to bind some type parameter <code>T</code> for doing interesting type-level stuff in our resolvers. To achieve this we need to have <code>PhantomData<T></code>, but we don't want it exposed in the GraphQL schema.</p>
<blockquote>
<p><strong>WARNING</strong>:<br/>
It's the <em>library user's responsibility</em> to ensure that ignored enum variant is <em>never</em> returned from resolvers, otherwise resolving the GraphQL query will <strong>panic at runtime</strong>.</p>
<p>If some custom logic is needed to resolve a <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> variant, you may specify an external function to do so:</p>
<p>With an external resolver function we can even declare a new <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> variant where the Rust type is absent in the initial enum definition. The attribute syntax <code>#[graphql(on VariantType = resolver_fn)]</code> follows the <ahref="https://spec.graphql.org/June2018/#example-f8163">GraphQL syntax for dispatching union variants</a>.</p>
<p>Using Rust structs as <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL unions</a> is very similar to using enums, with the nuance that specifying an external resolver function is the only way to declare a <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> variant.</p>
<p>To use a Rust trait definition as a <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> you need to use the <code>#[graphql_union]</code> macro. <ahref="https://doc.rust-lang.org/stable/reference/procedural-macros.html#derive-macros">Rust doesn't allow derive macros on traits</a>, so using <code>#[derive(GraphQLUnion)]</code> on traits doesn't work.</p>
<blockquote>
<p><strong>NOTICE</strong>:<br/>
A <strong>trait has to be <ahref="https://doc.rust-lang.org/stable/reference/items/traits.html#object-safety">object safe</a></strong>, because schema resolvers will need to return a <ahref="https://doc.rust-lang.org/stable/reference/types/trait-object.html">trait object</a> to specify a <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> behind it.</p>
<p>If a <ahref="https://docs.rs/juniper/0.14.2/juniper/trait.Context.html"><code>Context</code></a> is required in a trait method to resolve a <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> variant, specify it as an argument.</p>
<p>As with enums, we may want to omit some trait methods to be assumed as <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> variants and ignore them.</p>
<p>Similarly to enums and structs, it's not mandatory to use trait methods as <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> variant resolvers. Instead, custom functions may be specified:</p>
<p>By default, <code>#[derive(GraphQLUnion)]</code> and <code>#[graphql_union]</code> macros generate code, which is generic over a <ahref="https://docs.rs/juniper/latest/juniper/trait.ScalarValue.html"><code>ScalarValue</code></a> type. This may introduce a problem when at least one of <ahref="https://spec.graphql.org/June2018/#sec-Unions">GraphQL union</a> variants is restricted to a concrete <ahref="https://docs.rs/juniper/latest/juniper/trait.ScalarValue.html"><code>ScalarValue</code></a> type in its implementation. To resolve such problem, a concrete <ahref="https://docs.rs/juniper/latest/juniper/trait.ScalarValue.html"><code>ScalarValue</code></a> type should be specified:</p>