From c8b64e58341f6cb4169ea0a1a2d57d758ee30c3a Mon Sep 17 00:00:00 2001 From: HyungWookChoi Date: Thu, 14 Dec 2023 21:13:33 +0900 Subject: [PATCH] =?UTF-8?q?S3=20=EC=97=85=EB=A1=9C=EB=93=9C=20=EB=9D=BC?= =?UTF-8?q?=EC=9A=B0=ED=84=B0=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.js | 4 +- routes/badgeRouter.js | 41 +++++++++++-------- routes/challengeRouter.js | 21 ++++++++++ routes/indexRouter.js | 2 +- routes/s3Router.js | 76 ++++++++++++++++++++++++++++++++++++ routes/userRouter.js | 8 +++- services/challengeService.js | 2 - 7 files changed, 132 insertions(+), 22 deletions(-) create mode 100644 routes/s3Router.js diff --git a/app.js b/app.js index c4f3588..8a5d3fb 100644 --- a/app.js +++ b/app.js @@ -4,11 +4,13 @@ const cors = require('cors'); const path = require('path'); const cookieParser = require('cookie-parser'); const logger = require('morgan'); +const { swaggerUi, specs } = require('./swagger/swagger'); const indexRouter = require('./routes/indexRouter'); const userRouter = require('./routes/userRouter'); const challengeRouter = require('./routes/challengeRouter'); const badgeRouter = require('./routes/badgeRouter'); +const s3Router = require('./routes/s3Router'); require('dotenv').config(); @@ -32,7 +34,7 @@ app.use('/users', userRouter); app.use('/challenges', challengeRouter); app.use('/badges', badgeRouter); -const { swaggerUi, specs } = require('./swagger/swagger'); +app.use('/s3', s3Router); app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(specs)); diff --git a/routes/badgeRouter.js b/routes/badgeRouter.js index a1c71a0..9e51ff1 100644 --- a/routes/badgeRouter.js +++ b/routes/badgeRouter.js @@ -7,23 +7,30 @@ const { badgeController } = require('../controllers/badgeController'); /** * @swagger * paths: - * /badges: - * get: - * tags: [Badges] - * summary: "뱃지 조회" - * description: "뱃지 조회" - * responses: - * "200": - * description: "뱃지 조회 요청에 성공했습니다." - * content: - * application/json: - * schema: - * type: object - * properties: - * success: - * type: boolean - * message: - * type: string + * /badges: + * get: + * tags: [Badges] + * summary: "뱃지 조회" + * description: "뱃지 조회" + * parameters: + * - name: "Authorization" + * in: "header" + * description: "Access Token" + * required: true + * schema: + * type: "string" + * responses: + * "200": + * description: "뱃지 조회 요청에 성공했습니다." + * content: + * application/json: + * schema: + * type: object + * properties: + * success: + * type: boolean + * message: + * type: string */ router.get('/', badgeController.getBadges); diff --git a/routes/challengeRouter.js b/routes/challengeRouter.js index 7f17358..9a3dcfa 100644 --- a/routes/challengeRouter.js +++ b/routes/challengeRouter.js @@ -12,6 +12,13 @@ const { challengeController } = require('../controllers/challengeController'); * tags: [Challenges] * summary: "챌린지 생성" * description: "챌린지 생성" + * parameters: + * - name: "Authorization" + * in: "header" + * description: "Access Token" + * required: true + * schema: + * type: "string" * requestBody: * content: * application/json: @@ -47,6 +54,13 @@ router.post('/', challengeController.createChallenge); * tags: [Challenges] * summary: "챌린지 수락" * description: "챌린지 수락" + * parameters: + * - name: "Authorization" + * in: "header" + * description: "Access Token" + * required: true + * schema: + * type: "string" * requestBody: * content: * application/json: @@ -116,7 +130,14 @@ router.get('/upcoming/:id', challengeController.getUpcomingChallenge); * tags: [Challenges] * summary: "진행 중인 챌린지의 진행 상태 조회" * description: "진행 중인 챌린지의 진행 상태 조회" + * * parameters: + * - name: "Authorization" + * in: "header" + * description: "Access Token" + * required: true + * schema: + * type: "string" * - in: path * name: id * type: integer diff --git a/routes/indexRouter.js b/routes/indexRouter.js index 0e7a811..4e31bed 100644 --- a/routes/indexRouter.js +++ b/routes/indexRouter.js @@ -3,7 +3,7 @@ const express = require('express'); const router = express.Router(); router.get('/', (req, res, next) => { - res.send('Hello, Dodal!'); + res.redirect('/api-docs'); }); module.exports = router; diff --git a/routes/s3Router.js b/routes/s3Router.js new file mode 100644 index 0000000..4fc82f4 --- /dev/null +++ b/routes/s3Router.js @@ -0,0 +1,76 @@ +const express = require('express'); + +const multer = require('multer'); +const multerS3 = require('multer-s3'); +const { S3Client } = require('@aws-sdk/client-s3'); + +const router = express.Router(); + +const s3 = new S3Client({ + region: 'ap-northeast-2', + credentials: { + accessKeyId: process.env.AWS_ACCESS_KEY_ID, + secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY, + }, +}); + +const upload = multer({ + storage: multerS3({ + s3: s3, + bucket: 'dodals3', + key: function (req, file, cb) { + cb(null, Date.now().toString()); + }, + }), + limits: { fileSize: 5 * 1024 * 1024 }, // 5MB +}); + +/** + * @swagger + * /s3/upload: + * post: + * summary: S3에 파일 업로드 + * requestBody: + * content: + * multipart/form-data: + * schema: + * type: object + * properties: + * file: + * type: string + * format: binary + * responses: + * '200': + * description: File uploaded successfully + * content: + * application/json: + * example: + * success: true + * message: '이미지 업로드에 성공했습니다.' + * data: 'https://your-s3-bucket-url/file-key' + * '400': + * description: Bad request or file upload failed + * content: + * application/json: + * example: + * success: false + * message: '이미지 업로드에 실패했습니다.' + */ +router.post('/upload', upload.single('file'), (req, res) => { + try { + const fileUrl = req.file.location; + res.status(200).json({ + success: true, + message: '이미지 업로드에 성공했습니다.', + data: fileUrl, + }); + } catch (error) { + console.error(error); + res.status(400).json({ + success: false, + message: '이미지 업로드에 실패했습니다.', + }); + } +}); + +module.exports = router; diff --git a/routes/userRouter.js b/routes/userRouter.js index e6a5b2d..820f02a 100644 --- a/routes/userRouter.js +++ b/routes/userRouter.js @@ -8,7 +8,6 @@ const { userController } = require('../controllers/userController'); * @swagger * tags: * name: Users - * description: 유저 추가 수정 삭제 조회 */ /** @@ -129,6 +128,13 @@ router.post('/signUp', userController.signUp); * tags: [Users] * summary: "유저 프로필 조회" * description: "유저 프로필 조회" + * parameters: + * - name: "Authorization" + * in: "header" + * description: "Access Token" + * required: true + * schema: + * type: "string" * responses: * "200": * description: "유저 프로필 조회에 성공했습니다." diff --git a/services/challengeService.js b/services/challengeService.js index a27969f..9608518 100644 --- a/services/challengeService.js +++ b/services/challengeService.js @@ -117,8 +117,6 @@ const challengeService = { submitImage: async (req, res) => { try { - // 이미지 업로드 미들웨어를 사용 - //s3, upload 정보는 최상단에 선언 upload.single('image')(req, res, (err) => { if (err) { return res.status(500).json({ success: false, err: err });