-
-
Notifications
You must be signed in to change notification settings - Fork 677
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
79a3c84
commit cd90856
Showing
6 changed files
with
474 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
--- | ||
title: Enums | ||
id: version-1.1.0-enums | ||
original_id: enums | ||
--- | ||
|
||
Nowadays almost all typed languages have support for enumerated types, including TypeScript. Enums limit the range of a variable's values to a set of predefined constants, which makes it easier to document intent. | ||
|
||
GraphQL also has enum type support, so TypeGraphQL allows us to use TypeScript enums in our GraphQL schema. | ||
|
||
## Creating enum | ||
|
||
Let's create a TypeScript enum. It can be a numeric or string enum - the internal values of enums are taken from the enum definition values and the public names taken from the enum keys: | ||
|
||
```typescript | ||
// implicit value 0, 1, 2, 3 | ||
enum Direction { | ||
UP, | ||
DOWN, | ||
LEFT, | ||
RIGHT, | ||
} | ||
|
||
// or explicit values | ||
enum Direction { | ||
UP = "up", | ||
DOWN = "down", | ||
LEFT = "left", | ||
RIGHT = "right", | ||
} | ||
``` | ||
|
||
To tell TypeGraphQL about our enum, we would ideally mark the enums with the `@EnumType()` decorator. However, TypeScript decorators only work with classes, so we need to make TypeGraphQL aware of the enums manually by calling the `registerEnumType` function and providing the enum name for GraphQL: | ||
|
||
```typescript | ||
import { registerEnumType } from "type-graphql"; | ||
|
||
registerEnumType(Direction, { | ||
name: "Direction", // this one is mandatory | ||
description: "The basic directions", // this one is optional | ||
}); | ||
``` | ||
|
||
In case we need to provide additional GraphQL-related config for values, like description or deprecation reason, we can use `valuesConfig` property and put the data inside it, e.g.: | ||
|
||
```typescript | ||
enum Direction { | ||
UP = "UP", | ||
DOWN = "DOWN", | ||
LEFT = "LEFT", | ||
RIGHT = "RIGHT", | ||
SIDEWAYS = "SIDEWAYS", | ||
} | ||
|
||
registerEnumType(Direction, { | ||
name: "Direction", | ||
description: "The basic directions", | ||
valuesConfig: { | ||
SIDEWAYS: { | ||
deprecationReason: "Replaced with Left or Right", | ||
}, | ||
RIGHT: { | ||
description: "The other left", | ||
}, | ||
}, | ||
}); | ||
``` | ||
|
||
This way, the additional info will be emitted in the GraphQL schema: | ||
|
||
```graphql | ||
enum Direction { | ||
UP | ||
DOWN | ||
LEFT | ||
""" | ||
The other left | ||
""" | ||
RIGHT | ||
SIDEWAYS @deprecated(reason: "Replaced with Left or Right") | ||
} | ||
``` | ||
|
||
## Using enum | ||
|
||
The last step is very important: TypeScript has limited reflection ability, so this is a case where we have to explicitly provide the enum type for object type fields, input type fields, args, and the return type of queries and mutations: | ||
|
||
```typescript | ||
@InputType() | ||
class JourneyInput { | ||
@Field(type => Direction) // it's very important | ||
direction: Direction; | ||
} | ||
``` | ||
|
||
Without this annotation, the generated GQL type would be `String` or `Float` (depending on the enum type), rather than the `ENUM` we are aiming for. | ||
|
||
With all that in place, we can use our enum directly in our code 😉 | ||
|
||
```typescript | ||
@Resolver() | ||
class SpriteResolver { | ||
private sprite = getMarioSprite(); | ||
|
||
@Mutation() | ||
move(@Arg("direction", type => Direction) direction: Direction): boolean { | ||
switch (direction) { | ||
case Direction.Up: | ||
this.sprite.position.y++; | ||
break; | ||
case Direction.Down: | ||
this.sprite.position.y--; | ||
break; | ||
case Direction.Left: | ||
this.sprite.position.x--; | ||
break; | ||
case Direction.Right: | ||
this.sprite.position.x++; | ||
break; | ||
default: | ||
// it will never be hitten ;) | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
} | ||
``` | ||
|
||
## Interoperability | ||
|
||
Enums in TypeGraphQL are designed with server side in mind - the runtime will map the string value from input into a corresponding enum value, like `"UP"` into `0`. While this is very handy e.g. for mapping database values into GraphQL API enum names, it makes it unusable on the query side because `Direction.UP` will put `0` in the query which is an invalid value (should be `UP`). | ||
|
||
So if we would like to share the types definition and use the enum on the client side app or use the enums directly on the server app e.g. in tests, we have to use the direct mapping of the enum member names with values, e.g.: | ||
|
||
```typescript | ||
enum Direction { | ||
UP = "UP", | ||
DOWN = "DOWN", | ||
LEFT = "LEFT", | ||
RIGHT = "RIGHT", | ||
} | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
--- | ||
title: Examples | ||
sidebar_label: List of examples | ||
id: version-1.1.0-examples | ||
original_id: examples | ||
--- | ||
|
||
On the [GitHub repository](https://github.com/MichalLytek/type-graphql) there are a few simple examples of how to use different TypeGraphQL features and how well they integrate with 3rd party libraries. | ||
|
||
All examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute. | ||
|
||
## Basics | ||
|
||
- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/simple-usage) | ||
|
||
## Advanced | ||
|
||
- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/enums-and-unions) | ||
- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/simple-subscriptions) | ||
- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/redis-subscriptions) | ||
- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/interfaces-inheritance) | ||
- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/extensions) | ||
|
||
## Features usage | ||
|
||
- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/using-container) | ||
- [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/using-scoped-container) | ||
- [Authorization](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/authorization) | ||
- [Validation](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/automatic-validation) | ||
- [Custom validation](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/custom-validation) | ||
- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/interfaces-inheritance) | ||
- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/resolvers-inheritance) | ||
- [Generic types](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/generic-types) | ||
- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/mixin-classes) | ||
- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/middlewares-custom-decorators) | ||
- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/query-complexity) | ||
|
||
## 3rd party libs integration | ||
|
||
- [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/typeorm-basic-usage) | ||
- [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/typeorm-lazy-relations) | ||
- [MikroORM](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/mikro-orm) | ||
- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/typegoose) | ||
- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/apollo-federation) | ||
- [Apollo Engine (Apollo Cache Control) \*\*](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/apollo-engine) | ||
- [Apollo client state](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/apollo-client) | ||
- [GraphQL Modules](https://github.com/MichalLytek/type-graphql/tree/v1.1.0/examples/graphql-modules) | ||
|
||
_\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_ | ||
|
||
_\*\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
--- | ||
title: Prisma 2 Integration | ||
sidebar_label: Prisma 2 | ||
id: version-1.1.0-prisma | ||
original_id: prisma | ||
--- | ||
|
||
TypeGraphQL provides an integration with Prisma 2 by the [`typegraphql-prisma` package](https://www.npmjs.com/package/typegraphql-prisma). | ||
|
||
It generates the type classes and CRUD resolvers based on the Prisma schema, so you can execute complex queries or mutations that corresponds to the Prisma actions, without having to write any code for that. | ||
|
||
## Overview | ||
|
||
To make use of the prisma integration, first you need to add a new generator to the `schema.prisma` file: | ||
|
||
```sh | ||
generator typegraphql { | ||
provider = "typegraphql-prisma" | ||
output = "../src/generated/typegraphql-prisma" | ||
} | ||
``` | ||
|
||
Then, after running `prisma generate` you can import the generated classes and use them to build your schema: | ||
|
||
```typescript | ||
import { User, UserRelationsResolver, UserCrudResolver } from "./generated/typegraphql-prisma"; | ||
|
||
const schema = await buildSchema({ | ||
resolvers: [CustomUserResolver, UserRelationsResolver, UserCrudResolver], | ||
validate: false, | ||
}); | ||
``` | ||
|
||
So you will be able to execute such complex query that talks with the db in just a few minutes! | ||
|
||
```graphql | ||
query GetSomeUsers { | ||
users(where: { email: { contains: "prisma" } }, orderBy: { name: desc }) { | ||
id | ||
name | ||
posts(take: 10, orderBy: { updatedAt: desc }) { | ||
published | ||
title | ||
content | ||
} | ||
} | ||
} | ||
``` | ||
|
||
## Documentation and examples | ||
|
||
To read about all the `typegraphql-prisma` features, like exposing selected Prisma actions or changing exposed model type name, as well as how to write a custom query or how to add some fields to model type, please check the docs [on the separate GitHub repository](https://github.com/MichalLytek/typegraphql-prisma/blob/main/Readme.md). | ||
|
||
You can find there also some examples and more detailed info about the installation and the configuration. |
Oops, something went wrong.