MVC parttern


Dwitter말고 새로운 프로젝트를 시작하려고하니, MVC 패턴을 중요시 여겨 프로젝트를 진행해야 보다, 깔끔하게 진행될 거 같아 복습할겸 이렇게 게시글을 써본다.

강의에서 들었을때 MVC에 대해 난 되게 잘 이해했다고 생각했는데, 게시글을 쓰며 여러군데를 찾아보니까 조금 아쉽게 이해한 거 같았다.

우선 MVC가 무엇인지부터 살펴보자.

MVC

MVC는 Model - View - Controller의 앞글자만 따서 만든 단어이다. 세가지가 상호작용하며 진행되는데, 이로 인해 비지니스 로직을 수정할 때, 온갖 코드를 들쑤시며 전부 수정할 소요 없이 알아서 딱 잘 깔끔하고 센스있게 고칠 수 있게 된다. 아래는 상호작용하는 것에 대한 사진이다.

dwitter5

Model

  • Controller와 Database랑 연동되어서 작동한다.
  • DB와의 호흡,, 화합,,, 이 주 목적이다.
  • Client / View에 노출되지 않는다.

Controller

  • 사용자의 요청을 받고 응답을 조종한다. 즉, 생각하는건 거의 다 지 몫이다. 비지니스 로직에 해당되는 부분.
  • View 요청이 들어와서 Controller에서 생각한다음 Model에 데이터 보내달라하고 그걸 받아 View에 다시 띄우는 모든 역할은 Controller가 한다. 바쁨.

View

  • 클라이언트에 나타나는 부분.
  • HTML / CSS / JS 예쁘게 꾸미고, 화려하게 움직여 표현하는게 얘.
  • 확실하진 않지만, 백엔드에서의 View는 Router에 해당한다고 생각한다. 제일 바깥에서 Client랑 소통하려하는게 Router기 때문이다.

말로만 하면 이해안될 수 있으니 Dwitter에서의 예시를 가져와봤다.

app.use("/tweets", tweetsRouter);

이렇게 Router타고 이동하면

const router = express.Router();


// GET /tweets
// GET /tweets?username=:username
router.get("/", isAuth, tweetController.getTweets);

// GET /tweets/:id
router.get("/:id", isAuth, tweetController.getTweet);

// POST /tweets
router.post("/", isAuth, validateTweet, tweetController.createTweet);

// PUT /tweets/:id
router.put("/:id", isAuth, validateTweet, tweetController.updateTweet);

// DELETE /tweets/:id
router.delete("/:id", isAuth, tweetController.deleteTweet);

// DELETE /tweets?username=:username
router.delete("/", isAuth, tweetController.deleteTweetByUserId);

각 api마다 Controller에 어떤 함수를 실행시켜야하는지 가르킨다. 이게 View다.

그리고 여기서 updateTweet 함수를 예로들면,

export async function updateTweet(req, res) {
    const id = req.params.id;
    const text = req.body.text;
    const tweet = await tweetRepository.getById(id);
    if (!tweet) {
        return res.sendStatus(404);
    }
    const reqUserId = req.userId.toString;
    const reqTweetId = tweet.userId.toString;
    if (reqUserId !== reqTweetId) {
        return res.sendStatus(403);
    }
    const updated = await tweetRepository.update(id, text);
    res.status(200).json(updated);
}

이런식으로 구성되어있다.

여기서 보면 tweet을 찾지 못했을 때 404에러를 띄워준다던가, UserId와 TweetId가 다르다면 다른 사용자가 삭제를 시도한것이기 때문에 403에러를 띄워주는 등 생각해서 뱉어내는 역할인 Controller다.

그 후, Id, text 값을 받아 getById와 update 함수를 사용하였는데, update만 예시를 든다면

const Tweet = sequelize.define("tweet", {
    id: {
        type: DateTypes.INTEGER,
        autoIncrement: true,
        allowNull: false,
        primaryKey: true,
    },
    text: {
        type: DateTypes.TEXT,
        allowNull: false,
    },
});

export async function update(id, text) {
    return Tweet.findByPk(id, {
        ...INCLUDED_USER,
    }).then((tweet) => {
        tweet.text = text;
        return tweet.save();
    });
}

이런식으로 구성되어있는데, 나는 참고로 Sequelize ORM을 사용한 코드이다. 보다싶이 데이터와 실질적으로 접근하고, 바꾸는 역할을 하는 여기가 Model이다.

확실히 100% 블로그에 한번 더 정리하니까 이젠 안 까먹을 거 같다. 좋다 좋아.


© 2021. All rights reserved.

Powered by Hydejack v9.2.1