NestJS에서 파일 업로드 간소화: 디스크 저장소 없이 CSV 및 XLSX에 대한 효율적인 메모리 내 구문 분석
NestJS의 간편한 파일 구문 분석: 속도, 보안 및 확장성을 위해 메모리에서 CSV 및 XLSX 업로드 관리
소개
웹 애플리케이션에서 파일 업로드를 처리하는 것은 일반적인 작업이지만 다양한 파일 형식을 처리하고 올바르게 처리되는지 확인하는 것이 어려울 수 있습니다. 개발자는 업로드된 파일을 서버에 저장하지 않고 구문 분석해야 하는 경우가 많습니다. 이는 서버 저장 비용을 줄이고 민감한 데이터가 불필요하게 유지되지 않도록 하는 데 특히 중요합니다. 이 기사에서는 특히 CSV 및 XLS/XLSX 파일용 파일 업로드를 처리하기 위해 사용자 정의 NestJS 모듈을 만드는 과정을 살펴보고 Node.js 스트림을 사용하여 메모리에서 이러한 파일을 구문 분석하므로 정적 파일이 서버에서 생성됩니다.
왜 NestJS인가?
NestJS는 TypeScript를 활용하고 테스트 가능성, 확장성, 느슨하게 결합 및 유지 관리가 쉬운 애플리케이션을 구축할 수 있는 즉시 사용 가능한 애플리케이션 아키텍처를 제공하는 진보적인 Node.js 프레임워크입니다. NestJS를 사용하면 모듈식 구조, 강력한 종속성 주입 시스템 및 광범위한 생태계를 활용할 수 있습니다.
1단계: 프로젝트 설정
코드를 살펴보기 전에 새로운 NestJS 프로젝트를 설정해 보겠습니다. 아직 설치하지 않았다면 NestJS CLI를 설치하세요.
npm install -g @nestjs/cli
새 NestJS 프로젝트 만들기:
nest new your-super-name
프로젝트 디렉토리로 이동하세요:
cd your-super-name
2단계: 필수 패키지 설치
파일 업로드 및 구문 분석을 처리하려면 몇 가지 추가 패키지를 설치해야 합니다.
npm install @nestjs/platform-express multer exceljsfile-type
- Multer: 멀티파트/폼 데이터를 처리하기 위한 미들웨어로 주로 파일 업로드에 사용됩니다.
- Exlesjs: CSV/XLS/XLSX 파일을 구문 분석하기 위한 강력한 라이브러리.
- File-Type: 스트림이나 버퍼의 파일 형식을 감지하기 위한 라이브러리입니다.
3단계: 파일을 저장하지 않고 Multer Storage Engine 생성
파일 업로드 프로세스를 맞춤설정하기 위해 맞춤형 Multer 스토리지 엔진을 생성하겠습니다. 이 엔진은 CSV 및 XLS/XLSX 파일만 허용되도록 하고, Node.js 스트림을 사용하여 메모리에서 해당 파일을 구문 분석하고, 파일을 디스크에 저장하지 않고 구문 분석된 데이터를 반환합니다.
엔진용 새 파일 만들기:
import { PassThrough } from 'stream'; import * as fileType from 'file-type'; import { BadRequestException } from '@nestjs/common'; import { Request } from 'express'; import { Workbook } from 'exceljs'; import { createParserCsvOrXlsx } from './parser-factory.js'; const ALLOWED_MIME_TYPES = [ 'text/csv', 'application/vnd.ms-excel', 'text/comma-separated-values', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel', ] as const; export class CsvOrXlsxMulterEngine { private destKey: string; private maxFileSize: number; constructor(opts: { destKey: string; maxFileSize: number }) { this.destKey = opts.destKey; this.maxFileSize = opts.maxFileSize; } async _handleFile(req: Request, file: any, cb: any) { try { const contentLength = Number(req.headers['content-length']); if ( typeof contentLength === 'number' && contentLength > this.maxFileSize ) { throw new Error(`Max file size is ${this.maxFileSize} bytes.`); } const fileStream = await fileType.fileTypeStream(file.stream); const mime = fileStream.fileType?.mime ?? file.mimetype; if (!ALLOWED_MIME_TYPES.includes(mime)) { throw new BadRequestException('File must be *.csv or *.xlsx'); } const replacementStream = new PassThrough(); fileStream.pipe(replacementStream); const parser = createParserCsvOrXlsx(mime); const data = await parser.read(replacementStream); cb(null, { [this.destKey]: mime === 'text/csv' ? data : (data as Workbook).getWorksheet(), }); } catch (error) { cb(error); } } _removeFile(req: Request, file: any, cb: any) { cb(null); } }
이 사용자 정의 스토리지 엔진은 파일의 MIME 유형을 확인하고 CSV 또는 XLS/XLSX 파일인지 확인합니다. 그런 다음 Node.js 스트림을 사용하여 메모리에서 파일 전체를 처리하므로 서버에 임시 파일이 생성되지 않습니다. 이 접근 방식은 특히 민감한 데이터를 처리할 때 효율적이고 안전합니다.
4단계: 파서 팩토리 생성
파서 팩토리는 파일 형식에 따라 적절한 파서를 결정하는 역할을 담당합니다.
파서용 새 파일을 만듭니다.
import excel from 'exceljs'; export function createParserCsvOrXlsx(mime: string) { const workbook = new excel.Workbook(); return [ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', 'application/vnd.ms-excel', ].includes(mime) ? workbook.xlsx : workbook.csv; }
이 팩토리 함수는 MIME 유형을 확인하고 적절한 파서(xlsx 또는 csv)를 반환합니다.
5단계: NestJS 컨트롤러에서 Multer 구성
다음으로, 맞춤형 스토리지 엔진을 사용하여 파일 업로드를 처리하는 컨트롤러를 만들어 보겠습니다.
새 컨트롤러 생성:
nest g controller files
files.controller.ts에서 Multer 및 사용자 정의 스토리지 엔진을 사용하여 파일 업로드를 구성합니다.
import { Controller, Post, UploadedFile, UseInterceptors, } from '@nestjs/common'; import { FileInterceptor } from '@nestjs/platform-express'; import { Worksheet } from 'exceljs'; import { CsvOrXlsxMulterEngine } from '../../shared/multer-engines/csv-xlsx/engine.js'; import { FilesService } from './files.service.js'; const MAX_FILE_SIZE_IN_MiB = 1000000000; // Only for test @Controller('files') export class FilesController { constructor(private readonly filesService: FilesService) {} @UseInterceptors( FileInterceptor('file', { storage: new CsvOrXlsxMulterEngine({ maxFileSize: MAX_FILE_SIZE_IN_MiB, destKey: 'worksheet', }), }), ) @Post() create(@UploadedFile() data: { worksheet: Worksheet }) { return this.filesService.format(data.worksheet); } }
이 컨트롤러는 파일 업로드를 처리하기 위한 엔드포인트를 설정합니다. 업로드된 파일은 CsvOrXlsxMulterEngine에 의해 처리되며 구문 분석된 데이터는 디스크에 저장되지 않은 채 응답으로 반환됩니다.
6단계: 모듈 설정
마지막으로 컨트롤러를 포함할 모듈을 설정해야 합니다.
새 모듈 생성:
nest g module files
files.module.ts에서 컨트롤러를 가져옵니다.
import { Module } from '@nestjs/common'; import { FilesController } from './files.controller.js'; import { FilesService } from './files.service.js'; @Module({ providers: [FilesService], controllers: [FilesController], }) export class FilesModule {}
이 모듈을 AppModule로 가져와야 합니다.
7단계: HTML을 사용하여 파일 업로드 테스트
파일 업로드 기능을 테스트하기 위해 사용자가 CSV 또는 XLS/XLSX 파일을 업로드할 수 있는 간단한 HTML 페이지를 만들 수 있습니다. 이 페이지는 파일을 /api/files 엔드포인트로 보내며, 그곳에서 메모리에서 구문 분석되고 처리됩니다.
파일 업로드 테스트를 위한 기본 HTML 파일은 다음과 같습니다.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>File Upload</title> </head> <body> <h1>Upload a File (CSV or XLSX)</h1> <form action="/api/files" method="post" enctype="multipart/form-data"> <label for="file">Choose file:</label> <input type="file" id="file" name="file" accept=".csv, .xlsx" required> <br><br> <button type="submit">Upload</button> </form> </body> </html>
파일 업로드를 위한 HTML 페이지를 렌더링하려면 먼저 @nestjs/serve-static이라는 추가 NestJS 모듈을 설치해야 합니다. 다음 명령을 실행하면 됩니다:
npm install @nestjs/serve-static
설치 후 AppModule에서 이 모듈을 구성해야 합니다.
import { Module } from '@nestjs/common'; import { join } from 'path'; import { ServeStaticModule } from '@nestjs/serve-static'; import { FilesModule } from './modules/files/files.module.js'; @Module({ imports: [ FilesModule, ServeStaticModule.forRoot({ rootPath: join(new URL('..', import.meta.url).pathname, 'public'), serveRoot: '/', }), ], }) export class AppModule {}
이 설정을 통해 공개 디렉토리에서 정적 파일을 제공할 수 있습니다. 이제 브라우저에서 http://localhost:3000으로 이동하여 파일 업로드 페이지를 열 수 있습니다.
파일 업로드
파일을 업로드하려면 다음 단계를 따르세요.
- '파일 선택' 버튼을 클릭하여 파일을 선택하세요.
- 업로드 프로세스를 시작하려면 '업로드' 버튼을 클릭하세요.
파일이 성공적으로 업로드되면 파일이 업로드되고 포맷되었다는 확인 메시지가 표시됩니다.
참고: 업로드된 파일의 형식을 지정하는 코드는 포함하지 않았습니다. 이는 CSV 또는 XLS/XLSX 파일을 처리하기 위해 선택한 라이브러리에 따라 다르기 때문입니다. GitHub에서 전체 구현을 볼 수 있습니다.
인메모리 파일 처리의 장단점 비교
인메모리 파일 처리를 사용할지 디스크에 파일을 저장할지 결정할 때 장단점을 이해하는 것이 중요합니다.
인메모리 처리의 장점:
디스크에 임시 파일 없음:
- 보안: 민감한 데이터가 서버 디스크에 남지 않아 데이터 유출 위험이 줄어듭니다.
- 리소스 효율성: 서버는 임시 파일을 위한 디스크 공간을 할당할 필요가 없으며 이는 저장 공간이 제한된 환경에서 특히 유용할 수 있습니다.
더 빠른 처리:
- 성능: 디스크에서 파일을 쓰고 읽는 오버헤드를 제거하므로 메모리의 파일을 구문 분석하는 속도가 더 빨라질 수 있습니다.
- I/O 작업 감소: 디스크 I/O 작업이 적다는 것은 대기 시간이 짧고 강력하다는 것을 의미합니다. 파일 처리 처리량이 훨씬 더 높습니다.
단순화된 정리:
- 정리 필요 없음: 파일이 디스크에 저장되지 않으므로 임시 파일을 관리하거나 정리할 필요가 없어 코드베이스가 단순화됩니다.
인메모리 처리의 단점:
메모리 사용량:
- 높은 메모리 소비: 대용량 파일은 상당한 양의 메모리를 소비할 수 있으며, 서버에 리소스가 충분하지 않으면 메모리 부족 오류가 발생할 수 있습니다.
- 확장성: 대용량 파일이나 여러 파일 업로드를 동시에 처리하려면 신중한 메모리 관리 및 확장 전략이 필요할 수 있습니다.
파일 크기 제한:
- 메모리 제한: 처리할 수 있는 최대 파일 크기는 서버에서 사용 가능한 메모리에 따라 제한됩니다. 이는 의미 있는 일이 될 수 있습니다. 대용량 파일을 처리하는 애플리케이션의 단점.
오류 처리의 복잡성:
- 오류 관리: 스트리밍 데이터의 오류를 관리하는 것은 디스크에서 파일을 처리하는 것보다 더 복잡할 수 있으며, 특히 부분 데이터를 복구하거나 분석해야 하는 경우에는 더욱 그렇습니다.
인메모리 처리를 사용하는 경우:
소형에서 중형 파일: 애플리케이션이 상대적으로 작은 파일을 처리하는 경우 인메모리 처리가 속도와 단순성을 제공할 수 있습니다.
보안에 민감한 애플리케이션: 디스크에 저장하면 안 되는 민감한 데이터를 처리할 때 메모리 내 처리를 통해 데이터 유출 위험을 줄일 수 있습니다.
고성능 시나리오: 높은 처리량과 최소 지연 시간이 필요한 애플리케이션은 인메모리 처리 오버헤드 감소의 이점을 누릴 수 있습니다.
디스크 기반 처리를 고려해야 하는 경우:
대용량 파일: 애플리케이션이 매우 큰 파일을 처리해야 하는 경우 메모리 부족을 방지하기 위해 디스크 기반 처리가 필요할 수 있습니다.
리소스가 제한된 환경: 서버 메모리가 제한된 경우 디스크에서 파일을 처리하면 메모리 고갈을 방지하고 리소스 관리를 향상할 수 있습니다.
지속적인 저장 요구: 감사, 백업 또는 향후 검색을 위해 업로드된 파일의 복사본을 보관해야 하는 경우 파일을 디스크에 저장해야 합니다.
외부 스토리지 서비스와의 통합: 대용량 파일의 경우 AWS S3, Google Cloud와 같은 외부 스토리지 서비스에 업로드하는 것이 좋습니다.
- 스토리지 또는 Azure Blob Storage. 이러한 서비스를 사용하면 서버에서 스토리지를 오프로드할 수 있으며, 필요에 따라 클라우드에서 파일을 처리하거나 인메모리 처리를 위해 검색할 수 있습니다.
확장성: 클라우드 스토리지 솔루션은 대용량 파일을 처리하고 중복성을 제공하여 데이터가 안전하고 여러 지리적 위치에서 쉽게 액세스할 수 있도록 보장합니다.
비용 효율성: 클라우드 스토리지를 사용하면 로컬 서버 리소스의 필요성이 줄어들고 종량제 가격이 제공되므로 대용량 파일을 처리하는 데 더 비용 효율적일 수 있습니다.
결론
이 기사에서는 CSV 및 XLS/XLSX 파일을 처리하고, 메모리에서 구문 분석하고, 파일을 디스크에 저장하지 않고 구문 분석된 데이터를 반환하는 NestJS의 사용자 정의 파일 업로드 모듈을 만들었습니다. 이 접근 방식은 Node.js 스트림의 기능을 활용하여 서버에 임시 파일이 남지 않으므로 효율적이고 안전합니다.
또한 메모리 내 파일 처리와 디스크에 파일 저장의 장단점을 살펴보았습니다. 인메모리 처리는 속도, 보안 및 단순성을 제공하지만 이 접근 방식을 채택하기 전에 메모리 사용량과 잠재적인 파일 크기 제한을 고려하는 것이 중요합니다.
엔터프라이즈 애플리케이션을 구축하든 소규모 프로젝트를 구축하든 파일 업로드를 올바르게 처리하고 구문 분석하는 것이 중요합니다. 이 설정을 사용하면 불필요한 서버 저장이나 데이터 보안 문제에 대한 걱정 없이 NestJS에서 파일 업로드를 마스터할 수 있습니다.
아래 댓글 섹션에서 여러분의 생각과 개선 사항을 자유롭게 공유해 주세요!
이 기사가 마음에 들었거나 이러한 도구가 유용하다고 생각했다면 Dev.to에서 저를 팔로우하여 코딩 및 개발에 대한 더 많은 통찰력과 팁을 얻으세요. 여러분의 코딩 여정을 더욱 원활하게 만들어줄 유용한 콘텐츠를 정기적으로 공유합니다.
X(트위터)에서 저를 팔로우하세요. 여기서 프로그래밍과 기술에 대한 더 흥미로운 생각, 업데이트, 토론을 공유합니다! 놓치지 마세요 - 팔로우 버튼을 클릭하세요.
또한 LinkedIn에서 저를 팔로우하여 전문적인 통찰력, 최신 프로젝트 업데이트, 코딩, 기술 동향 등에 대한 토론을 받아보실 수도 있습니다. 개발 실력을 한 단계 끌어올릴 수 있는 귀중한 콘텐츠를 놓치지 마세요 - 함께해요!
위 내용은 NestJS에서 파일 업로드 간소화: 디스크 저장소 없이 CSV 및 XLSX에 대한 효율적인 메모리 내 구문 분석의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

Video Face Swap
완전히 무료인 AI 얼굴 교환 도구를 사용하여 모든 비디오의 얼굴을 쉽게 바꾸세요!

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

각각의 엔진의 구현 원리 및 최적화 전략이 다르기 때문에 JavaScript 엔진은 JavaScript 코드를 구문 분석하고 실행할 때 다른 영향을 미칩니다. 1. 어휘 분석 : 소스 코드를 어휘 단위로 변환합니다. 2. 문법 분석 : 추상 구문 트리를 생성합니다. 3. 최적화 및 컴파일 : JIT 컴파일러를 통해 기계 코드를 생성합니다. 4. 실행 : 기계 코드를 실행하십시오. V8 엔진은 즉각적인 컴파일 및 숨겨진 클래스를 통해 최적화하여 Spidermonkey는 유형 추론 시스템을 사용하여 동일한 코드에서 성능이 다른 성능을 제공합니다.

Python은 부드러운 학습 곡선과 간결한 구문으로 초보자에게 더 적합합니다. JavaScript는 가파른 학습 곡선과 유연한 구문으로 프론트 엔드 개발에 적합합니다. 1. Python Syntax는 직관적이며 데이터 과학 및 백엔드 개발에 적합합니다. 2. JavaScript는 유연하며 프론트 엔드 및 서버 측 프로그래밍에서 널리 사용됩니다.

C/C에서 JavaScript로 전환하려면 동적 타이핑, 쓰레기 수집 및 비동기 프로그래밍으로 적응해야합니다. 1) C/C는 수동 메모리 관리가 필요한 정적으로 입력 한 언어이며 JavaScript는 동적으로 입력하고 쓰레기 수집이 자동으로 처리됩니다. 2) C/C를 기계 코드로 컴파일 해야하는 반면 JavaScript는 해석 된 언어입니다. 3) JavaScript는 폐쇄, 프로토 타입 체인 및 약속과 같은 개념을 소개하여 유연성과 비동기 프로그래밍 기능을 향상시킵니다.

