|
|
@@ -168,3 +168,59 @@ export class FieldOverrideExampleResolver {
|
|
|
}
|
|
|
```
|
|
|
|
|
|
+## Resolving union results
|
|
|
+
|
|
|
+When dealing with operations that return a GraphQL union type, there is an extra step needed.
|
|
|
+
|
|
|
+Union types are commonly returned from mutations in the Vendure APIs. For more detail on this see the section on [ErrorResults]({{< relref "error-handling" >}}#expected-errors-errorresults). For example:
|
|
|
+
|
|
|
+```GraphQL
|
|
|
+type MyCustomErrorResult implements ErrorResult {
|
|
|
+ errorCode: ErrorCode!
|
|
|
+ message: String!
|
|
|
+}
|
|
|
+
|
|
|
+union MyCustomMutationResult = Order | MyCustomErrorResult
|
|
|
+
|
|
|
+extend type Mutation {
|
|
|
+ myCustomMutation(orderId: ID!): MyCustomMutationResult!
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+In this example, the resolver which handles the `myCustomMutation` operation will be returning either an `Order` object or a `MyCustomErrorResult` object. The problem here is that the GraphQL server has no way of knowing which one it is at run-time. Luckily Apollo Server (on which Vendure is built) has a means to solve this:
|
|
|
+
|
|
|
+> To fully resolve a union, Apollo Server needs to specify which of the union's types is being returned. To achieve this, you define a `__resolveType` function for the union in your resolver map.
|
|
|
+>
|
|
|
+> The `__resolveType` function is responsible for determining an object's corresponding GraphQL type and returning the name of that type as a string.
|
|
|
+>
|
|
|
+-- <cite>Source: [Apollo Server docs](https://www.apollographql.com/docs/apollo-server/schema/unions-interfaces/#resolving-a-union)</cite>
|
|
|
+
|
|
|
+In order to implement a `__resolveType` function as part of your plugin, you need to create a dedicated Resolver class with a single field resolver method which will look like this:
|
|
|
+
|
|
|
+```TypeScript
|
|
|
+import { Parent, ResolveField, Resolver } from '@nestjs/graphql';
|
|
|
+import { Ctx, RequestContext, ProductVariant } from '@vendure/core';
|
|
|
+
|
|
|
+@Resolver('MyCustomMutationResult')
|
|
|
+export class MyCustomMutationResultResolver {
|
|
|
+
|
|
|
+ @ResolveField()
|
|
|
+ __resolveType(value: any): string {
|
|
|
+ // If it has an "id" property we can assume it is an Order.
|
|
|
+ return value.hasOwnProperty('id') ? 'Order' : 'MyCustomErrorResult';
|
|
|
+ }
|
|
|
+}
|
|
|
+```
|
|
|
+
|
|
|
+This resolver is then passed in to your plugin metadata like any other resolver:
|
|
|
+
|
|
|
+```TypeScript
|
|
|
+@VendurePlugin({
|
|
|
+ imports: [PluginCommonModule],
|
|
|
+ shopApiExtensions: {
|
|
|
+ schema: gql` ... `,
|
|
|
+ resolvers: [/* ... */, MyCustomMutationResultResolver]
|
|
|
+ }
|
|
|
+})
|
|
|
+export class MyPlugin {}
|
|
|
+```
|