Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: 이미지 업로드 오브젝트 배열로 변경 (#24) #25

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 43 additions & 7 deletions src/api/imageUpload/image.routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,16 +7,35 @@ const upload = multer({ storage: memoryStorage() });

imageRouter.post(
'/upload',
upload.array('images', 10),
upload.fields([
{ name: 'thumbnail', maxCount: 1 },
{ name: 'meetingSpace', maxCount: 5 },
{ name: 'introSrcs', maxCount: 5 },
]),
async (req: Request, res: Response): Promise<void> => {
try {
if (!req.files || req.files.length === 0) {
if (!req.files) {
res.status(400).json({ message: '이미지 파일이 없습니다.' });
return;
Comment on lines +17 to 19
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🛠️ Refactor suggestion

입력값 검증을 강화하는 것이 좋겠습니다.

현재는 req.files의 존재 여부만 확인하고 있습니다. 각 필드별로 필수값 여부와 파일 형식을 검증하는 것이 좋겠습니다.

다음과 같이 검증 로직을 추가하는 것을 제안드립니다:

      if (!req.files) {
        res.status(400).json({ message: '이미지 파일이 없습니다.' });
        return;
      }
+     
+     const files = req.files as { [fieldname: string]: Express.Multer.File[] };
+     
+     // thumbnail은 필수값으로 처리
+     if (!files.thumbnail || files.thumbnail.length === 0) {
+       res.status(400).json({ message: '썸네일 이미지는 필수입니다.' });
+       return;
+     }
+     
+     // 이미지 형식 검증
+     const allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
+     for (const [category, categoryFiles] of Object.entries(files)) {
+       for (const file of categoryFiles) {
+         if (!allowedMimeTypes.includes(file.mimetype)) {
+           res.status(400).json({ 
+             message: `지원하지 않는 파일 형식입니다: ${file.originalname}` 
+           });
+           return;
+         }
+       }
+     }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if (!req.files) {
res.status(400).json({ message: '이미지 파일이 없습니다.' });
return;
if (!req.files) {
res.status(400).json({ message: '이미지 파일이 없습니다.' });
return;
}
const files = req.files as { [fieldname: string]: Express.Multer.File[] };
// thumbnail은 필수값으로 처리
if (!files.thumbnail || files.thumbnail.length === 0) {
res.status(400).json({ message: '썸네일 이미지는 필수입니다.' });
return;
}
// 이미지 형식 검증
const allowedMimeTypes = ['image/jpeg', 'image/png', 'image/gif'];
for (const [category, categoryFiles] of Object.entries(files)) {
for (const file of categoryFiles) {
if (!allowedMimeTypes.includes(file.mimetype)) {
res.status(400).json({
message: `지원하지 않는 파일 형식입니다: ${file.originalname}`
});
return;
}
}
}

}

const imageUrls = await uploadImages(req.files as Express.Multer.File[]);
res.status(200).json({ imageUrls });
const files = req.files as { [fieldname: string]: Express.Multer.File[] };

const result: { [key: string]: string[] } = {
thumbnail: [],
meetingSpace: [],
introSrcs: [],
};

// 각 카테고리별 이미지 업로드 처리
for (const [category, categoryFiles] of Object.entries(files)) {
if (categoryFiles && categoryFiles.length > 0) {
const urls = await uploadImages(categoryFiles);
result[category as keyof typeof result] = urls;
}
}

res.status(200).json(result);
} catch (error) {
console.error('이미지 업로드 오류:', error);
res.status(500).json({ message: '이미지 업로드 실패' });
Expand All @@ -26,6 +45,23 @@ imageRouter.post(

export { imageRouter };

// curl -X POST -H "Content-Type: multipart/form-data" -F "[email protected]" -F "[email protected]" -F "[email protected]" http://localhost:3000/api/images/upload
// 이렇게 여러개 이미지를 넣으면 이렇게 반환됩니다.
// {"imageUrls":["https://d25zqr3uop6qu8.cloudfront.net/fb5f5d18-61c2-4ede-b90c-4d454526b717.jpeg","https://d25zqr3uop6qu8.cloudfront.net/2dc24822-1e96-424f-b5b5-c93ea98889d3.jpeg","https://d25zqr3uop6qu8.cloudfront.net/b4282321-eb7b-4dcc-82f9-28a26da6f113.jpeg"]}%
// curl -X POST \
// -H "Content-Type: multipart/form-data" \
// -F "[email protected]" \
// -F "[email protected]" \
// -F "[email protected]" \
// -F "[email protected]" \
// -F "[email protected]" \
// http://localhost:3000/api/images/upload

// {
// "thumbnail": ["https://cloudfront.url/image1.jpg"],
// "meetingSpace": [
// "https://cloudfront.url/image2.jpg",
// "https://cloudfront.url/image3.jpg"
// ],
// "introSrcs": [
// "https://cloudfront.url/image4.jpg",
// "https://cloudfront.url/image5.jpg"
// ]
// }