What is the MVC?
•
MVC는 Separation of Concern를 위해 고안된 디자인 패턴이다.
•
Models는 기본적으로 프로젝트에서 쓰이는 데이터들을 표현하는 Object를 말한다. 즉, 데이터들을 활용 (불러오거나 저장하는 등)하는데 쓰이는 것들을 말한다.
•
Views는 이전에 작성했던 HTML 파일들이나, Template 파일들을 의미한다. 이런 파일들은 우리가 실제로 볼 수 있는 것들을 말한다. 사용자가 원하는 적절한 Content들을 보여주는 역할을 담당한다. 가공된 데이터들이 Template Engine에 주입되어 Template Engine이 View를 Render하도록 한다.
•
Controllers는 위에서 언급한 Models와 Views를 연결 포인트라고 할 수 있다. 일반적으로 Views는 Application에서 쓰이는 로직들을 신경 쓰지 않고 보여주는 역할만 수행하고, Models는 오로지 데이터들을 어떻게 불러오고 어떻게 저장할지만 신경쓰기 때문에 Controllers는 불러온 데이터들을 특정 Logic으로 처리하여 Views에 보내는 역할을 한다.
•
즉, Controller는 일종의 Middleman 역할을 수행한다. 그렇다면 Routes들은 무엇일까? → Routes들은 특정 Path에 따라서 실행되는 HTTP Method에 따라 어떤 Controller의 Code를 수행해야 하는지 정해준다.
•
또한, Express가 Middleware를 사용한다는 특징 덕에 Controller 역시 여러 Middleware의 Function들로 나뉘어 구현된다. (특정 Logic에 따라서 구분 짓는다.)
Defining a Model
•
Model을 정의할 때, ES5에서는 function 키워드를 이용하여 function Object() {} 와 같이 정의하고, ES6에서는 class Object {}와 같이 정의할 수 있다.
•
ES6 기준으로 하여, Class 선언 시 생성자를 작성해야 하는데 이는 constrctor function을 통해서 작성할 수 있다. constructor() {}로 이용한다.
Storing Data in Files Via the Model
•
Path Module과 File System Module을 이용한다.
•
Path Module을 이용하여 디렉토리와 파일 명을 지정하고 File System Module을 통해서 파일에 접근한다.
•
File System Module의 readFile()을 통해서 파일을 읽을 수 있지만, 매우 매우 큰 파일에 대해서는 readFile() 보다 더 효율적인 방법이 있다. 파일로 작업하기 전에 파일을 다 읽을 때까지 기다리는 방법이 아닌, Stream을 이용하는 방식이 이에 해당 된다. 이 때는 createReadStream()을 이용한다. 이 때 readFile()의 첫 번째 인자는 Path, 두 번째 인자는 Error와 Buffer를 인자로 갖는 Callback Function이다.
•
File System Module의 writeFile()을 통해서 파일을 쓸 수 있다. writeFile()의 첫 번째 인자는 Path, 두 번째 인자는 Write할 Content(JSON 파일로 저장 시 JSON으로 먼저 만들어주는 과정이 필요하다.), 세 번째 인자는 Error을 인자로 갖는 Callback Function이다.
•
JSON 파일의 경우, JSON.parse() Method를 이용하여 Decoding, JSON.stringify() Method를 이용하여 Encoding 할 수 있다.
•
파일로 읽고 쓸 때, JSON Array로 잘 데이터를 처리를 한 것 같음에도 Length를 활용 했을 때 오류가 생긴다면 그 이유는 무엇인가? → Node.js 특성 상 Blocking Code는 지양해야 한다. 그러하기 때문에 readFileSync()나 writeFileSync()는 이용을 지양했다. 즉, readFile()과 writeFile()은 비동기 코드이다. 두 Method를 정의하면서 등록한 Callback Function들은 Event Emitter에 붙어서 Event가 발생할 때 호출 되도록 설계된 Method들이다. 따라서 Event가 발생하면서 Event Emitter에 붙어서 Callback Function이 해당 Event를 처리하는 동안 이 함수를 호출 하고 있는 Method는 이미 return을 해버려서 Length 자체를 이용을 못 하는 것이다. 코드에는 이상이 없지만 Length를 이용하려고 하면 'undefined'가 출력되는 이유가 이런 것이다.
•
해당 문제에 대해서 고치는 방법은 여럿 있겠지만, readFile()과 writeFile() 이용하는 Method에 추가 인자를 받는 방법으로 해결할 수 있다. 추가 인자는 Callback Function이다. 예를 들어서, cb라는 Callback Function을 받았다고 치자. 원래 Method에는 [] 와 같은 일반 배열이 return 되는 것 일텐데, 이를 cb([])로 처리한다. 그렇다면 readFile()과 writeFile()을 갖는 이 함수를 호출 할 때, 인자로 넣는 cb는 어떤 Callback Function 인가? → 특정 배열을 이용하려는 Logic들을 Anonymous Function으로 처리하여 Callback Function 내로 Logic을 옮겨서 처리한다.