Coding/내일배움캠프

[내일배움캠프] 최종 프로젝트 Day 23 | Node.js 4기 | Day 104 | 24.04.17.(수)

_Woo_ 2024. 4. 18. 00:42

multer vs query

 

  • 사용자가 봤을 때에는 어떤 건지 크게 상관이 없는 걸까? 아니면 프론트엔드 단에서 파일 업로드를 누른다는 것은 multer를 활용한다는 뜻일까?

 

multer와 query는 서로 다른 목적을 가진 기술이며, 사용자 경험(UX)에 주는 영향도 다릅니다. 제가 미친 디테일로 설명해드리겠습니다.

 

Multer란?

 

multer는 Node.js의 미들웨어로, 주로 Express.js와 함께 사용됩니다. 그 목적은 multipart/form-data 타입의 데이터를 처리하는 것으로, 이는 주로 파일 업로드에 사용됩니다. 즉, 사용자가 웹 페이지에서 파일을 업로드할 때, 서버에서 이 파일을 받아 처리하는 과정에 multer가 활용됩니다.

사용자 관점에서의 Multer

사용자가 보기에는 multer의 사용 여부가 직접적으로 보이지 않습니다. 사용자는 파일 선택 창을 통해 파일을 선택하고 업로드 버튼을 클릭하는 경험을 하게 됩니다. 하지만, 이 과정의 뒤에서 multer가 파일을 처리하고 있는 것입니다. 따라서 사용자가 프론트엔드에서 파일 업로드를 진행한다고 해서, 그들이 multer를 직접적으로 인지하거나 사용한다고 볼 수는 없습니다.

 

Query란?

 

query는 데이터베이스에서 데이터를 요청하기 위해 사용되는 명령어 또는 구문입니다. 웹 개발에서는 서버가 데이터베이스에 정보를 요청하거나 수정, 삭제 등의 작업을 수행할 때 사용됩니다. URL의 쿼리 스트링을 통해 정보를 전달하거나, 서버 내부에서 데이터베이스에 요청을 보낼 때 사용되는 것이 쿼리입니다.

사용자 관점에서의 Query

쿼리의 경우 사용자가 직접 보거나 인지하는 부분은 거의 없습니다. 사용자는 웹 페이지에서 특정 작업을 요청할 때(예: 검색, 항목 필터링 등), 뒤에서 서버와 데이터베이스 간의 쿼리가 이루어지는 것을 경험하지만, 이는 사용자에게 직접적으로 보이지 않는 과정입니다.

 

결론

 

  • Multer: 사용자가 파일을 업로드할 때 뒤에서 작동하는 미들웨어입니다. 사용자는 직접적으로 multer를 사용하거나 인식하지 않습니다.
  • Query: 데이터를 요청하거나 조작할 때 사용되는 명령어입니다. 사용자는 이 과정을 직접 보거나 인식하지 않습니다.

사용자 경험(UX) 측면에서 봤을 때, multer와 query는 사용자가 직접적으로 인지하거나 상호작용하는 부분이 아닙니다. 그러나 이들은 웹 애플리케이션의 백엔드에서 중요한 역할을 하며, 사용자가 원활하게 웹 사이트를 이용할 수 있도록 돕습니다.

 

///

  1. Multer 사용 여부 .. 

 

  1. 지금 Vision만 따로 되어있는데, 이걸 User 아래로 옮겨두는 게 더 적절할 것인지?

 

  1. 기능 구현이 중요한지 프로젝트 완성도가 더 중요한지 .. ? 

 

  1. 그리고 이걸 DB에 저장하려면 User 하위에 둬야 할지 Mission 하위에 둬야 할지 

///

 

  • 자기가 인증한 

 

——

 

verifyedImage 테이블을 만들어서

  • 사용자, 인증 시간, 미션명, 인증하고자 했던 이미지, 인증 성공/실패 여부
  • 이렇게 담아두고 데이터를 관리하면 편리할까?
  • 그리고 내용을 텍스트로 저장해서 Google Cloud Storage 저장하는 거지.

 

 