웹 개발에서 JavaScript의 주요 용도에는 클라이언트 상호 작용, 양식 검증 및 비동기 통신이 포함됩니다. 1) DOM 운영을 통한 동적 컨텐츠 업데이트 및 사용자 상호 작용; 2) 사용자가 사용자 경험을 향상시키기 위해 데이터를 제출하기 전에 클라이언트 확인이 수행됩니다. 3) 서버와의 진실한 통신은 Ajax 기술을 통해 달성됩니다.

실제 세계에서 JavaScript의 응용 프로그램에는 프론트 엔드 및 백엔드 개발이 포함됩니다. 1) DOM 운영 및 이벤트 처리와 관련된 TODO 목록 응용 프로그램을 구축하여 프론트 엔드 애플리케이션을 표시합니다. 2) Node.js를 통해 RESTFULAPI를 구축하고 Express를 통해 백엔드 응용 프로그램을 시연하십시오.

보다 효율적인 코드를 작성하고 성능 병목 현상 및 최적화 전략을 이해하는 데 도움이되기 때문에 JavaScript 엔진이 내부적으로 작동하는 방식을 이해하는 것은 개발자에게 중요합니다. 1) 엔진의 워크 플로에는 구문 분석, 컴파일 및 실행; 2) 실행 프로세스 중에 엔진은 인라인 캐시 및 숨겨진 클래스와 같은 동적 최적화를 수행합니다. 3) 모범 사례에는 글로벌 변수를 피하고 루프 최적화, Const 및 Lets 사용 및 과도한 폐쇄 사용을 피하는 것이 포함됩니다.

