티스토리 뷰

728x90
반응형

이 포스팅을 읽고 모르는 부분이 있으면 자유롭게 코멘트를 주셔도 됩니다. 

제 포스팅을 통해 개념을 이해에 도움이 되기를 바랍니다.  읽어주셔서 감사합니다 :)


[문제1 전체코드]

더보기
var express = require('express');
var app = express();
var fs = require('fs');
var path = require('path');
var qs = require('querystring');
//1. body-parser 모듈을 불러오세요.
var bodyParser = require('body-parser');

var sanitizeHtml = require('sanitize-html');
var template = require('./lib/template.js');

//2.app.use()를 사용해서 json 타입의 데이터로 요청할 때 사용하는 bodyParser 를 로드하세요.(지시사항을 참고하세요)
app.use(bodyParser.urlencoded({ extended: false })); //
app.use(bodyParser.json()); //요청 본문을 json 형태로 파싱

//route, routing
//app.get('/', (req, res) => res.send('Hello World!'))
app.get('/', function (request, response) {
  fs.readdir('./data', function (error, filelist) {
    var title = 'Middleware';
    var description = 'Use body-parser';
    var list = template.list(filelist);
    var html = template.HTML(
      title,
      list,
      `<h2>${title}</h2>${description}`,
      `<a href="/create">create</a>`
    );
    response.send(html);
  });
});

app.get('/page/:pageId', function (request, response) {
  fs.readdir('./data', function (error, filelist) {
    var filteredId = path.parse(request.params.pageId).base;
    fs.readFile(`data/${filteredId}`, 'utf8', function (err, description) {
      var title = request.params.pageId;
      var sanitizedTitle = sanitizeHtml(title);
      var sanitizedDescription = sanitizeHtml(description, {
        allowedTags: ['h1'],
      });
      var list = template.list(filelist);
      var html = template.HTML(
        sanitizedTitle,
        list,
        `<h2>${sanitizedTitle}</h2>${sanitizedDescription}`,
        ` <a href="/create">create</a>
          <a href="/update/${sanitizedTitle}">update</a>
          <form action="/delete_process" method="post">
            <input type="hidden" name="id" value="${sanitizedTitle}">
            <input type="submit" value="delete">
          </form>`
      );
      response.send(html);
    });
  });
});

app.get('/create', function (request, response) {
  fs.readdir('./data', function (error, filelist) {
    var title = 'WEB - create';
    var list = template.list(filelist);
    var html = template.HTML(
      title,
      list,
      `
      <form action="/create_process" method="post">
        <p><input type="text" name="title" placeholder="title"></p>
        <p>
          <textarea name="description" placeholder="description"></textarea>
        </p>
        <p>
          <input type="submit">
        </p>
      </form>
    `,
      ''
    );
    response.send(html);
  });
});

//아래 함수의 request라는 요청에 body-parser 미들웨어가 json 형태로 바꿔줍니다.
//create_process라는 라우터를 사용할때 request객체의 body property에 접근해서 간결하게 코드가 작성됨
app.post('/create_process', function (request, response) {
  //   var post = request.body;
  //   var title = post.title;
  //   var description = post.description;
  const { title, description } = request.body;
  fs.writeFile(`data/${title}`, description, 'utf8', function (err) {
    response.writeHead(302, { Location: encodeURI(`/?id=${title}`) });
    response.end();
  });
});