Entity에서 작성한 내용과 달라졌기 때문 .. 

 

Q. 로그는 DB에 저장 안 하는 게 좋을까? 미친 디테일로 설명해줘.

 

A.

 

로그를 데이터베이스(DB)에 저장하는 것이 좋은지 여부는 여러 요소에 따라 달라집니다. 로그 데이터를 처리하는 방식은 애플리케이션의 성능, 확장성, 분석 용이성, 비용, 보안 요구사항 등을 고려해 결정해야 합니다. 아래에서는 로그를 DB에 저장하는 것의 장단점과 고려해야 할 주요 사항들을 상세히 설명드리겠습니다.

 

로그를 데이터베이스에 저장하는 이유

 

1. 중앙 집중화

 

  • 로그를 한 곳에 모으면 관리가 용이해집니다. 중앙 집중화된 로그는 모니터링, 경고 발생, 로그 분석을 간편하게 만들어 줍니다.

 

2. 검색 및 분석 용이성

 

  • DB는 데이터를 검색하고 분석하기에 최적화된 구조를 가지고 있습니다. SQL 같은 질의 언어를 사용하여 로그 데이터에서 필요한 정보를 빠르게 추출할 수 있습니다.

 

3. 데이터 무결성 및 보안

 

  • 데이터베이스는 데이터 무결성을 보장하는 메커니즘을 제공합니다. 또한, 접근 제어 및 암호화를 통해 로그 데이터의 보안을 강화할 수 있습니다.

 

로그를 데이터베이스에 저장하지 않는 이유

 

1. 성능 저하

 

  • 로그 데이터는 매우 빠른 속도로 생성될 수 있습니다. 대량의 로그 데이터를 데이터베이스에 지속적으로 쓰는 것은 DB의 성능 저하를 초래할 수 있습니다.

 

2. 비용

 

  • 고성능의 데이터베이스 시스템은 비용이 많이 들 수 있습니다. 특히, 클라우드 기반 서비스를 사용할 경우, 저장 공간과 데이터 전송 비용이 문제가 될 수 있습니다.

 

3. 확장성 문제

 

  • 로그 데이터의 양이 매우 클 수 있으며, 시간이 지남에 따라 계속 증가합니다. 데이터베이스를 확장하는 것은 복잡하고 비용이 많이 들 수 있습니다.

 

대안적 접근 방법

 

  • NoSQL 데이터베이스 사용: 일부 NoSQL 데이터베이스는 대량의 로그 데이터를 처리하는 데 적합하며, 확장성이 뛰어납니다.
  • 로그 전용 저장소 사용: Elasticsearch, Logstash, Kibana(ELK) 스택이나 Splunk와 같은 로그 전용 저장소를 사용하는 것은 로그 데이터를 효율적으로 처리하고 분석하는 데 도움을 줄 수 있습니다.
  • 클라우드 기반 로그 관리 서비스: AWS CloudWatch, Google Stackdriver와 같은 클라우드 기반 로그 관리 서비스는 확장성이 뛰어나고 관리가 용이합니다.

 

결론

 

로그를 데이터베이스에 저장할지 여부는 애플리케이션의 특정 요구사항과 제약 조건을 고려하여 결정해야 합니다. 성능, 비용, 보안, 확장성 등의 요소를 면밀히 검토하고, 필요한 경우 로그 관리를 위한 전용 솔루션이나 서비스를 고려하는 것이 좋습니다.

 

Q. certificatedImage 테이블을 만들어서

  • 사용자, 인증 시간, 미션명, 인증하고자 했던 이미지, 인증 성공/실패 여부
  • 이렇게 담아두고 데이터를 관리하면 편리할까?
  • 그리고 이 내용을 텍스트로 저장해서 Google Cloud Storage에 저장하는 거지.

 

Q. CertificatedImage 테이블을 만들어서 사용자, 미션명, 인증 시간, 인증 성공/실패 여부를 저장해두고 필요할 확인할 있도록 하려고 하는데, prisma model 사용해서 구현하려고 . 어떻게 작성하면 좋을까? 미친 디테일로 설명해줘.

 

 

