728x90

우연히 들어가게 된 대학 연구실에서 웹 서버를 구현하는 과제를 받게 되었는데, 이를 Node.js로 구현을 하게 되었다.


여기에 추가적인 사항은 restful 한 구현이면 좋겠다는 것이였고, xml또는 json 형식을 데이터 형태로 교환하면 좋을 것 같다는 얘기를 해주었다.


그래서 이것들을 만족시킬 수 있도록 구현을 해보았다.


1차 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
var http = require('http');
var fs = require('fs');
var url = require('url');
var template = require('./lib/template.js');
 
 
//나의 목표 : https://poiemaweb.com/js-rest-api
 
var app = http.createServer(function(request,response){
  var _url = request.url;
  //동적인 접근을 하도록 설정해준다.
  var queryData = url.parse(_url, true).query;
  var pathname = url.parse(_url, true).pathname;
  //가독성을 높이기 위해서 title로 묶어주었다.
  var title = queryData.id;
  var qs = require('querystring');
  console.log(queryData.id);
  console.log(url.parse(_url, true));
  var description = 'Hello, Node.js';
  var contents = fs.readFileSync("./data/data.json");
  var jsonContent = JSON.parse(contents);
  console.log(jsonContent.person[0].owner);
  console.log(jsonContent.person[0]);
  console.log(Object.keys(jsonContent.person).length);
 
  //처음 메인화면
  if(pathname === '/')
  {
    if(title == undefined){
      title = 'Welcome';
 
      // var list = template.JSONList(jsonContent.person);
 
      var list = '<ol>';
      for(var i=0;i<Object.keys(jsonContent.person).length;i++){
        // var string = JSON.stringify(jsonContent.person[i]);
        console.log(jsonContent.person[i].owner);
        list = list + `<li><a href="/?id=${i+1}">${jsonContent.person[i].owner}</a></li>`;
      }
      list = list + '</ol>';
 
      var html = template.HTML(title, list, `<h2>${title}</h2>${description}`, `<a href="/post">post</a>`);
      response.writeHead(200);
      response.end(html);
 
 
 
      // //data폴더의 항목을 읽어 목록으로 만든다.(default)
      // fs.readdir('./data',(err, fileList)=>{
      //   //함수를 활용해 코드의 반복을 줄인다.
      //   var list = template.list(fileList);
      //   var html = template.HTML(title, list, `<h2>${title}</h2>${description}`, `<a href="/post">post</a>`);
      //   response.writeHead(200);
      //   response.end(html);
      // });
 
    }
    else{
      title = jsonContent.person[title-1].owner
      var list = '<ol>';
      for(var i=0;i<Object.keys(jsonContent.person).length;i++){
        // var string = JSON.stringify(jsonContent.person[i]);
        console.log(jsonContent.person[i].owner);
        list = list + `<li><a href="/?id=${i+1}">${jsonContent.person[i].owner}</a></li>`;
      }
      list = list + '</ol>';
 
      var description = `
      phoneNumber : ${jsonContent.person[1].phoneNumber}
      owner : ${jsonContent.person[1].owner}
      corporation : ${jsonContent.person[1].corporation}
      `
 
      var html = template.HTML(title, list, `<h2>${title}</h2>${description}`,`<a href="/post">post</a>
      <a href="/update?id=${title}">update</a>
      <form action="/delete_process" method="post">
        <input type="hidden" name="id" value=${title}>
        <input type="submit">
      </form>
      `);
      response.writeHead(200);
      response.end(html);
 
 
 
 
      // title = jsonContent.person[title-1].owner
      // var list = '<ol>';
      // for(var i=0;i<Object.keys(jsonContent.person).length;i++){
      //   // var string = JSON.stringify(jsonContent.person[i]);
      //   console.log(jsonContent.person[i].owner);
      //   list = list + `<li><a href="/?id=${i+1}">${jsonContent.person[i].owner}</a></li>`;
      // }
      // list = list + '</ol>';
      //
      // var description = `
      // phoneNumber : ${jsonContent.person[1].phoneNumber}
      // owner : ${jsonContent.person[1].owner}
      // corporation : ${jsonContent.person[1].corporation}
      // `
      //
      // var html = template.HTML(title, list, `<h2>${title}</h2>${description}`,`<a href="/post">post</a>
      // <a href="/update?id=${title}">update</a>
      // <form action="/delete_process" method="post">
      //   <input type="hidden" name="id" value=${title}>
      //   <input type="submit">
      // </form>
      // `);
      // response.writeHead(200);
      // response.end(html);
 
 
        //default;
        // fs.readFile(`data/${title}`, 'utf8', (err, description) => {
        //   //if(err) throw err;
        //   //템플릿을 활용해 문서를 처리하였다.
        //   fs.readdir('./data',(err, fileList)=>{
        //     var list = template.list(fileList);
        //     var html = template.HTML(title, list, `<h2>${title}</h2>${description}`,`<a href="/post">post</a>
        //     <a href="/update?id=${title}">update</a>
        //     <form action="/delete_process" method="post">
        //       <input type="hidden" name="id" value=${title}>
        //       <input type="submit">
        //     </form>
        //     `);
        //     response.writeHead(200);
        //     response.end(html);
        //   });
        // })
    }
  }
  else if(pathname === '/get'){
 
  }
  //post방식 구현
  else if(pathname === '/post'){
    var title = 'WEB - post';
    fs.readdir('./data',(err, fileList)=>{
      //함수를 활용해 코드의 반복을 줄인다.
      var list = template.list(fileList);
      var html = template.HTML(title, list, `
        <form action="/post_process" method="post">
          <p><input type="text" name="title" placeholder ="title"></p>
          <p>
            <textarea name="description" rows="8" cols="80" placeholder="description"></textarea>
          </p>
          <p>
            <input type="submit">
          </p>
        </form>
        `,' ');
      response.writeHead(200);
      response.end(html);
    });
  }
  else if(pathname === '/post_process'){
    var body = '';
    request.on('data'function(data){
      body += data;
    });
 
    //데이터량이 너무 많으면 통신 차단(보안)
    // if(body.length > 1e6){
    //   request.connection.destroy();
    // }
    request.on('end'function(){
      var post = qs.parse(body);
      var title = post.title;
      var description = post.description;
      console.log(post);
      console.log(post.title);
      console.log(post.description);
 
      fs.writeFile(`./data/${title}`, description, 'utf8', (err) => {
        response.writeHead(302, {Location: `/?id=${title}`});
        response.end();
      });
    });
  }
  //update를 구현하자.
  else if(pathname === '/update'){
    fs.readFile(`data/${title}`, 'utf8', (err, description) => {
      //if(err) throw err;
      //템플릿을 활용해 문서를 처리하였다.
      fs.readdir('./data',(err, fileList)=>{
        var list = template.list(fileList);
        var html = template.HTML(title, list, `<form action="/update_process" method="post">
        <input type="hidden" name="id" value="${title}">
          <p><input type="text" name="title" placeholder ="title" value="${title}"></p>
          <p>
            <textarea name="description" rows="8" cols="80" placeholder="description">${description}</textarea>
          </p>
          <p>
            <input type="submit">
          </p>
        </form>`, ' ');
        response.writeHead(200);
        response.end(html);
      });
    })
  }
  else if(pathname === '/update_process'){
    var body = '';
    request.on('data'function(data){
      body += data;
    });
    request.on('end'function(){
      var post = qs.parse(body);
      var title = post.title;
      var id = post.id;
      var description = post.description;
      console.log(post);
      console.log(post.title);
      console.log(post.id);
      console.log(post.description);
 
      fs.rename(`./data/${id}`, `./data/${title}`, (err) => {
        fs.writeFile(`./data/${title}`, description, 'utf8', (err) => {
          response.writeHead(302, {Location: `/?id=${title}`});
          response.end();
        });
      });
    });
  }
  else if(pathname === '/delete_process'){
    var body = '';
    request.on('data'function(data){
      body += data;
    });
    request.on('end'function(){
      var post = qs.parse(body);
      var id = post.id;
      fs.unlink(`./data/${id}`, (err) => {
        response.writeHead(302, {Location: `/`});
        response.end();
      });
    });
  }
  else {
      response.writeHead(404);
      response.end('Not found');
    }
 
 
 
 
 
 
 
});
app.listen(3000);
 
