Skip to content

Commit

Permalink
Merge branch 'master' into feature/recursive-merge-schemas
Browse files Browse the repository at this point in the history
  • Loading branch information
ardatan committed Mar 18, 2019
2 parents 9f97cf8 + e9831d4 commit de850fb
Show file tree
Hide file tree
Showing 38 changed files with 2,105 additions and 1,067 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ jobs:
ignore:
- gh-pages
docker:
- image: circleci/node:10.15.1-browsers-legacy
- image: circleci/node:10.15.3-browsers-legacy
steps:
- checkout
- restore_cache:
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
- **[Writing a GraphQL TypeScript project w/ GraphQL-Modules and GraphQL-Code-Generator](https://medium.com/the-guild/writing-strict-typed-graphql-typescript-project-w-graphql-modules-and-graphql-code-generator-c22f6caa17b8)**
- **[Authentication and Authorization in GraphQL (and how GraphQL-Modules can help)](https://medium.com/the-guild/authentication-and-authorization-in-graphql-and-how-graphql-modules-can-help-fadc1ee5b0c2)**
- **[Authentication with AccountsJS & GraphQL Modules](https://medium.com/the-guild/authentication-with-accountsjs-graphql-modules-e0fb9799a9da)**

- **[Manage Circular Imports Hell in GraphQL-Modules](https://medium.com/the-guild/manage-circular-imports-hell-with-graphql-modules-4b1611dee781)**

## Highlights

Expand All @@ -35,9 +35,9 @@ To install graphql-modules, use the following:

```sh
$ npm install @graphql-modules/core

# Or, with Yarn

$ yarn add @graphql-modules/core
```

Expand Down Expand Up @@ -65,13 +65,13 @@ const module = new GraphQLModule({
title: String
author: User
}
type Query {
posts: [Post]
}
`,
resolvers: blogResolvers,
imports: [UserModule],
imports: [UserModule]
});
```

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
id: integrate-with-apollo-server
title: Integrate With Apollo-Server
sidebar_label: Apollo-Server
sidebar_label: Integrate With Apollo-Server
---

GraphQLModules comes with a built-in support for **[Apollo-Server](https://www.apollographql.com/docs/apollo-server/getting-started.html)**.
Expand All @@ -18,14 +18,20 @@ Then, create a new instance of `ApolloServer`, and use your `GraphQLModule` inst
import { GraphQLModule } from '@graphql-modules/core';
import { ApolloServer } from 'apollo-server';

const { schema, context } = new GraphQLModule({
const AppModule = new GraphQLModule({
/*...*/
});

const server = new ApolloServer({
schema,
context,
/*...*/
schema: AppModule.schema,
context: session => session,
})
// or use `modules` in `ApolloServer`
const server = new ApolloServer({
modules: [
AppModule
],
context: session => session,
});

server.listen().then(({ url }) => {
Expand Down
3 changes: 1 addition & 2 deletions docs/guides/data-sources.md
Original file line number Diff line number Diff line change
Expand Up @@ -115,11 +115,10 @@ As described in Apollo Server docs, GraphQL-Modules also uses in-memory caching
You can share GraphQL-Modules cache mechanism with your GraphQL Server;

```typescript
const { schema, context, cache } = YourGraphQLModule;
const { schema, cache } = YourGraphQLModule;

new ApolloServer({
schema,
context,
cache
});
```
Expand Down
11 changes: 4 additions & 7 deletions docs/introduction/context.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,21 +92,18 @@ export interface User {
lastName: string;
}

export interface IAuthModuleContext {
currentUser: User;
}

export interface IAuthModuleRequest {
export interface ISession {
req: express.Request;
res: express.Response;
}

export const AuthModule = new GraphQLModule<{}, IAuthModuleRequest, IAuthModuleContext>({
export const AuthModule = new GraphQLModule({
typeDefs,
resolvers,
providers: [
AuthenticationProvider,
],
async context(session, currentContext, { injector }) {
async context(session: ISession, currentContext, { injector }) {
const authToken = session.req.headers.authentication;
const currentUser = injector.get(AuthenticationProvider).authorizeUser(authToken);
return {
Expand Down
107 changes: 100 additions & 7 deletions docs/introduction/dependency-injection.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,18 +220,44 @@ export const MyModule = new GraphQLModule({

## Hooks

### `OnRequest hook`
### `OnInit` hook

This hook is called once when your application is started.

Example;

```typescript
import { Injectable } from '@graphql-modules/di';
import { OnRequest } from '@graphql-modules/core';
@Injectable()
export class DatabaseProvider implements OnInit {
constructor(private dbClient: DbClient) {}
onInit() {
this.dbClient.connect();
console.info('Database Client is connected!');
}
}
```

### `OnRequest` hook

You can get access to useful information: the top `GraphQLModule` instance, GraphQL Context, and the network session by defining this hook as a method in your class provider.

```typescript
import { Injectable, OnRequest } from '@graphql-modules/core';

@Injectable()
export class MyProvider implements OnRequest {
Example;

@Injectable({
scope: ProviderScope.Session
})
export class AuthProvider implements OnRequest {
userId: string;
onRequest(moduleSessionInfo: ModuleSessionInfo) {
// ...do your magic...
// Let's assume you have your network request object under req property of network session
const authToken = moduleSessionInfo.session.req.headers.authentication;
this.userId = someFnForTokenExchange(authToken);
}
}
```
Expand All @@ -240,26 +266,93 @@ export class MyProvider implements OnRequest {
[API of `OnRequest` is available here](/docs/api/core/api-interfaces-onrequest)
[API of `ModuleSessionInfo` is available here](/docs/api/core/api-classes-modulesessioninfo)

### `OnResponse` hook (experimental)

It takes same parameter like `OnRequest` hook but it gets called even before the server sends HTTP response to the client.

Example;

```typescript
import { Injectable, OnResponse } from '@graphql-modules/core';

@Injectable()
export class MyProvider implements OnResponse {

onResponse(moduleSessionInfo: ModuleSessionInfo) {
// ...do your magic...
clearDatabasePool(moduleSessionInfo.session);
}
}
```

#### Note:
> For now it only works with Apollo-Server, and you need to pass `formatResponse` from GraphQL-Modules.
```typescript
const { schema, formatResponse } = new GraphQLModule({
providers: [MyProvider],
...
});

new ApolloServer({
schema,
context: session => session,
formatResponse
});
```


> `OnResponse` hook is called on each HTTP GraphQL request with a single `ModuleSessionInfo` parameter.
[API of `OnResponse` is available here](/docs/api/core/api-interfaces-onresponse)
[API of `ModuleSessionInfo` is available here](/docs/api/core/api-classes-modulesessioninfo)

### `OnConnect hook`

This hook is similar to `OnRequest` hook, but this is called on the initialization of WebSockets connection. It is exactly same with `OnConnect` hook that is passed to `subscriptions` in **Apollo Server**.

[You can learn more from Apollo docs.](https://www.apollographql.com/docs/graphql-subscriptions/authentication.html)

Example;

```typescript
import { Injectable, OnConnect } from '@graphql-modules/core';

@Injectable({
scope: ProviderScope.Session
})
export class AuthProvider implements OnConnect {
userId: string;
onConnect(connectionParams) {
// ...do your magic...
const authToken = connectionParams.authentication;
this.userId = someFnForTokenExchange(authToken);
}
}
```

> `OnConnect` hook is called once for each WebSocket GraphQL connection.
[API of `OnConnect` is available here](/docs/api/core/api-interfaces-onconnct)

### `OnDisconnect hook`

This hook is similar to `OnResponse` hook, but this is called on the termination of WebSockets connection. It is exactly same with `OnDisconnect` hook that is passed to `subscriptions` in **Apollo Server**.

[You can learn more from Apollo docs.](https://www.apollographql.com/docs/graphql-subscriptions/authentication.html)

```typescript
import { Injectable, OnDisconnect } from '@graphql-modules/core';

@Injectable()
export class MyProvider implements OnConnect {
export class MyProvider implements OnDisconnect {

onConnect(connectionParams, webSocket) {
onDisconnect(connectionParams, webSocket) {
// ...do your magic...
clearSomeSubscriptions(moduleSessionInfo.session);
}
}
```

> `OnConnect` hook is called once for each WebSocket GraphQL connection.
[API of `OnConnect` is available here](/docs/api/core/api-interfaces-onrequest)
> `OnDisconnect` hook is called once for each WebSocket GraphQL connection.
[API of `OnDisconnect` is available here](/docs/api/core/api-interfaces-ondisconnect)

## Provider Scopes

Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
id: implement-your-providers
id: implement-providers
title: Implement Your Providers
sidebar_label: Implement Your Providers
sidebar_label: Implement Providers
---

When your app grows and becomes more complex, you can use **Providers** (it's just a class...) to implement your resolvers' logic.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
id: implement-your-resolvers
id: implement-resolvers
title: Implement Your Resolvers
sidebar_label: Implement Your Resolvers
sidebar_label: Implement Resolvers
---

GraphQL Modules let you implement your GraphQL resolvers in a normal way, just like any other GraphQL application.
Expand Down
36 changes: 36 additions & 0 deletions docs/introduction/implement-server.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
id: implement-server
title: Implement Your Server
sidebar_label: Implement Server
---

To get started, add `express` and `express-graphql` to your app:

```bash
yarn add express express-graphql
```

Then,

```typescript
import { GraphQLModule } from '@graphql-modules/core';
import * as express from 'express';
import * as graphqlHTTP from 'express-graphql';

const { schema } = new GraphQLModule({
/*...*/
});

const app = express();

app.use('/graphql', graphqlHTTP({
schema,
graphiql: true
});

app.listen(4000);
```
> To test your server, run `ts-node index.ts` and try to open `http://localhost:4000/`, you should see the **[GraphiQL](https://github.com/graphql/graphiql)** UI.

> If you want to use **[Apollo-Server](https://www.apollographql.com/docs/apollo-server/getting-started.html)** check **Integrate with Apollo Server** section
4 changes: 2 additions & 2 deletions docs/introduction/subscriptions.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ Subscriptions need to have defined `PubSub` implementation in your GraphQL-Modul
You have to export `subscriptions` from your `AppModule`, and pass it to your GraphQL Server.

```typescript
const { schema, context, subscriptions } = new GraphQLModule({
const { schema, subscriptions } = new GraphQLModule({
imports: [
CommonModule,
PostsModule
Expand All @@ -74,7 +74,7 @@ You have to export `subscriptions` from your `AppModule`, and pass it to your Gr

const server = new ApolloServer({
schema,
context,
context: session => session,
subscriptions
});

Expand Down
Loading

0 comments on commit de850fb

Please sign in to comment.