app.get('/update/:pageId', function (request, response) {
  fs.readdir('./data', function (error, filelist) {
    var filteredId = path.parse(request.params.pageId).base;
    fs.readFile(`data/${filteredId}`, 'utf-8', function (err, description) {
      var title = request.params.pageId;
      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" placeholder="description">${description}</textarea>
          </p>
          <p>
            <input type="submit">
          </p>
        </form>
        `,
        `<a href="/create">create</a> <a href="/update?id=${title}">update</a>`
      );
      response.send(html);
    });
  });
});

//3. `create_process`라는 라우터를 사용할 때  request 객체의 body에 접근해서 본문을 json 형태로 바꿔준것 과 마찬가지로 `update_process`라우터를 사용할 때에도 post, id, title, description을 request로 받은 형태를 json으로 바꾸세요.
app.post('/update_process', function (request, response) {
  //   var post = null;
  //   var id = null;
  //   var title = null;
  //   var description = null;
  console.log(request.body);
  const { post, id, title, description } = request.body;
  fs.rename(`data/${id}`, `data/${title}`, function (error) {
    fs.writeFile(
      `data/${title}`,
      description,
      function (err) {
        response.redirect( encodeURI(`/?id=${title}`) );
      }
    );
  });
});

app.post('/delete_process', function (request, response) {
  var post = request.body;
  var id = post.id;
  var filteredId = path.parse(id).base;
  fs.unlink(`data/${filteredId}`, function (error) {
    response.redirect('/');
  });
});

app.listen(8080, function () {
  console.log('Example app listening on port 8080!');
});

 

여러분이 문제를 풀다가, 영어로 title, description 입력은 되는데

한글일 때는 데이터 입력이 안되는 문제에 대해 해결책을 찾아봤습니다.

var express = require('express');
var app = express();
var fs = require('fs');
var path = require('path');
var qs = require('querystring');
//1. body-parser 모듈을 불러오세요.
var bodyParser = require('body-parser');

var sanitizeHtml = require('sanitize-html');
var template = require('./lib/template.js');

//2.app.use()를 사용해서 json 타입의 데이터로 요청할 때 사용하는 bodyParser 를 로드하세요.(지시사항을 참고하세요)
// bodyParser은 POST방식으로 요청할때 request객체에 body에 요청데이터를 저장한다.

app.use(bodyParser.urlencoded({ extended: false })); //
app.use(bodyParser.json()); //요청 본문을 json 형태로 파싱


app.get('/page/:pageId', function (request, response) {
	console.log(request.params); // pageId: 값 형태로 출력됨.
    
  fs.readdir('./data', function (error, filelist) {
    var filteredId = path.parse(request.params.pageId).base;
    fs.readFile(`data/${filteredId}`, 'utf8', function (err, description) {
      var title = request.params.pageId;
      var sanitizedTitle = sanitizeHtml(title);
      var sanitizedDescription = sanitizeHtml(description, {
        allowedTags: ['h1'],
      });
      var list = template.list(filelist);
      var html = template.HTML(
        sanitizedTitle,
        list,
        `<h2>${sanitizedTitle}</h2>${sanitizedDescription}`,
        ` <a href="/create">create</a>
          <a href="/update/${sanitizedTitle}">update</a>
          <form action="/delete_process" method="post">
            <input type="hidden" name="id" value="${sanitizedTitle}">
            <input type="submit" value="delete">
          </form>`
      );
      response.send(html);
    });
  });
});



//아래 함수의 request라는 요청에 body-parser 미들웨어가 json 형태로 바꿔줍니다.
//create_process라는 라우터를 사용할때 request객체의 body property에 접근해서 간결하게 코드가 작성됨
app.post('/create_process', function (request, response) {

  const { title, description } = request.body;
  fs.writeFile(`data/${title}`, description, 'utf8', function (err) {

	// url에 한글이 들어올 경우에는 encodeURI()를 호출하여 인코딩을 해야합니다. 
    response.writeHead(302, { Location: encodeURI(`/?id=${title}`) });
    response.end();
  });
});



//3. `create_process`라는 라우터를 사용할 때  request 객체의 body에 접근해서 본문을 json 형태로 바꿔준것 과 마찬가지로 `update_process`라우터를 사용할 때에도 post, id, title, description을 request로 받은 형태를 json으로 바꾸세요.
app.post('/update_process', function (request, response) {
  console.log(request.body);
  const { post, id, title, description } = request.body;
  fs.rename(`data/${id}`, `data/${title}`, function (error) {
    fs.writeFile(
      `data/${title}`,
      description,
      function (err) {
      
      	// url에 한글이 들어올 경우에는 encodeURI()를 호출하여 인코딩을 해야합니다. 
        response.redirect( encodeURI(`/?id=${title}`) );
      }
    );
  });
});

 


[문제1] Express의 body-parser 사용하기

설명

미들웨어 중 하나인 body-parser를 사용하면 여러가지 발생가능한 문제들을 방지하고 요청의 본문(body)을 지정한 형태로 parsing 해줍니다. Express프레임워크는 요청을 처리할 때 기본적으로 body를 undefined로 처리하고있기 때문에 아래 코드처럼 req.body를 콘솔에 출력하면 undefined가 출력됩니다.

 

  • body 란 요청한 정보의 본체를 의미합니다.
app.get('/test', (req, res) => {
    res.send('test');
    console.log(req.body);
});

 

  • 이 때 body-parser 미들웨어를 사용하면 request의 body 부분을 개발자가 원하는 json 형태로 파싱하여 활용할 수 있습니다.
//body-parser 모듈 불러오기
const bodyParser = require('body-parser');

app.use(bodyParser.json());    //요청 본문을 json 형태로 파싱
app.use(bodyParser.urlencoded({extended: false}));  //

 

지시사항

lib 폴더 내의 template.js에는 HTML 페이지의 뼈대가 작성되어있습니다.

main.js 내에 create_process, update_process, delete_process라는 라우터를 사용해서 그 응답에 경로를 미리 설정하는 코드를 작성하게 되는데 이 때 body-parser를 사용하면 코드가 훨씬 간결해집니다.

1. main.js에 body-parser 모듈을 불러오세요.이 때 변수명은 bodyParser 로 작성하세요.
2. app.use()를 사용해서 json 타입의 데이터로 요청할때 사용하는 바디파서를 로드하세요.
- app.use(bodyParser.urlencoded({extended: false}));

3. create_process 라는 라우터를 사용할 때 request 객체의 body에 접근해서 본문을 json 형태로 바꿔준것 과 마찬가지로 update_process 라우터를 사용할 때에도 post, id, title, description을 request로 받은 형태를 json으로 바꾸세요.

[입문자의 눈높이에서 개념설명]

  • Node.js 가 무엇이죠?
  • express 는 javascript 언어로 된 프레임워크라고 하는데, 프레임워크가 무엇이죠?
  • 미들웨어(middle-ware) 가 무엇일까요?
  • body-parser 은 무엇인가요?
  • body-parser의 urlencoded() 역할이 무엇인가요?
  • body-parser의 json() 역할이 무엇이에요?

 

Node.js가 무엇이죠?

Node.js 는 chrome V8 자바스크립트 엔진으로 빌드된 Javascript 런타임 입니다.

노드를 통해서 다양한 자바스크립트 애플리케이션을 실행 시킬 수 있고, 서버 실행에 많이 쓰입니다.

 

Node.js 는 자바스크립트를 브라우저의 콘솔창이 아닌 서버에서 사용할 수 있도록 만든 프로그램 입니다.

Node.js는 서버사이드 스크립트 언어가 아니라, 프로그램(환경) 입니다.

여기서 Javascript는 스크립트 언어입니다.
스크립트 언어란, 특정한 프로그램 안에서 동작하는 프로그램이고, 자바스크립트는 웹브라우저 프로그램 안에서만 동작을 합니다.

Node.js는 브라우저에서 독립시켜, 브라우저없이도 자바스크립트 파일을 실행시킬 수 있고, 애플리케이션 서버를 만들 수 있습니다.

 

자바스크립트 런타임

런타임은 특정 언어로 만든 프로그램을 실행할 수 있는 환경을 의미합니다.

자바스크립트 런타임은 자바스크립트 파일을 실행할 수 있는 환경을 의미합니다.

 

+ V8 엔진

V8은 오픈소스 자바스크립트 엔진 중 하나 입니다.

V8 엔진은 자바스크립트를 바이트코드로 컴파일하고 실행하는 방식을 사용합니다.

 

+ 바이트코드(bytecode)

고급언어로 (사람이 이해할 수 있는 언어) 작성된 소스코드를 가상머신이 이해할 수 있는 코드로 컴파일 한 것을 의미합니다.

바이트코드는 각각의 하드웨어 아키텍쳐에 맞는 기계어로 다시 컴파일 합니다.

즉, 운영체제(macOS, Windows, Linux) 에 맞춰서 컴파일하여, 바이트코드를 기계어로 번역시킵니다.

 

+ 컴파일(compile)

컴파일은 인간이 이해할 수 있는 언어로 작성된 코드(고급언어)를 기계어로 번역해주는 것을 의미합니다.


프레임워크가 무엇인가요?

프레임워크는 특정 애플리케이션을 개발을 하기위한 틀(요소와 규칙 등)을 제공해주는 프로그램 입니다.

Fame+Work 로 '틀 뼈대를 가지고 만든다' 로 생각하시면 됩니다.

 

그래도 어렵다면, '장난감 키트'를 비유해볼게요.


장난감 키트 = 우리가 만들 앱 

설명서 = 프레임워크

장난감 제조사 = 프레임워크 제공 회사

 

장난감 키트 상자를 열면, 장난감 키트의 부품과 설명서가 있지요?

장난감을 만들려면, 장난감을 만드는 방법을 알아야겠죠? 그리고 만드는 순서도 있겠고요.

설명서가 장난감을 만드는 순서, 만드는 방법 과 같은  규칙을 제공해주는게 프레임워크죠.

 

express 는  node.js 환경에서 javascript 언어로 서버를 만들 수 있도록 해주는 프레임워크에요.

우리가 앱(장난감)을 완성하려면, express 사용방법을 알아야되고

express에서 제공해주는 모듈들을 활용해야되요.

모듈(라이브러리)는 장난감를 만들 수 있는 도구에요. 

 

 

IT관련 "개발용어"에 익숙해지자 3편 - library 와 framework

배경 친한 동생과 대화하다가 포스팅을 하게 되었습니다. 대화의 핵심내용은 텐서플로우 가 라이브러리 인가 프레임워크 인가 입니다. 자료조사 중, 참조한 논문에서 '텐서플로우는 오픈소스

ek12mv2.tistory.com


body-parser은 무엇인가요?

npm 공식 다큐먼트에서 body-parser 의 정의를 봅시다.

Node.js body parsing middleware.
body 영역에 해당하는 데이터를 파싱 미들웨어 입니다.

* 파싱: 데이터를 탐색하여 얻는 것을 의미합니다.
 

body-parser

Node.js body parsing middleware. Latest version: 1.20.0, last published: 6 months ago. Start using body-parser in your project by running `npm i body-parser`. There are 21675 other projects in the npm registry using body-parser.

www.npmjs.com

 

조금더 깊이가보면, HTTP의 POST 방식으로 서버에게 요청할 때 body 영역의 데이터를 활용합니다.
'블로그에서 글을 올리는 것'을 예시로 해보겠습니다.

블로그에 글을 올릴려면, 작성자가 직접 블로그의 주제,내용, 해시태그 등을 입력해야되겠죠?
'주제', '내용', '해시태그', '날짜', '카테고리' 등이 입력해야되는 데이터가 요청데이터 입니다.
 
서버는 요청객체(request)의  body영역에서 요청데이터가 key-value 형태로 저장되어있습니다.

즉, body-parser 은 POST방식의 요청데이터를 저장하게끔 만들어진 함수 입니다.


body-parser의 urlencoded() 역할이 무엇인가요?

 

post방식으로 요청했을 때 요청한 데이터가 body에 저장됩니다.

자동으로 request객체에 body 속성이 추가되고 저장됩니다.

 

bodyParser.urlencoded() 라고 하면

body-parser deprecated undefined extended: provide extended option 

Warning 문구가 발생합니다.

 

왜냐면 bodyParser.urlencoded() 코드형태가 현재 node버젼에서 지원할 수 없는 코드이기 때문입니다.

bodyParser.urlencoded({ extended : true/false }) 형식을 지원하고 있습니다.

extended 옵션의 true/false 는 qs / query-string 라이브러리를 사용할 것이냐 결정을 하는 걸 의미합니다.

 

extended: true

const bodyParser = require('body-parser');

bodyParser.urlencoded({extended: true});

 

  • qs 라이브러리를 사용합니다.
  • qs 라이브러리는 요청 쿼리 스트링(query string)으로  JSON 형식으로 요청데이터를 나타내게 해줍니다.
const qs = require("qs");

const result = qs.parse("blog[title]=Test&blog[author]=dev-alakazam");
console.log(result);

/*
JSON 형식의 데이터

{
	blog: {
		title: Test,
		author: dev-alakazam
	}
}
*/

 

 

  • qs 라이브러리는 쿼리스트링의 ? 을 기준으로 데이터를 필터링 않습니다.
const qs = require("qs")
const result = qs.parse("?a=b")
console.log(result) // { '?a': 'b' }

 

 

extended: false 

const bodyParser = require("body-parser");

bodyParser.urlencoded({ extended: false });

 

 

  • query-string 라이브러리를 사용합니다.
  • query-string 는 쿼리스트링을 요청쿼리스트링을 JSON형식으로 변환하지 않습니다.
const queryString = require("query-string");

const result = queryString.parse("blog[title]=Test&blog[author]=dev-alakazam");
console.log(result);

/*

{
	'blog[title]': 'Test',
	'blog[author]': 'dev-alakazam',
}
*/

 

  • query-string 은 ? 을 기준으로 데이터를 필터링 합니다.
  const queryString = require("query-string")
  const result = queryString.parse("?a=b")
  console.log(result) // { a: 'b' }

 

요청 쿼리스트링을 JSON 형식으로 요청데이터를 나타내고 싶다면

depth 가 있는 객체를 주고받을 필요가 있다면

url.encoded({ extended: true }) 를 하는게 좋습니다.


body-parser의 json() 역할이 무엇인가요?

request.body 가  JSON 타입일 때, 요청데이터를 받을 수있게 해주는 미들웨어 입니다.

express 버젼이 4.16 이후에는 body-parser 모듈을 호출하지 않아도

express 모듈만으로  express.json() 으로  JSON 요청데이터를 문제없이 받을 수 있습니다. 

const express = require("express");
const app = express();

app.use(express.json());

app.post('/', function(req, res){
	console.log(req.body);	// 사용자의 JSON 요청
	res.send(req.body);	// JSON 응답
});

app.listen(3000);

미들웨어가 무엇인가요?

공식문서에서의 정의를 보면

미들웨어 함수는 요청객체(req) 와 응답객체(res)
그리고 애플리케이션의 요청-응답 주기 중 그 다음의 미들웨어 함수에 대한 액세스 권한을 갖는 함수이다.
그 다음의 미들웨어 함수는 일반적으로 next라는 이름의 변수로 표시됩니다.

 

미들웨어는 middle software 로 요청과 응답 사이의 중간 처리를 의미합니다. 

URL 호출 ->  미들웨어함수 -> next() : 미들웨어에서 응답로직으로 넘어감 ->  응답함수

 

미들웨어를 활용하는 경우의 예는 로그인 본인 인증처리 입니다.

우리가 카카오톡, 네이버, Gmail 등 로그인 했을 때

자신의 휴대폰 에서 카톡, 네이버에서 앱에서 본인이 맞다면

제한 시간 내에 화면에 보여준 번호를 입력을 요구합니다.

네이버 QR코드 본인인증

 

const express = require("express");
const app = express();

app.use(express.urlencoded({ extended: false }));
app.use(express.json());

// 미들웨어
const middleWare = (req, res, next) => {
	console.log("미들웨어 호출완료");
	next();
}


// 응답함수
const responseFunction = (req, res) => {
	return res.status(200).json("succeed")

}


// app.get( URL, 미들웨어함수 , 응답함수 )
// URL 을 호출하면 -> 미들웨어함수를 호출하고 -> 미들웨어호출함수가 완료되면 next() 로 응답함수를 호출한다.
app.get("/", middleWare , responseFunction );

app.get("/", middleWare, responseFunction ) 을 해석해보면

먼저 URL "/" 을 요청하면, 응답을 받기 전에 middleWare 함수를 호출합니다.

middleWare함수 처리가 끝나면 내부로직의 next() 함수에 의해 미들웨어함수를 종료하고 다음함수로 넘어갑니다.

responseFunction 함수를 호출하여 응답데이터를 리턴합니다.

 


[참고자료]

더보기

[ Node.js ]

 

Node.js 노드 개념 이해하기 자바스크립트 JavaScript 런타임 이벤트

Node.js 노드 개념 이해하기 JavaScript 런타임 - 노드는 다양한 자바스크립트 애플리케이션을 실행할 수 있으며, 서버를 실행하는데 제일 많이 사용된다. 이벤트 기반 이벤트 루프 논블로킹 I/O 싱글

hanamon.kr

 

 

[JavaScript] 런타임 작동 방식, 비동기와 이벤트 루프 - 하나몬

⚡️ [JavaScript] 런타임 작동 방식, 비동기와 이벤트 루프 ❗️알아볼 키워드 자바스크립트란? 자바스크립트 V8 엔진이란? 자바스크립트 런타임이란? 자바스크립트 싱글 스레드 기반 프로그래밍

hanamon.kr

 

[프레임워크]

 

프레임워크(Framework)? 라이브러리(Library)? 둘의 차이점? 이것만 알면 됩니다.

막 프로그래밍을 배우기 시작했거나 프로그래밍을 모르는 분들에게 저 두 개념은 아주 헷갈리는 개념일 것입니다. 사실 어느정도 숙달된 프로그래머라도 일반인에게 저 두 개념을 쉽고 확실하

engkimbs.tistory.com

 

[미들웨어]

 

[Node.js] Express 미들웨어 함수

미들웨어(Middleware) 함수 Express는 자체적인 최소한의 기능을 가진 라우팅 및 미들웨어 웹 프레임워크다. Express 애플리케이션은 일련의 미들웨어 함수를 호출한다. 미들웨어 함수란 요청 오브젝트

about-tech.tistory.com

 

[body-parser 의 urlencoded({extended: true/false}) ]

 

What does 'extended' mean in express 4.0?

I'm using express and also body-parser in my app. app.use(bodyParser.urlencoded({ extended: false })); But, What does 'extended' mean in express 4.0? I found this extended - parse extended sy...

stackoverflow.com

 

[node.js] body-parser을 정확히 알자

express를 사용하면 보통 아래와 같이 시작을 한다.보통 body-parser를 설명할때 'request.body에 있는 데...

blog.naver.com

 


[문제1 풀이]

var express = require('express');
var app = express();
var fs = require('fs');
var path = require('path');
var qs = require('querystring');

//1. body-parser 모듈을 불러오세요.
var bodyParser = require('body-parser');

var sanitizeHtml = require('sanitize-html');
var template = require('./lib/template.js');

//2.app.use()를 사용해서 json 타입의 데이터로 요청할 때 사용하는 bodyParser 를 로드하세요. (지시사항을 참고하세요)
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());


//아래 함수의 request라는 요청에 body-parser 미들웨어가 json 형태로 바꿔줍니다.
//create_process라는 라우터를 사용할때 request객체의 body property에 접근해서 간결하게 코드가 작성됨
app.post('/create_process', function (request, response) {

  var { title, description } = request.body;
  
  fs.writeFile(`data/${title}`, description, 'utf8', function (err) {
    response.writeHead(302, { Location: `/?id=${title}` });
    response.end();
  });
});


//3. `create_process`라는 라우터를 사용할 때  request 객체의 body에 접근해서 본문을 json 형태로 바꿔준것 과 마찬가지로 `update_process`라우터를 사용할 때에도 post, id, title, description을 request로 받은 형태를 json으로 바꾸세요.
app.post('/update_process', function (request, response) {

  var { post, id, title, description } = request.body;
  
  fs.rename(`data/${id}`, `data/${title}`, function (error) {
    fs.writeFile(`data/${title}`, description, 'utf8', function (err) {
      response.redirect(`/?id=${title}`);
    });
  });
});


app.listen(8080, function () {
  console.log('Example app listening on port 8080!');
});

 

 

 


[문제2] Node.js + Mongoose 연결하기

설명

Mongoose는 MongoDB Mongoose 서버에 연결하고 Schema를 정의하세요.

Schema 란 데이터를 넣는 테이블이라고 이해하시면 됩니다. Mongoose는 Schema를 기준으로 데이터를 데이터베이스에 넣기 전에 검사를 하고 어긋나는 데이터들이 있으면 에러를 발생시킵니다.

 

지시사항

1. index.js내 connect()함수안에 mongoose.connect()를 사용해서 MongoDB에 연결하세요.
이때 성공적으로 연결되면 console에 메시지를 출력하고, 에러가 발생하면 에러메시지를 console에 출력하세요.
- 성공 메시지는 connected to database successfully로 설정하세요.
- 주소는 로컬 몽고디비 기본 주소인 mongodb://localhost:27017을 사용합니다.

2. models/User.js에 Schema를 구조를 설정해야 합니다. 이름, 이메일, 등록 시간 등 원하는 데이터를 어떻게 불러올지 고민해보세요.

3. model로 이 userSchema를 다른 파일에서 사용할 수 있게 User model을 exports하세요.

[입문자의 눈높이에서 개념설명]

  • Schema (스키마) 
  • mongodb 가 무엇인가요?
  • mongoose는 무엇인가요?
  • Promise 객체

 

스키마(schema) ?

스키마는 데이터베이스의 구조와 제약조건에 관한 전반적인 명세를 정의한 메타데이터의 집합 입니다.

*메타데이터: 데이터에 대한 데이터로, 어떤 목적을 가지고 만들어진 데이터 입니다.


스키마를 좀더 정확히 정의하자면

개체의 특성을 나타내는 속성(Attribute)와
속성들의 집합을 이뤄진 개체(Entity)
개체 사이에 존재하는 관계(Relation) 에 대한 정의와
이들이 유지해야할 제약 조건 을 기술 한 것들의 집합입니다.

* 개체(Entity) : 데이터로 표현하려고 하는 객체 
* 속성(Attribute): 개체가 갖는 속성 
* 관계(Relation): 개체와 개체 사이의 연관성

데이터베이스의 구조와 제약조건, 관계를 나타내는 집합 입니다.

 

Mongodb 가 무엇인가요?

MongoDB는 NoSQL 데이터베이스 중 Document 기반의 데이터베이스 입니다.

MongoDB는 Document 기반의 데이터베이스 중 가장 많이 사용하는 데이터베이스입니다!

 

+ NoSQL

NoSQL은 Not Only SQL의 약어 입니다. 

NoSQL은 관계형 방식이 아닌 다른 유형으로 데이터를 저장하고 관리합니다.

NoSQL 데이터베이스는 데이터 모델에 따라 유형이 다양합니다. 방식은 다르지만 NoSQL도 관계데이터를 저장이 가능합니다.


데이터가 고정되어 있지 않고, 데이터모델에 따라 유형이 다양해서 유연한 스키마를 제공합니다.


그래서 NoSQL은 대량의 데이터를 제공할 수 있고, 높은 사용자 부하에서도 확장이 가능하다는 장점을 갖고 있습니다.

관계형 방식은 고정된 컬럼과 행으로 구성된 2차원 형태를 의미합니다.

테이블에 정의된 내용에, 알맞은 데이터만을 삽입할 수 있습니다. RDBMS가 관계형유형의 데이터베이스며, SQL문으로 데이터베이스의 테이블과 테이블에 저장된 데이터들을 다룹니다.

 

+ Document 기반

다큐먼트 기반(Document Oriented) 데이터베이스 중 Document 를 '문서'로 떠올랐나요?

간단히 말하자면, "1개의 데이터" 를 의미합니다. 다큐먼트는 객체(JSON) 형태로 되어있습니다.

제 몽고디비의 *콜렉션 입니다.

* 콜렉션(collection): 다큐먼트들의 집합입니다.

* (추가) RDBMS 에서의 "데이터 한개" 를 나타내는 용어는 "레코드(record)" 입니다.
레코드들을 저장하는 집합을 테이블(table) 이라고 합니다.

 

 

[mongodb] MongoDB와 NoSQL 정의 소개 및 MongoDB Shell로 데이터를 insert 하기

몽고디비 클러스터 이동으로 json데이터를 다른 클러스터로 이관하는 작업을 하게 되었습니다. 몽고디비는 document 기반의 데이터베이스여서 RDBMS와 다르게 넣은 데이터 타입에 맞게 알아서 스키

ek12mv2.tistory.com


Mongoose 가 무엇인가요?

npm(node.js package manager) 사이트에서 Mongoose 를  다음과 같이 정의했습니다.

Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment.
Mongoose supports both promises and callbacks.
 

mongoose

Mongoose MongoDB ODM. Latest version: 6.6.4, last published: a day ago. Start using mongoose in your project by running `npm i mongoose`. There are 12830 other projects in the npm registry using mongoose.

www.npmjs.com

 

  • Mongoose는 MongoDB 객체 모델링 도구입니다.
  • Node.js 환경에서 MongoDB 연결하여 데이터베이스에 접근할 수 있도록 하는 도구입니다.
  • Mongoose는 비동기 방식의 환경에서 동작하도록 설계되어 있습니다.
  • Mongoose는 Promise 와 Callback 을 이용하여 MongoDB에 있는 데이터를 갖고옵니다. 

 

 

+ 동기처리 와 비동기처리

동기처리 (synchronous)

동기는 요청을 보내면 요청에 대한 응답을 받아야 다음 동작을 실행하는 처리방식 입니다.

 

비동기처리 (asynchronous)

비동기는 요청을 보낸 후 응답과 관계없이 다음 동작을 실행하는 처리방식 입니다.

즉, 앞의 코드(프로세스)의 실행 연산을 끝날 때까지 기다리지 않고 처리하는 것을 의미합니다.

 

카페에서 주문하는 것을  동기처리(synchronous) 와 비동기처리(asynchronous)의 예를 들어봅시다.


1) 동기처리

점원은 한명밖에 없는 카페에서 커피를 주문한다고 생각해봅시다. 주문을 하고나니 점원이 커피 나올때까지 기다리라고 했습니다.
뒤에 사람은 계속 오는데 커피가 나올 때까지 가만히 서있어야 합니다. 동기는 순서대로 실행하는 것을 의미합니다.


2) 비동기처리

카페에서 주문을하는데, 커피를 주문하니 점원이 진동벨을 건너주면서 진동벨이 울리면 가지러오라고 했습니다. 주문만하고 앞에 사람이 빠져나가면 뒤에 기다리던 사람이 주문을 합니다. 진동벨이 울리면 주문한 커피를 가져가면 됩니다.
비동기처리는 앞의 작업(코드)가 끝날 때 까지 멈추지 않고, 바로 다음 작업(코드)를 먼저 실행하는 것을 의미합니다.

 

 

[Javascript] callback함수와 async와 await 그리고 Promise 에 대한 이해

[참고자료] 더보기 입문자에게 읽기 좋은 자료입니다. 천천히 이해할 때까지 계속 읽어보는걸 추천합니다. 자바스크립트 비동기 처리와 콜백 함수 (중급) 중급 자바스크립트 개발자가 되기 위한

ek12mv2.tistory.com


Callback

콜백함수는 이름그대로 이벤트가 발생하면 나중에 호출되는 함수 를 의미합니다.
콜백함수의 구조는 함수안에 함수가 있습니다.

console.log("Hello");

setTimeout( function() { 
	console.log("End"); 
}, 1000 );


console.log("Bye");

순서대로로하면 Hello End Bye 순일거 같지만, 예상과 다른 순서인 Hello Bye End 입니다.

Hello를 출력합니다.

Bye를 출력합니다.

(1초가 지났으면 함수가 호출되므로) End를 출력합니다.

 

예를 들면, 마우스 클릭 을 하면 버튼의 색깔이 바뀝니다. 
그러면 마우스를 클릭한 시점에서 콜백이 발생한거고 콜백함수로 인해서 버튼의 색깔이 바뀌는 거죠.

서버로직도 마찬가지입니다. URL 요청하면 요청이벤트가 온 순간에 미들웨어함수를 실행합니다.

next() 함수를 호출이 시작하면 요청에대한 응답로직인 응답함수가 실행됩니다. 

위의 커피 예시 에서, 진동벨이 콜백함수의 역할을 합니다. 정리해보면 다음과 같습니다.

커피 제작 완료 = 이벤트 발생
진동벨이 울린다 = 이벤트 발생하면 바로 콜백함수를 호출
커피를 가지러온다 = 콜백함수의 내부로직 실행

Promise 객체

콜백을 반복하거나, 너무 많으면 코드의 가독성이 떨어지고 수정하기가 어렵습니다. 
(콜백지옥 코드는 바로 밑에있는 포스트에서 확인하시면 됩니다.)

callback 지옥을 해결하기 위해서 만든 객체입니다.

Promise 객체는 자바스크립트 비동기 처리에 사용되는 객체 입니다.

 

[참고자료]

더보기

[문제2 풀이]

User.js

const mongoose = require('mongoose');

const userSchema = new mongoose.Schema({
  //2. 데이터를 불러올 테이블을 어떻게 정의해야 하는지 고민해보세요.
  name: { type: String, required: true },
  email: { type: String, required: true },
  enrollDate: { type: Date, default: Date.now },
});

//3. model로 이 userSchema를 다른 파일에서 사용할 수 있게 User model을 exports하세요.
const User = mongoose.model('User', userSchema);
module.exports = { User };

 

 

index.js

solution 1 ~ soltion3 모두 mongoose 공식 다큐먼트의 connections 을 참고하여 작성했습니다.

 

Mongoose v6.6.4: Connecting to MongoDB

You can connect to MongoDB with the mongoose.connect() method. mongoose.connect('mongodb://localhost:27017/myapp'); This is the minimum needed to connect the myapp database running locally on the default port (27017). If connecting fails on your machine, t

mongoosejs.com

 

 

1) solution 1

const mongoose = require('mongoose');
const express = require('express');
const server = express();

// import User Model
const User = require('./models/User');

// Test Error Message
// const User = require('./User');

const mongodbURI = 'mongodb://localhost:27017';
const successMsg = 'connected to database successfully';


server.listen(8080, err => {
  if (err) {
    console.log('err');
  } else {
    console.log('start the server successfully');

  
    //1.`connect()`함수안에 `mongoose.connect()`를 사용해서 MongoDB에 연결하세요.
    // 이때 성공적으로 연결되면 console에 메시지를 출력하고, 에러가 발생하면 에러메시지를 console에 출력하세요.
    
    mongoose.connect(mongodbURI)
      .then(() => {
        console.log(successMsg);
      })
      .catch( (err) => {
        console.error('Error: ', err);
      });
   
  }
});

 

2) solution 2

const mongoose = require('mongoose');
const express = require('express');
const server = express();

// import User Model
const User = require('./models/User');

// Test Error Message
// const User = require('./User');

const mongodbURI = 'mongodb://localhost:27017';
const successMsg = 'connected to database successfully';


server.listen(8080, err => {
  if (err) {
    console.log('err');
  } else {
    console.log('start the server successfully');

  
    //1.`connect()`함수안에 `mongoose.connect()`를 사용해서 MongoDB에 연결하세요.
    // 이때 성공적으로 연결되면 console에 메시지를 출력하고, 에러가 발생하면 에러메시지를 console에 출력하세요.
    
    mongoose.connect(mongodbURI).then(
      () => {
        console.log(successMsg);
      },
      err => {
        console.log('Error: ', err);
      }
    );
   
  }
});

 

3) solution 3

const mongoose = require('mongoose');
const express = require('express');
const server = express();

// import User Model
const User = require('./models/User');

// Test Error Message
// const User = require('./User');

const mongodbURI = 'mongodb://localhost:27017';
const successMsg = 'connected to database successfully';

server.listen(8080, err => {
  if (err) {
    console.log('err');
  } else {
    console.log('start the server successfully');

    //1.`connect()`함수안에 `mongoose.connect()`를 사용해서 MongoDB에 연결하세요. 
    // 이때 성공적으로 연결되면 console에 메시지를 출력하고, 에러가 발생하면 에러메시지를 console에 출력하세요.

    mongoose.connect(mongodbURI, () => {
        console.log(successMsg);
      })
      .catch(err => {
        console.log('Error: ', err);
      });

  }
});

 

4) solution 4

const mongoose = require('mongoose');
const express = require('express');
const server = express();

// import User Model
const User = require('./models/User');

// Test Error Message
// const User = require('./User');

const mongodbURI = 'mongodb://localhost:27017';
const successMsg = 'connected to database successfully';

// Database Open function
const dbOpen = () => {
  console.log(successMsg);
};

// Database Error Checking function
const dbError = (err) => {
  console.error(err);
};

server.listen(8080, err => {
  if (err) {
    console.log('err');
  } else {
    console.log('start the server successfully');
    
    //1.`connect()`함수안에 `mongoose.connect()`를 사용해서 MongoDB에 연결하세요. 
    // 이때 성공적으로 연결되면 console에 메시지를 출력하고, 에러가 발생하면 에러메시지를 console에 출력하세요.
    mongoose.connect(mongodbURI);
    const db = mongoose.connection;

    db.on('error', dbError);
    db.once('open', dbOpen);
  }
});

 

Common.JS에서의 모듈 불러오기/내보내기 - require() 와 module.exports

 

[Node.js/Javascript] commonJS 문법과 ES6 - require() 와 import 비교

안녕하세요. Node.js 와 Express.js 로 개발하다가 구글링을 해서 블로그에 있는 코드를 살펴보면 외부의 모듈을 불러올 때(import) 모듈을 외부로 내보낼 때(export) 표현이 2가지로 나뉘는 걸 볼 수 있습

ek12mv2.tistory.com

 

 

728x90
반응형
반응형
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/05   »
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
글 보관함