cs


처음의 코드는 다른 패키지를 사용하지 않고, 서버를 만들고, _url에서 가져온 url을 활용하여 처리를 하는 형태로 만들었었다.


하지만, 공부를 하다보니, express라는 패키지를 활용하여 더 직관적으로 해결하는 방법이 있어서 그것을 활용해 두번째 코드를 기획하였다.



2차 코드 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var main = require('./router/main') ;
var fs = require('fs');
// var contents = fs.readFileSync("./data/data.json");
// var jsonContent = JSON.parse(contents);
var url = require('url');
 
// console.log(jsonContent.person[0].owner);
// console.log(jsonContent.person[0]);
// console.log(Object.keys(jsonContent.person).length);
 
app.listen(3000function(){
  console.log("start, express server on port 3000");
});
 
 
//get방식의 요청을 처리한다.
//data폴더 내의 정적인 파일들을 불러올 수 있도록 설정
app.use(express.static('data'));
//json형태의 입력을 받는다.
app.use(bodyParser.json())
//타입이 정해지지 않은 입력을 받는다.
app.use(bodyParser.urlencoded({extended:true}))
app.set('view engine''ejs');
 
 
//url routing
app.use('/main', main);
 
app.get('/'function(req,res){
  // var _url = req.url;
  // var queryData = url.parse(_url, true).query;
  // var pathname = url.parse(_url, true).pathname;
  // console.log(_url);
  // console.log(queryData.get);
  // console.log(pathname);
  res.sendFile( __dirname + '/data/form.html');
});
 
