Skip to content

Commit 0216321

Browse files
committed
release: 1.0.0-rc.3
1 parent d280c3d commit 0216321

File tree

7 files changed

+710
-1
lines changed

7 files changed

+710
-1
lines changed

CHANGELOG.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Changelog and release notes
22

3-
## Unreleased
3+
<!-- ## Unreleased -->
44
<!-- here goes all the unreleased changes descriptions -->
5+
## v1.0.0-rc.3
56
### Features
67
- **Breaking Change**: remove legacy array inference - now explicit array syntax (`[Item]`) is required
78
- **Breaking Change**: update `graphql-js` peer dependency to `^15.1.0`
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
---
2+
title: Bootstrapping
3+
id: version-1.0.0-rc.3-bootstrap
4+
original_id: bootstrap
5+
---
6+
7+
After creating our resolvers, type classes, and other business-related code, we need to make our app run. First we have to build the schema, then we can expose it with an HTTP server, WebSockets or even MQTT.
8+
9+
## Create Executable Schema
10+
11+
To create an executable schema from type and resolver definitions, we need to use the `buildSchema` function.
12+
It takes a configuration object as a parameter and returns a promise of a `GraphQLSchema` object.
13+
14+
In the configuration object we must provide a `resolvers` property, which can be an array of resolver classes:
15+
16+
```typescript
17+
import { FirstResolver, SecondResolver } from "../app/src/resolvers";
18+
// ...
19+
const schema = await buildSchema({
20+
resolvers: [FirstResolver, SecondResolver],
21+
});
22+
```
23+
24+
Be aware that only operations (queries, mutation, etc.) defined in the resolvers classes (and types directly connected to them) will be emitted in schema.
25+
26+
So if we have defined some object types (that implements an interface type [with disabled auto registering](interfaces.md#registering-in-schema)) but are not directly used in other types definition (like a part of an union, a type of a field or a return type of an operation), we need to provide them manually in `orphanedTypes` options of `buildSchema`:
27+
28+
```typescript
29+
import { FirstResolver, SecondResolver } from "../app/src/resolvers";
30+
import { FirstObject } from "../app/src/types";
31+
// ...
32+
const schema = await buildSchema({
33+
resolvers: [FirstResolver, SecondResolver],
34+
// here provide all the types that are missing in schema
35+
orphanedTypes: [FirstObject],
36+
});
37+
```
38+
39+
In case of defining the resolvers array somewhere else (not inline in the `buildSchema`), we need to use the `as const` syntax to inform the TS compiler and satisfy the `NonEmptyArray<T>` constraints:
40+
41+
```typescript
42+
// resolvers.ts
43+
export const resolvers = [FirstResolver, SecondResolver] as const;
44+
45+
// schema.ts
46+
import { resolvers } from "./resolvers";
47+
48+
const schema = await buildSchema({ resolvers });
49+
```
50+
51+
However, when there are several resolver classes, manual imports can be cumbersome.
52+
So we can also provide an array of paths to resolver module files instead, which can include globs:
53+
54+
```typescript
55+
const schema = await buildSchema({
56+
resolvers: [__dirname + "/modules/**/*.resolver.{ts,js}", __dirname + "/resolvers/**/*.{ts,js}"],
57+
});
58+
```
59+
60+
> Be aware that in case of providing paths to resolvers files, TypeGraphQL will emit all the operations and types that are imported in the resolvers files or their dependencies.
61+
62+
There are also other options related to advanced features like [authorization](authorization.md) or [validation](validation.md) - you can read about them in docs.
63+
64+
To make `await` work, we need to declare it as an async function. Example of `main.ts` file:
65+
66+
```typescript
67+
import { buildSchema } from "type-graphql";
68+
69+
async function bootstrap() {
70+
const schema = await buildSchema({
71+
resolvers: [__dirname + "/**/*.resolver.{ts,js}"],
72+
});
73+
74+
// other initialization code, like creating http server
75+
}
76+
77+
bootstrap(); // actually run the async function
78+
```
79+
80+
## Create an HTTP GraphQL endpoint
81+
82+
In most cases, the GraphQL app is served by an HTTP server. After building the schema we can create the GraphQL endpoint with a variety of tools such as [`graphql-yoga`](https://github.com/prisma/graphql-yoga) or [`apollo-server`](https://github.com/apollographql/apollo-server). Here is an example using [`apollo-server`](https://github.com/apollographql/apollo-server):
83+
84+
```typescript
85+
import { ApolloServer } from "apollo-server";
86+
87+
const PORT = process.env.PORT || 4000;
88+
89+
async function bootstrap() {
90+
// ... Building schema here
91+
92+
// Create the GraphQL server
93+
const server = new ApolloServer({
94+
schema,
95+
playground: true,
96+
});
97+
98+
// Start the server
99+
const { url } = await server.listen(PORT);
100+
console.log(`Server is running, GraphQL Playground available at ${url}`);
101+
}
102+
103+
bootstrap();
104+
```
105+
106+
Remember to install the `apollo-server` package from npm - it's not bundled with TypeGraphQL.
107+
108+
Of course you can use the `express-graphql` middleware, `graphql-yoga` or whatever you want 😉
109+
110+
## Create typeDefs and resolvers map
111+
112+
TypeGraphQL provides a second way to generate the GraphQL schema - the `buildTypeDefsAndResolvers` function.
113+
114+
It accepts the same `BuildSchemaOptions` as the `buildSchema` function but instead of an executable `GraphQLSchema`, it creates a typeDefs and resolversMap pair that you can use e.g. with [`graphql-tools`](https://github.com/apollographql/graphql-tools):
115+
116+
```typescript
117+
import { makeExecutableSchema } from "graphql-tools";
118+
119+
const { typeDefs, resolvers } = await buildTypeDefsAndResolvers({
120+
resolvers: [FirstResolver, SecondResolver],
121+
});
122+
123+
const schema = makeExecutableSchema({ typeDefs, resolvers });
124+
```
125+
126+
Or even with other libraries that expect the schema info in that shape, like [`apollo-link-state`](https://github.com/apollographql/apollo-link-state):
127+
128+
```typescript
129+
import { withClientState } from "apollo-link-state";
130+
131+
const { typeDefs, resolvers } = await buildTypeDefsAndResolvers({
132+
resolvers: [FirstResolver, SecondResolver],
133+
});
134+
135+
const stateLink = withClientState({
136+
// ...other options like `cache`
137+
typeDefs,
138+
resolvers,
139+
});
140+
141+
// ...the rest of `ApolloClient` initialization code
142+
```
143+
144+
Be aware that some of the TypeGraphQL features (i.a. [query complexity](complexity.md)) might not work with the `buildTypeDefsAndResolvers` approach because they use some low-level `graphql-js` features.
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
title: Browser usage
3+
id: version-1.0.0-rc.3-browser-usage
4+
original_id: browser-usage
5+
---
6+
7+
## Using classes in a client app
8+
9+
Sometimes we might want to use the classes we've created and annotated with TypeGraphQL decorators, in our client app that works in the browser. For example, reusing the args or input classes with `class-validator` decorators or the object type classes with some helpful custom methods.
10+
11+
Since TypeGraphQL is a Node.js framework, it doesn't work in a browser environment, so we may quickly get an error, e.g. `ERROR in ./node_modules/fs.realpath/index.js` or `utils1_promisify is not a function`, while trying to build our app with Webpack. To correct this, we have to configure Webpack to use the decorator shim instead of the normal module. We simply add this plugin code to our webpack config:
12+
13+
```js
14+
module.exports = {
15+
// ... the rest of the webpack config
16+
plugins: [
17+
// ... here are any other existing plugins that we already have
18+
new webpack.NormalModuleReplacementPlugin(/type-graphql$/, resource => {
19+
resource.request = resource.request.replace(/type-graphql/, "type-graphql/dist/browser-shim.js");
20+
}),
21+
];
22+
}
23+
```
24+
25+
In case of cypress, you can adapt the same webpack config trick just by applying the [cypress-webpack-preprocessor](https://github.com/cypress-io/cypress-webpack-preprocessor) plugin.
26+
27+
However, in some TypeScript projects like the ones using Angular, which AoT compiler requires that a full `*.ts` file is provided instead of just a `*.js` and `*.d.ts` files, to use this shim we have to simply set up our TypeScript configuration in `tsconfig.json` to use this file instead of a normal TypeGraphQL module:
28+
29+
```json
30+
{
31+
"compilerOptions": {
32+
"baseUrl": ".",
33+
"paths": {
34+
"type-graphql": ["./node_modules/type-graphql/dist/browser-shim.ts"]
35+
}
36+
}
37+
}
38+
```
39+
40+
Thanks to this, our bundle will be much lighter as we don't need to embed the whole TypeGraphQL library code in our app.
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
---
2+
title: Examples
3+
sidebar_label: List of examples
4+
id: version-1.0.0-rc.3-examples
5+
original_id: examples
6+
---
7+
8+
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.
9+
10+
All examples have an `examples.gql` file with sample queries/mutations/subscriptions that we can execute.
11+
12+
## Basics
13+
14+
- [Simple usage of fields, basic types and resolvers](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-usage)
15+
16+
## Advanced
17+
18+
- [Enums and unions](https://github.com/MichalLytek/type-graphql/tree/master/examples/enums-and-unions)
19+
- [Subscriptions (simple)](https://github.com/MichalLytek/type-graphql/tree/master/examples/simple-subscriptions)
20+
- [Subscriptions (using Redis)](https://github.com/MichalLytek/type-graphql/tree/master/examples/redis-subscriptions)
21+
- [Interfaces](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance)
22+
- [Extensions (metadata)](https://github.com/MichalLytek/type-graphql/tree/master/examples/extensions)
23+
24+
## Features usage
25+
26+
- [Dependency injection (IoC container)](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-container)
27+
- [Scoped containers](https://github.com/MichalLytek/type-graphql/tree/master/examples/using-scoped-container)
28+
- [Authorization](https://github.com/MichalLytek/type-graphql/tree/master/examples/authorization)
29+
- [Validation](https://github.com/MichalLytek/type-graphql/tree/master/examples/automatic-validation)
30+
- [Types inheritance](https://github.com/MichalLytek/type-graphql/tree/master/examples/interfaces-inheritance)
31+
- [Resolvers inheritance](https://github.com/MichalLytek/type-graphql/tree/master/examples/resolvers-inheritance)
32+
- [Generic types](https://github.com/MichalLytek/type-graphql/tree/master/examples/generic-types)
33+
- [Mixin classes](https://github.com/MichalLytek/type-graphql/tree/master/examples/mixin-classes)
34+
- [Middlewares and Custom Decorators](https://github.com/MichalLytek/type-graphql/tree/master/examples/middlewares-custom-decorators)
35+
- [Query complexity](https://github.com/MichalLytek/type-graphql/tree/master/examples/query-complexity)
36+
37+
## 3rd party libs integration
38+
39+
- [TypeORM (manual, synchronous) \*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typeorm-basic-usage)
40+
- [TypeORM (automatic, lazy relations) \*](https://github.com/MichalLytek/type-graphql/tree/master/examples/typeorm-lazy-relations)
41+
- [Typegoose](https://github.com/MichalLytek/type-graphql/tree/master/examples/typegoose)
42+
- [Apollo federation](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-federation)
43+
- [Apollo Engine (Apollo Cache Control) \*\*](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-engine)
44+
- [Apollo client state](https://github.com/MichalLytek/type-graphql/tree/master/examples/apollo-client)
45+
46+
_\* Note that we need to edit the TypeORM example's `index.ts` with the credentials of our local database_
47+
48+
_\*\* Note that we need to provide an `APOLLO_ENGINE_API_KEY` env variable with our own API key_

0 commit comments

Comments
 (0)