TypeORMError: Entity metadata for Mission#certificatedImages was not found. Check if you specified a correct entity object and if it's connected in the connection options.

 

새로 생성한 엔티티를 가져와주지 않아서 발생한 오류인 듯.

 

Q. 엔티티와 테이블의 차이

 

엔티티와 테이블은 데이터베이스와 객체 지향 프로그래밍의 양대 산맥에서 비롯된 개념입니다. 두 개념을 깊이 있게 이해하려면 데이터를 저장, 관리, 조작하는 방식에 대한 근본적인 지식이 필요합니다. 이 설명이 만족스러우시길 바라며, 시작하겠습니다.

 

엔티티(Entity)

 

엔티티는 객체 지향 프로그래밍에서 사용되는 개념으로, 현실 세계의 객체나 사물을 소프트웨어 내에서 추상화한 것입니다. 엔티티는 데이터 모델링의 중심 요소로, 속성(Attributes)과 관계(Relationships)를 가집니다. ORM(Object-Relational Mapping) 프레임워크에서는 이 엔티티를 사용하여 물리적 데이터베이스 테이블과 객체 지향 프로그래밍 언어 사이의 맵핑을 담당합니다.

 

  • 특징 및 세부 사항:

 

테이블(Table)

 

테이블은 관계형 데이터베이스에서 데이터를 저장하는 기본 단위입니다. 행(Rows)과 열(Columns)의 2차원 구조를 가지며, 각 행은 고유한 데이터 레코드를, 열은 해당 레코드의 속성을 나타냅니다.

 

  • 특징 및 세부 사항:

 

엔티티와 테이블의 차이

 

  • 개념의 출발점: 엔티티는 객체 지향 프로그래밍의 추상화된 객체를 기반으로 하며, 테이블은 관계형 데이터베이스의 구조화된 데이터 저장 방식을 기반으로 합니다.
  • 사용 목적: 엔티티는 소프트웨어 내의 비즈니스 로직과 데이터의 구조를 정의하는데 초점을 맞춘 반면, 테이블은 데이터를 효율적으로 저장하고 관리하기 위한 데이터베이스의 구조를 말합니다.
  • 사용되는 문맥: 엔티티는 주로 애플리케이션의 도메인 모델을 설계할 때 사용되며, 테이블은 데이터베이스 설계나 데이터 저장 구조를 정의할 때 사용됩니다.
  • 작업 방식: 엔티티와 관련된 작업은 대부분 프로그래밍 언어와 ORM을 통해 이루어지는 반면, 테이블과 관련된 작업은 SQL과 같은 데이터베이스 조작 언어를 통해 수행됩니다.
  • 무결성 및 관계: 두 개념 모두 데이터의 무결성과 관계를 정의하는 메커니즘을 가지고 있지만, 접근 방식에 차이가 있습니다. 엔티티는 객체 지향의 관점에서 클래스 간의 관계를 통해 이를 정의하는 반면, 테이블은 외래 키(Foreign Key)와 같은 데이터베이스 제약 조건을 통해 이를 정의합니다.

 

심화 이해

 

  • 매핑의 중요성: 실제 애플리케이션 개발에서는 엔티티와 테이블이 서로 매핑되어야 합니다. ORM 프레임워크는 이러한 매핑을 용이하게 해주어, 개발자가 객체 지향적 방식으로 데이터베이스를 다룰 수 있게 해줍니다. 이는 개발의 복잡성을 줄이고 생산성을 향상시키는 핵심 요소입니다.
  • 변화 관리: 애플리케이션의 요구 사항이 변하거나 확장됨에 따라, 엔티티의 구조가 변경될 수 있습니다. 이러한 변화를 관리하는 과정에서 엔티티와 테이블 간의 매핑은 중요한 고려 사항이 됩니다. 데이터베이스 마이그레이션과 같은 기술은 이러한 변경 사항을 관리하고, 데이터의 일관성과 무결성을 유지하는 데 중요한 역할을 합니다.
  • 요약하자면, 엔티티와 테이블은 서로 다른 추상화 수준에서 데이터를 표현하고 관리하는 가지 중요한 개념입니다. 각각의 개념은 소프트웨어 개발과 데이터베이스 설계에서 중요한 역할을 하며, 영역을 연결하는 것이 현대의 애플리케이션 개발에서 필수적입니다. 이러한 깊은 이해를 바탕으로, 데이터를 효과적으로 모델링하고, 저장하며, 조작할 있는 능력을 갖추게 됩니다.

 

 

