NodeJS (3) ExpressJS를 활용한 유저 데이터 저장 및 반환
지난 시간까지
Express에서 제공하는 body 메소드를 통해서
클라이언트가 POST해준 데이터를 받아온 뒤,
use와 urlencoded를 통해 파싱해주는 법을 배웠다.
이제 이렇게 입력받은 유저이름에 관한 데이터를
서버의 특정 공간에 파일의 형태로 저장하는 방법에 대해 알아보자.
프로젝트의 폴더에 data라는 이름으로 새로운 폴더를 추가해주고,
users.json이라는 파일을 만들어주자.
앞선 package.json 파일에서 그 형태를 보았듯이
중괄호의 형태로 데이터를 저장하는 형태이며, xml, csv, yaml과 같이 업계표준에 가까운 양식이다.
이렇게 갓 만든 제이슨 파일에 대괄호 한쌍을 적어주고, app.js로 돌아가자.
const express = require('express');
const app = express();
app.use(express.urlencoded({extended: false}));
app.get('/', function(req,res){
res.send('<form action="/store-user" method="POST"><label>Your Name</label><input type="text" name="userName"><button>Submit</button></form>');
});
app.post('/store-user',function(req,res){
const userName = req.body.username;
// 파일에 해당내용을 추가
}
파일을 열고 닫기 위해서는
NodeJS에 빌트인된 fs 패키지를 사용하면된다. 별도의 임포트 없이
const fs = require('fs'); 를 코드상단에 추가해주자.
fs는 파일시스템의 준말이며,
fs라는 이름을 가진 상수에 해당 패키지의 기능이 담긴 객체를 저장해서
편하게 꺼내쓰겠다는 의미를 가진다.
const express = require('express');
const app = express();
const fs = require('fs');
const path = require('path');
app.use(express.urlencoded({extended: false}));
또한 파일을 읽어오기 위해서는 파일의 경로가 필요하다.
path 패키지를 통해 파이썬의 os.path처럼 현재 실행되는 프로그램의 경로를 찾아오는 기능을 추가하고..
__dirname이라는 valid js variable name을 사용하여
const filePath = path.join(__dirname + '/data'); 코드를 작성해주자.
이 과정을 통해서 데이터를 저장할 target file이 존재하는 경로를 알아낼 수 있다.
(* 변수명 앞에 _ _ , double underscore 가 달린 컨벤션은 참 많이 접하게 된다.
클래스 내부의 캡슐화, 은닉 등과 관련되어있다)
그래서 파일에 데이터를 저장하는 방법은 다음과 같다.
0. 서버로부터 받은 유저데이터 userName을 찾고
1. 데이터를 저장할 파일의 경로를 찾은 뒤 ( path 패키지 사용 )
2. 해당 파일의 모든 데이터를 read해서 existingUsers배열을얻고 ( + JSON포맷 데이터를 파싱하고)
3. 그 데이터 뒤에 userName을 추가한 뒤
4. 변경된 배열을 다시 해당파일에 write한다.
app.post('/store-user', function(req,res){
const userName = req.body.username;
const filePath = path.join(__dirname,'data','users.json');
const fileData = fs.readFileSync(filePath);
const existingUsers = JSON.parse(fileData);
existingUsers.push(userName);
fs.writeFileSync(filePath,JSON.stringify(existingUsers));
res.send('<h1>User name stored!</h1>');
})
Json파일을 읽고 쓰는 과정에서
빌트인 JSON 패키지를 사용하여 JS자료구조를 RAW데이터로 자연스럽게 바꾸는 과정이 중요하다.
JSON.parse()와 JSON.stringify()를 잘 기억해주자.
//
const express = require('express');
const app = express();
const fs = require('fs');
const path = require('path');
app.use(express.urlencoded({extended: false}));
app.get('/currenttime', function(req, res) {
res.send('<h1>' + new Date().toISOString() + '</h1>');
} );
app.get('/', function(req, res) {
res.send('<form action="/store-user" method="POST"><label>Your Name</label><input type="text" name="username"><button>Submit</button></form>');
}); // localhost:3000/
app.post('/store-user', function(req,res){
const userName = req.body.username;
const filePath = path.join(__dirname,'data','users.json');
const fileData = fs.readFileSync(filePath);
const existingUsers = JSON.parse(fileData);
existingUsers.push(userName);
fs.writeFileSync(filePath,JSON.stringify(existingUsers));
res.send('<h1>User name stored!</h1>');
})
app.listen(3000)
이렇게 작성된 코드를 저장하고 Node서버를 돌려주고
localhost:3000에서 기능을 확인하자.
이름을 쳐주면...
제대로 localhost:3000/store-user 페이지로 넘어가지고
JSON파일에도 input data가 잘 추가된 것을 확인할 수 있다.
---
이제 마지막으로 이렇게 저장된 데이터에 대하여
request를 날린 클라이언트에게 response를 되돌려주는 기능을 추가해보자.
app.get('/users', function(req, res){
const filePath = path.join(__dirname,'data','users.json');
const fileData = fs.readFileSync(filePath);
const existingUsers = JSON.parse(fileData);
res.send(existingUsers);
})
이런식으로 get메소드의 라우터를 추가하고
/users 경로로 찾아오는 클라이언트에게
위에서 만들었던 ./data/users.json 파일의 내용을 알려주는 기능을 구현할 수 있다.
서버에 alice와 bob을 보내 username을 추가한 뒤...
localhost:3000/users에 접속하면
아까 추가했던 Max에 alice와 bob이 추가되어 출력되는 것을 볼 수 있다.
json 파일을 통째로 출력하는 것도 한 방법이지만
결국 웹페이지 상에서 HTML의 원소로 출력하는 방법을 알아놓는 것이,
이후 웹사이트를 다루는 데 편리할 것이다.
app.get('/users', function(req, res){
const filePath = path.join(__dirname,'data','users.json');
const fileData = fs.readFileSync(filePath);
const existingUsers = JSON.parse(fileData);
let responseData = '<ul>';
for (const user of existingUsers){
responseData += '<li>' + user + '</li>'
}
responseData += '</ul>';
res.send(responseData);
})
responseData에 앞뒤로 <ul>과 </ul>태그를 달아주고
배열의 요소마다 <li>+user+</li>로 추가를 해준 뒤
send해주는 방식으로
'/users'에 대한 라우터를 위와 같이 변경해주면..
HTML의 unordered list 원소로 출력이 되는 것을 확인할 수 있다.
---
출처 : 100일 코딩 챌린지 - Web Development 부트캠프, Maximilian Schwarzmuller, Udempy