[2023-2 WINK Project] 1. Express 시작하기

2024. 4. 20. 11:49·Back-end/Node.js
목차
  1. 1. 프로젝트 시작
  2. 2. 패키지 설치
  3. 3. 프로젝트 구조
  4. app.js
  5. routes / user.js
  6. controller / userController.js
반응형

1. 프로젝트 시작

프로젝트 시작 시 패키지 정보들을 저장해야 하기 위한 기록을 남겨야 한다

npm init


터미널에서 위 코드 실행 시 만들고자 하는 앱의 정보들을 기입할 수 있다.

npm init

2. 패키지 설치

npm i [패키지명]


현재 진행하는 프로젝트에서는 express, express-session, morgan, dotenv, cookie-parser, passport, nodemon 모듈을 사용하고 있다.

  • express-session : express에서 세션을 관리하기 위한 모듈
  • morgan : 로깅을 관리해주는 모듈
GET /favicon.ico 500 6.647 ms - 26
  • dotenv : 오픈 소스에 코드를 올릴 때 노출되면 안되는 값들을 .env 파일에 모아두기 위한 모듈
  • cookie-parser : 쿠키 관리 모듈
  • passport : 로그인 시 필요한 세션과 보안에 대한 처리 모듈
  • nodemon : 코드 변경 시 자동으로 서버 재시작시켜주는 모듈
npm i -D nodemon 으로 설치

3. 프로젝트 구조

  • app.js
  • routes (라우터 모음)
  • controller (비즈니스 로직)
  • models (엔티티)
  • .env (보안이 필요한 키값 사용)
  • package.json

app.js

- 기본 구조

const express = require('express');
const session = require('express-session');
const morgan = require('morgan');


require('dotenv').config(); // .env 파일 연결

const app = express();

app.set('port', process.env.PORT || 8080)

// 라우터 import 예시
const userRouter = require("./routes/user");

// middleware 설정.
app.use(morgan('dev')); // morgan 적용
app.use(express.static(path.join(__dirname, 'public'))); // 정적 파일 가져오기
app.use(express.json()); // json 형식 사용
app.use(express.urlencoded({ extended: true }));
app.use(cookieParser(process.env.COOKIE_SECRET)); // 쿠키 인증 키
app.use(session({ // 세션 사용.
    resave: false,
    saveUninitialized: false,
    secret: process.env.COOKIE_SECRET,
}));

// Router 연결 예시
app.use("/user", userRouter);


// 에러 라우터 미들웨어
app.use((req, res, next) => {
  const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
  error.status = 404;
  next(error);
});

// 에러 로깅 미들웨어
app.use((err, req, res, next) => {
  console.error(err.stack);
  res.status(500).send("네트워크 에러 발생");
});

app.listen(app.get("port"), () => {
  console.log(app.get("port"), "번 포트에서 대기 중");
});

 

routes / user.js

const express = require('express');
const { editMember, getUser, checkProfile} = require('../controller/userController');
const { uploadS3 } = require('../util/S3/config')

const router = express.Router();

router.route('/update')
    .get(getUser)
    .patch(uploadS3.single('profile'), editMember);

module.exports = router;

 

controller / userController.js

const AWS = require('aws-sdk');
const Member = require("../models/member");
const Seat = require("../models/seat")

const s3 = new AWS.S3({
    accessKeyId: process.env.AWS_ACCESS_KEY,
    secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
    region: 'ap-northeast-2',
});


// 이전 프로필 사진 체크 후 삭제
exports.checkProfile = async (req, res, next) => {
    const findOne = Member.findOne({ kakaoId: req.token.kakaoId });

    try {
        if (findOne === null) res.status(401).send('Not exist token')
        else if (findOne.profile !== null) { // 기존 프로필이 있는 경우 해당 user의 프로필 사진 삭제.
            const params = {
                Bucket: 'wink-2023-2-bucket',
                Key: findOne.profile.split('/').pop(), // 파일명만 추출
            };

            s3.deleteObject(params, (err, data) => {
                if (err) {
                    console.error(err);
                    return res.status(500).send('Error deleting file from S3.');
                }
                next();
            });
        } else {
            next();
        }
    } catch (e) {
        next(e);
    }
}

// 회원 정보 수정
exports.editMember = async (req, res, next) => {
    try {
        const member = await Member.updateOne({ kakaoId: req.token.kakaoId }, {
               $set: {
                    name: req.body.name,
                    profile: req.file.location ? req.file.location : null,
                    club: req.body.club,
                    studentId: req.body.studentId
                }});
        return res.status(200).json(member);
    } catch (err) {
        next(err);
    }
}

// 회원 정보 조회
exports.getUser = async (req, res, next) => {
    try {
        const member = await Member.findOne({ kakaoId: req.token.kakaoId });
        const seat = await Seat.findOne({ memberId: member._id });

        return res.status(200).json({
            member,
            seatNumber: seat ? seat.number : null
        })
    } catch (error) {
        next(error)
    }
}

 

다음은 예시로 user model과 user 관련한 router, 그리고 router에 들어가는 비즈니스 로직 UserController를 구현한 것이다.

 

이런 식으로 Model / Controller / Router / config 등 layer 별로 프로젝트를 세분화하는게 유지보수에 용이하다.

반응형

'Back-end > Node.js' 카테고리의 다른 글

[Express.js] Passport 모듈을 활용한 카카오 소셜 로그인 구현  (3) 2024.06.27
[2023-2 WINK Project] 2. MongoDB 사용하기  (0) 2024.05.01
  1. 1. 프로젝트 시작
  2. 2. 패키지 설치
  3. 3. 프로젝트 구조
  4. app.js
  5. routes / user.js
  6. controller / userController.js
'Back-end/Node.js' 카테고리의 다른 글
  • [Express.js] Passport 모듈을 활용한 카카오 소셜 로그인 구현
  • [2023-2 WINK Project] 2. MongoDB 사용하기
류건
류건
개발 일지
  • 류건
    건's Dev
    류건
  • 전체
    오늘
    어제
    • 분류 전체보기 (101) N
      • Back-end (56)
        • Spring (31)
        • Nest.js (3)
        • Next.js (2)
        • Node.js (3)
      • Infra & Cloud (21)
        • Cloud Computing (6)
        • Docker (3)
        • AWS (7)
      • Java (2)
      • Computer Science (12)
        • Computer Network (0)
        • Operating System (0)
        • 정보 보호와 시스템 보안 (12)
        • Software Architecture (0)
      • 회고록 (9) N
        • 우아한테크코스 (3)
        • Naver BoostCamp (5) N
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    JPA
    보안
    ddl-auto
    EC2
    Github Actions
    public key
    어노테이션
    aws
    CI/CD
    db
    JWT
    정보보호
    ssl
    Webflux
    express.js
    CD
    CORS
    고가용성
    WebClient
    Kafka
    Docker
    오블완
    Spring Boot
    https
    node.js
    Nest.js
    Spring
    티스토리챌린지
    Lock
    nginx
  • 최근 댓글

  • 최근 글

  • 반응형
  • hELLO· Designed By정상우.v4.10.0
류건
[2023-2 WINK Project] 1. Express 시작하기
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.