//전체 데이터 출력
app.get('/get'function(req,res){
  // console.log(queryData);
  res.sendFile( __dirname + '/data/data.json');
});
 
//원하는 데이터 출력
app.get('/get/:id'function (req, res, next) {
  console.log(req.params.id);
  var contents = fs.readFileSync("./data/data.json");
  var jsonContent = JSON.parse(contents);
  console.log(jsonContent);
  res.json(jsonContent.person[req.params.id]);
});
 
app.post('/user_post'function(req,res){
  //get : req.param('email')
  console.log(req.body);
 
  // fs.writeFile(`./data/data.json`, description, 'utf8', (err) => {
  //   response.writeHead(302, {Location: `/?id=${title}`});
  //   response.end();
  // });
 
  // res.send("welcome! " + req.body.email);
  //출력을 할때 값을 조정해야 할 필요가 있을때, 이런식으로 전송한다.
  //뷰 엔진 활용
  res.render('email.ejs', {'phoneNumber' : req.body.phoneNumber});
});
 
app.post('/ajax_send_user'function(req, res){
  console.log(req.body);
  var responseData = {
    'phoneNumber' : req.body.phoneNumber,
    'owner' : req.body.owner,
    'corporation' : req.body.corporation
  };
 
  var contents = fs.readFileSync("./data/data.json");
  var jsonContent = JSON.parse(contents);
  //데이터 추가
  jsonContent.person.push(responseData);
  console.log(jsonContent);
 
  var input = JSON.stringify(jsonContent);
  fs.writeFile(`./data/data.json`, input, 'utf8'function(error) {
    if(error) {
      console.log('[write auth]: ' + err);
    } else {
      console.log('[write auth]: success');
    }
  });
  //수정 필요
  res.json(responseData);
 
});
 
 
app.post('/delete'function(req,res){
  //get : req.param('email')
  console.log(req.body);
 
  var contents = fs.readFileSync("./data/data.json");
  var jsonContent = JSON.parse(contents);
  console.log(jsonContent);
  //splice(a,b)는 a부터 b개의 원소를 삭제한다.
  jsonContent.person.splice(req.body.id, 1);
  console.log(jsonContent);
  var input = JSON.stringify(jsonContent);
  fs.writeFile(`./data/data.json`, input, 'utf8'function(error) {
    if(error) {
      console.log('[write auth]: ' + err);
    } else {
      console.log('[write auth]: success');
    }
  });
 
  //뷰 엔진 활용
  res.render('delete.ejs', {'id' : req.body.id});
});
//delete요청 처리
app.delete('/delete/:id'function (req, res, next) {
  console.log(req.params.id);
  var contents = fs.readFileSync("./data/data.json");
  var jsonContent = JSON.parse(contents);
  console.log(jsonContent);
  //splice(a,b)는 a부터 b개의 원소를 삭제한다.
  jsonContent.person.splice(req.params.id, 1);
  console.log(jsonContent);
  var input = JSON.stringify(jsonContent);
  fs.writeFile(`./data/data.json`, input, 'utf8'function(error) {
    if(error) {
      console.log('[write auth]: ' + err);
    } else {
      console.log('[write auth]: success');
    }
  });
  res.sendFile( __dirname + '/data/form.html');
});
 
//delete관련 등등은 https://velopert.com/332 참고해서
//app.get('/get/:id', function(req, res) 이렇게 id값을 가져오면 될 것 같은데...
//생각해보니까, 파라미터값으로 주어지면 되나?
 
 
const http = require('http');
const https = require('https');
 
cs


2차 코드는 위와 같이 된다.

이 메인 코드 뒤에 data파일과 ejs 파일들이 추가적으로 있지만, 크게 중요하다 생각되지는 않아서 위의 코드만 쓴다.


우선 이 코드는 express를 활용하여 웹 서버를 구현하였다.

뭐 주석에 이런 저런 글을 써서 대충 이해 될 듯 싶지만, rest한 웹 페이지를 만들기 위해서 get요청과 post요청에 대해서 응답해주는 방식을 다르게 구현하였다.


웹 루트에서 접속하여 간단하게 하는 처리와, 임의의 url에서 get, post, delete등을 요청하면 그에 맞춰 응답을 할 수 있게끔도 설계하였다.


개인적으로 일반적인 사용자들이 접근하는 페이지와 개발자가 사용 할 수 있는 페이지를 나누어서 구현하기 위해서 이렇게 만들어 보았는데, 제대로 만든 것인지 약간 아쉬운 부분이 있긴 하다.



+) 이 코드 활용법

1. git을 가지고 있다면, git clone https://github.com/kyun1016/nodejs2.git 를 요청한다.

2. cd nodejs/restful_web/node

3. npm install

4. nodemon app(이부분은 자신이 사용하는 node.js 툴을 활용하면 된다.) (없다면, install npm nodemon -g)

(다른 툴로 pm2도 상당히 유용하게 사용하였다.)



미숙하지만 작업한 코드들은 아래에 들어있다.

https://github.com/kyun1016/nodejs2.git

+ Recent posts