Python과 JavaScript는 커뮤니티, 라이브러리 및 리소스 측면에서 고유 한 장점과 단점이 있습니다. 1) Python 커뮤니티는 친절하고 초보자에게 적합하지만 프론트 엔드 개발 리소스는 JavaScript만큼 풍부하지 않습니다. 2) Python은 데이터 과학 및 기계 학습 라이브러리에서 강력하며 JavaScript는 프론트 엔드 개발 라이브러리 및 프레임 워크에서 더 좋습니다. 3) 둘 다 풍부한 학습 리소스를 가지고 있지만 Python은 공식 문서로 시작하는 데 적합하지만 JavaScript는 MDNWebDocs에서 더 좋습니다. 선택은 프로젝트 요구와 개인적인 이익을 기반으로해야합니다.

개발 환경에서 Python과 JavaScript의 선택이 모두 중요합니다. 1) Python의 개발 환경에는 Pycharm, Jupyternotebook 및 Anaconda가 포함되어 있으며 데이터 과학 및 빠른 프로토 타이핑에 적합합니다. 2) JavaScript의 개발 환경에는 Node.js, VScode 및 Webpack이 포함되어 있으며 프론트 엔드 및 백엔드 개발에 적합합니다. 프로젝트 요구에 따라 올바른 도구를 선택하면 개발 효율성과 프로젝트 성공률이 향상 될 수 있습니다.
