Skip to content

Commit

Permalink
docs(interfaces-unions): add info about support for resolveType
Browse files Browse the repository at this point in the history
  • Loading branch information
MichalLytek committed Apr 22, 2019
1 parent 69d22d3 commit 4476223
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 3 deletions.
26 changes: 24 additions & 2 deletions docs/interfaces.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ The main idea of TypeGraphQL is to create GraphQL types based on TypeScript clas

In object-oriented programming it is common to create interfaces which describe the contract that classes implementing them must adhere to. Hence, TypeGraphQL supports defining GraphQL interfaces.

## How to
Read more about the GraphQL Interface Type in the [official GraphQL docs](https://graphql.org/learn/schema/#interfaces).

## Usage

TypeScript has first class support for interfaces. Unfortunately, they only exist at compile-time, so we can't use them to build GraphQL schema at runtime by using decorators.

Expand Down Expand Up @@ -43,8 +45,28 @@ The only difference is that we have to let TypeGraphQL know that this `ObjectTyp

We can also omit the decorators since the GraphQL types will be copied from the interface definition - this way we won't have to maintain two definitions and solely rely on TypeScript type checking for correct interface implementation.

## Resolving Type

Be aware that when our object type is implementing a GraphQL interface type, **we have to return an instance of the type class** in our resolvers. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly.

We can also provide our own `resolveType` function implementation to the `@InterfaceType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, the same ways [like in unions](./unions.md), e.g.:

```typescript
@InterfaceType({
resolveType: value => {
if ("grades" in value) {
return "Student"; // schema name of the type as a string
}
return Person; // or the object type class
},
})
abstract class IPerson {
// ...
}
```

However in case of interfaces, it might be a little bit more tricky than with unions, as we might not remember all the object types that implements this particular interface.

## Examples

For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, got to [this examples folder](https://github.com/19majkel94/type-graphql/tree/master/examples/interfaces-inheritance).
For more advanced usage examples of interfaces (and type inheritance), e.g. with query returning an interface type, go to [this examples folder](https://github.com/19majkel94/type-graphql/tree/master/examples/interfaces-inheritance).
27 changes: 26 additions & 1 deletion docs/unions.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ title: Unions

Sometimes our API has to be flexible and return a type that is not specific but one from a range of possible types. An example might be a movie site's search functionality: using the provided phrase we search the database for movies but also actors. So the query has to return a list of `Movie` or `Actor` types.

Read more about the GraphQL union type in the [official docs](http://graphql.org/learn/schema/#union-types).
Read more about the GraphQL Union Type in the [official GraphQL docs](http://graphql.org/learn/schema/#union-types).

## Usage

Expand Down Expand Up @@ -60,8 +60,29 @@ class SearchResolver {
}
```

## Resolving Type

Be aware that when the query/mutation return type (or field type) is a union, we have to return a specific instance of the object type class. Otherwise, `graphql-js` will not be able to detect the underlying GraphQL type correctly when we use plain JS objects.

However, we can also provide our own `resolveType` function implementation to the `createUnionType` options. This way we can return plain objects in resolvers and then determine the returned object type by checking the shape of the data object, e.g.:

```typescript
const SearchResultUnion = createUnionType({
name: "SearchResult",
types: [Movie, Actor],
// our implementation of detecting returned object type
resolveType: value => {
if ("rating" in value) {
return Movie; // we can return object type class (the one with `@ObjectType()`)
}
if ("age" in value) {
return "Actor"; // or the schema name of the type as a string
}
return undefined;
},
});
```

**Et Voilà!** We can now build the schema and make the example query 😉

```graphql
Expand All @@ -80,3 +101,7 @@ query {
}
}
```

## Examples

More advanced usage examples of unions (and enums) are located in [this examples folder](https://github.com/19majkel94/type-graphql/tree/master/examples/enums-and-unions).

0 comments on commit 4476223

Please sign in to comment.