먼저 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를 반환합니다.