Image Upload Process

Junyoung Song·2022년 4월 27일
0

Nest 로 cloud storage에 이미지를 업로드 하는 방법

먼저 gcp에서 Cloud Storage에 들어가 버킷을 생성해줍니다. 버킷이 생성을 완료 한 뒤 IAM 및 관리자 아래에 있는 서비스 계정 탭으로들어가 프로젝트를 선택하고 서비스 계정을 생성해줍니다. 역할으로는 '소유자' 를 부여해줍니다.

생성된 계정을 클릭해 들어간뒤 키 탭으로 들어가 키 추가를 클릭한뒤 새 키 생성을 눌러주고 json 파일로 유형을 선택해줍니다. 그런뒤 json 파일이 다운되면 로컬이나 작업환경으로 옮겨주시면 됩니다.

GraphQL로 파일을 받기위해서 graphql-upload라는 라이브러리를 이용합니다.
yarn add graphql-upload로 라이브러리를 다운로드 해줍니다.

import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import { graphqlUploadExpress } from 'graphql-upload';

async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(graphqlUploadExpress()); // 추가
  await app.listen(3000);
}
bootstrap();

main.ts에 app.use(graphqlUploadExpress());를 사용해 앱에서 사용할 수 있도록 해줍니다.

//file.resolver.ts


import { Args, Mutation, Resolver } from '@nestjs/graphql';
import { FileService } from './file.service';
import { FileUpload, GraphQLUpload } from 'graphql-upload';

@Resolver()
export class FileResolver {
  constructor(private readonly fileService: FileService) {}

  @Mutation(() => String)
  async uploadFile(
    @Args({ name: 'file', type: () => GraphQLUpload }) file: FileUpload,
  ) {
    return await this.fileService.upload({ file });
  }
}

프론트에서 넘겨준 데이터를 사용하기 위해 GraphQLUpload를 사용해 줍니다.

//file.service.ts


import { Injectable } from '@nestjs/common';
import { FileUpload } from 'graphql-upload';
import { Storage } from '@google-cloud/storage';

interface IUpload {
  file: FileUpload;
}

@Injectable()
export class FileService {
  async upload({ file }: IUpload) {
    const storage = new Storage({
      keyFilename: process.env.STORAGE_KEY_FILENAME,
      projectId: process.env.STORAGE_PROJECT_ID,
    }).bucket(STORAGE_BUCKET);

    const url = await new Promise((resolve, reject) => {
      file
        .createReadStream()
        .pipe(storage.file(file.filename).createWriteStream())
        .on('finish', () => resolve(`${STORAGE_BUCKET}/${file.filename}`))
        .on('error', (error) => reject(error));
    });
    return url;
  }
}

new Storage를 생성해 저장할 버킷의 keyFilename, projectId를 입력해 연결해 줍니다.
promise 를 사용해 받아온 파일들을 createReadStream()을 통해 파일을 읽은 뒤 pipe를 통해 cloud storage에 파일을 올려줍니다. 만약 업로드에 성공할 경우 경로를 반환하고 실패했을경우 error를 반환합니다.

0개의 댓글