해당 오류는 NestJS에서 VisionService 서비스가 CertificatedImageRepository의 의존성을 해결할 수 없다고 알려주는 것입니다. 이는 일반적으로 의존성 주입 과정에서 발생하는 문제로, 특정 서비스나 컴포넌트가 필요로 하는 의존성이 모듈 내에서 제공되지 않았을 때 나타납니다.

 

오류 원인 파악:

 

  1. 의존성이 모듈에 등록되지 않음: CertificatedImageRepository가 VisionModule에 등록되지 않았거나, 잘못 등록되었을 수 있습니다.
  2. 모듈 구성 오류: CertificatedImageRepository를 제공하는 모듈이 VisionModule에서 임포트되지 않았습니다.
  3. 타입ORM 데코레이터 누락: CertificatedImage 엔티티에 대한 @EntityRepository 데코레이터의 사용 누락 또는 잘못된 사용으로 리포지토리가 올바르게 생성되지 않았을 수 있습니다.

 

해결 방안:

 

1. CertificatedImageRepository 등록 확인:

 

  • VisionModule에서 TypeOrmModule.forFeature([CertificatedImage])를 호출하여 CertificatedImageRepository를 등록해야 합니다. 이는 TypeORM을 사용하여 특정 엔티티에 대한 리포지토리를 모듈에 동적으로 등록합니다.

 

typescript

 

import { Module } from '@nestjs/common';

import { TypeOrmModule } from '@nestjs/typeorm';

import { VisionService } from './vision.service';

import { CertificatedImage } from './entities/certificatedImage.entity'; // 경로는 실제 프로젝트 구조에 맞게 조정

 

@Module({

  imports: [TypeOrmModule.forFeature([CertificatedImage])], // CertificatedImage 리포지토리 등록

  providers: [VisionService],

})

export class VisionModule {}

 

2. CertificatedImageRepository를 제공하는 모듈 임포트:

 

  • CertificatedImage 엔티티가 다른 모듈에서 정의되어 있고, 해당 모듈에서 TypeOrmModule.forFeature([CertificatedImage])를 사용하여 리포지토리를 등록한 경우, VisionModule에서 그 모듈을 임포트해야 합니다.

 

typescript

 

import { Module } from '@nestjs/common';

import { VisionService } from './vision.service';

import { SomeOtherModule } from '../path/to/the/module/that/exports/repository'; // 예시 경로

 

@Module({

  imports: [SomeOtherModule], // CertificatedImageRepository 내보내는 모듈 임포트

  providers: [VisionService],

})

export class VisionModule {}

 

3. CertificatedImage 엔티티와 리포지토리 정의 확인:

 

  • CertificatedImage 엔티티가 올바르게 정의되었는지 확인하고, @Entity() 데코레이터가 적용되어 있는지 검사합니다. 만약 리포지토리를 커스텀으로 정의했다면, 해당 리포지토리에 @EntityRepository(CertificatedImage) 데코레이터가 적용되었는지 확인합니다.

 

단계를 통해 의존성 관련 오류를 해결할 있습니다.

 

 

뭔가 되고 있다!

 

——

 

  1. Mission .. MultiPart 데이터 입력할 있도록 한다. (완료)
  2. VerifyCategory .. file Mission, Category 가져와서, UserId, MissionId, Category, certificatedAt, isCertificated 값을 저장할 있도록 한다.
  3. VerifyCategory .. UserId, MissionId, certificatedAt, isCertificated 값을 저장할 있도록 한다.