Application - Server - Module

9/18/2021 NestJsGraphQL

# Module:

Structure (UserModule)

...
├── modules/
|     ├── dto/
|     |       ├── user-create.dto.ts
|     |       ├── user-update.dto.ts
|     |       └── ...
|     |         
|     ├── entities/
|     |       ├── user.entity.ts
|     |       └── ...
|     | 
|     ├── repositories
|     |       ├── user.repository.ts
|     |       └── ...
|     |
|     ├── services
|     |       ├── user.service.ts
|     |       └── ...
|     |
|     ├── user.graphql
|     ├── user.module.ts
|     ├── user.resolver.ts
...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# UserGraphQL: (user.graphql)

Định nghĩa các operation(query, mutation, subscription) trong UserModule. vd get thông tin và create user.

  • Query: get data, tương ứng với Get của REST.
  • Mutation: create, update, delete data, tương ứng với POST, PUT, DELETE của REST.
  • Subscription: Cho phép kết nối realtime giữa client và server.
### DIRECTIVE ###
directive @isAuthenticated on FIELD | FIELD_DEFINITION
directive @hasRole(role: String) on FIELD | FIELD_DEFINITION

### INPUT ###
input UserCreateInput {
    name: String!
    password: String!
    email: String!
}

input UserUpdateInput {
    name: String!
    email: String!
}

### TYPES ###
type User {
    _id: String!
    name: String!
    email: String!
    userType: Int
    createdAt: String!
    updatedAt: String!
    roles: [Role]
}

type Role {
    name: String!
    code: String!
}

### QUERY ###
type Query {
    users: [User] @hasRole(role: "admin")
    user(_id: String!): User @isAuthenticated
}
### MUTATION ###
type Mutation {
	register(input: UserCreateInput!): User
    userUpdate(_id: String!, input: UserUpdateInput!): Boolean @isAuthenticated
    userDelete(_id: String!): Boolean @hasRole(role: "admin")
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

File graphql định nghĩa các GraphQL Schema và type.

# Resolver: UserResolver

Resolver cung cấp instructions (hướng dẫn) để chuyển GraphQL operation (query, mutation, subscription) thành dữ liệu. Hay dễ hiểu là ta đã định nghĩa phần schema của các operation ở UserGraphQL còn UserResolver sẽ xử lí business logic.

Mặc định các function sẽ mapping theo tên nhưng có thể custom tên @Query(() => [User], {name: 'users'})

@Resolver('User')
export class UserResolver {
  constructor(
      private readonly userService: UserService,
  ) {
  }

  @Query(() => [User])
  async users() {
    return this.userService.findAll();
  }

  @Query(() => User)
  async user(@Args('_id') _id: string) {
    return this.userService.findById(_id);
  }

  @Mutation(() => User, {name: 'register'})
  async userCreate(@Args('input') input: UserCreateInputDto) {
    return await this.userService.create(input);
  }

  @Mutation(() => User)
  async userUpdate(
      @Args('_id') _id: string,
      @Args('input') input: UserUpdateInputDto,
  ) {
    return await this.userService.update(_id, input);
  }

  @Mutation(() => Boolean)
  async userDelete(@Args('_id') _id: string) {
    return await this.userService.delete(_id);
  }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36

Để DI UserService trong UserResolver vần khai báo UserService trong provider tại UserModule.

Resolved còn có thể xử lí liên kết với dữ liệu khác. Trường hợp db đang dùng là mongodb thì giúp get dữ liệu relation giữa các colecction (không tạo relation mà giúp get dữ liệu để trả về trong response). VD UserEntity hiện roles đang lưu chung trong 1 collection.

@Entity('user', {
  orderBy: {
    created_at: 'ASC',
  },
})
export class User {
  ...
  @Column({default: []})
  roles: [{
    name: string;
    code: string;
  }];
  ...
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Nếu role được lưu ở 1 collection riêng.

@Column({default: []})
roleId: string;
1
2

Thì có thể dùng decorator @ResolveProperty để liên kết dữ liệu user và role.

@ResolveProperty()
async roles(@Parent() users) {
    const { roleId } = users;
    /* Get roles from role collection */
    return this.roleService.find({_id: roleId});
}
1
2
3
4
5
6

Series:

GitHub: https://github.com/ninhnguyen22/nestjs-angular-graphql (opens new window)