Application - Server - Supscription & Upload file

9/18/2021 NestJsGraphQL

# Supscription:

Tạo kết nối realtime giữa client và server. Đầu tiên cần Enable giá trị installSubscriptionHandlers: true trong GraphQlService và subscriptions để verify token.

VD tạo subscription gửi thông báo cho client.

  • GraqhQL Schema:
type NotifySubscription {
    userId: String
    message: String
    createdAt: String
}

type Subscription {
    notify: NotifySubscription! @isAuthenticated
}
1
2
3
4
5
6
7
8
9
  • Resolver:

    import { PubSub } from 'graphql-subscriptions';
    
    const pubSub = new PubSub();
    
    ...
    
    @Subscription('notify')
    notify() {
        return pubSub.asyncIterator('notify');
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10

    Dùng class PubSub để kết nối App code (Nesjs) và GraphQL subscriptions engine. Subscribe qua method asyncIterator với tham số trigger name "notify".

  • Publish:

    Publish data bằng method publish

    const notify = {
        userId: user._id, 
        message: "Welcome to app!", 
        createdAt: new Date()
    };
    pubSub.publish('notify', {notify});
    
    1
    2
    3
    4
    5
    6

# Upload file:

  • Scalars: Mặc định GraphQL có các type: Int, Float, String, Boolean and ID. Tạo thêm type Upload cho mutation upload file.

    @Scalar('Upload')
    export class Upload {
      description = 'Upload custom scalar type';
    
      parseValue(value) {
        return GraphQLUpload.parseValue(value);
      }
    
      serialize(value: any) {
        return GraphQLUpload.serialize(value);
      }
    
      parseLiteral(valueNode, variables) {
        return GraphQLUpload.parseLiteral(valueNode, variables);
      }
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
  • Khai báo provider tại module:

    providers: [
        Upload,
    ],
    
    1
    2
    3
  • GraqhQL Schema:

    type Mutation {
        profileAvatarUpdate(file: Upload!): Boolean @isAuthenticated
    }
    
    1
    2
    3
  • Resolver:

    import { GraphQLUpload, FileUpload } from 'graphql-upload';
    import { createWriteStream } from 'fs';
    
    @Mutation(() => Boolean)
    async profileAvatarUpdate(
        @Context('currentUser') currentUser: User,
        @Args({name: 'file', type: () => GraphQLUpload}) fileUpload: FileUpload,
        ): Promise<boolean> {
    
            const {createReadStream, filename} = fileInput;
            return new Promise(async (resolve, reject) =>
              createReadStream()
                .pipe(createWriteStream(`/upload/${filename})`)
                .on('finish', () => resolve(true))
                .on('error', (err) => {
                  logger.error(err.toString());
                  reject(false);
                }),
            );
    
    }
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21

Series:

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