티스토리 뷰

<목표. 최대한 쉽게~>

 

1. Project 생성

 

PowerShell, IntelliJ 사용.

 

#1. 작업할 폴더 생성

(PowerShell에서 실행하였습니다)

PS D:\forStudy> dir
PS D:\forStudy> md nodejs_simaple_exam


    디렉터리: D:\forStudy


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----     2020-02-14   오후 4:46                nodejs_simaple_exam


PS D:\forStudy> dir


    디렉터리: D:\forStudy


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----     2020-02-14   오후 4:46                nodejs_simaple_exam


PS D:\forStudy>

 

#2. package.json 생성 (기본값 / 변경없음)

 

package.json?

package.json이란 프로젝트 정보와 의존성을 관리하는 파일을 의미함.

JSON 포맷으로 작성해야하며 npm init 명령을 통해 생성 가능.

 

PS D:\forStudy> cd .\nodejs_simaple_exam\
PS D:\forStudy\nodejs_simaple_exam> npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults.

See `npm help json` for definitive documentation on these fields
and exactly what they do.

Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file.

Press ^C at any time to quit.
package name: (nodejs_simaple_exam)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\forStudy\nodejs_simaple_exam\package.json:

{
  "name": "nodejs_simaple_exam",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}


Is this OK? (yes)
PS D:\forStudy\nodejs_simaple_exam> dir


    디렉터리: D:\forStudy\nodejs_simaple_exam


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----     2020-02-14   오후 4:49            215 package.json


PS D:\forStudy\nodejs_simaple_exam>

 

#3. Package 설치

 

> npm install --save express mongoose body-parser

 

위 명령에서 express는 웹프레임워크이고, Mongo DB를 사용하기 위해 mongoose 라이브러리를 설치함.

Body-parser는 데이터 처리 미들웨어임.

 

PS D:\forStudy\nodejs_simaple_exam> npm install --save express mongoose body-parser
npm notice created a lockfile as package-lock.json. You should commit this file.
npm WARN nodejs_simaple_exam@1.0.0 No description
npm WARN nodejs_simaple_exam@1.0.0 No repository field.

+ express@4.17.1
+ body-parser@1.19.0
+ mongoose@5.9.0
added 77 packages from 49 contributors and audited 196 packages in 8.52s

1 package is looking for funding
  run `npm fund` for details

found 0 vulnerabilities

PS D:\forStudy\nodejs_simaple_exam>

 

설치 후 확인해보면 다음과 같이 필요한 module이 설치되어있음.

PS D:\forStudy\nodejs_simaple_exam> dir


    디렉터리: D:\forStudy\nodejs_simaple_exam


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----     2020-02-14   오후 4:57                node_modules
-a----     2020-02-14   오후 4:57          22302 package-lock.json
-a----     2020-02-14   오후 4:57            321 package.json


PS D:\forStudy\nodejs_simaple_exam>

 

-- 이후 내용은 편의를 위해 IntelliJ에서 실행함 ---


2. Create

 

#1. 기본 설정

 

구조

다음과 같이 경로 / 파일 생성

(1) models/exam.js : Mongo DB와 연결에 사용할 모델

(2) routes/index.js : Router

(3) app.js : Main

 

 

#2. app.js

 

// Load Package
var express     = require('express');
var app         = express();
var bodyParser  = require('body-parser');
var mongoose    = require('mongoose');

// MongoDB
var db = mongoose.connection;
db.on('error', console.error);
db.once('open', function(){
    // CONNECTED TO MONGODB SERVER
    console.log("Connected to mongod server");
});

mongoose.connect('mongodb://localhost/mongo_exam');

// Model
var examModel = require('./models/exam');

// Body Parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// Port
var port = process.env.PORT || 8080;

// Router
var router = require('./routes')(app, examModel);

// Run
var server = app.listen(port, function(){
    console.log("Express server has started on port " + port)
});

 

Package? 

- bodyParser : POST 방식을 사용하게 될 경우 Request Data의 Body에서 데이터를 추출해야함.

그 기능을 편리하게 해줌. Express를 사용할 경우 별도로 Load 하지 않아도 됨(Ref. Expressjs.com).

여기서는 그냥 명시적으로 해줬음.

- Express : 웹 프레임워크. 

- Mongoose : Mongoose 모듈은 MongoDB를 Nodejs에서 사용할 수 있게 함.

 

 

#3. models/exam.js

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

var examSchema = new Schema({
    stringA : String,
    stringB : String
});

module.exports = mongoose.model('exam', examSchema);

- MongoDB는 Schema가 없으나 Mongoose Module을 통해 Schema를 사용할 수 있음.

- Schema를 사용하면 데이터베이스의 테이블, 컬렉션의 타입과 속성을 정의해서 각각의 필드에 저장하는 값에 의존성을 부여할 수 있음.

- Schema의 등록은 mongoose.model을 호출함으로서 등록됨. 첫번째 인자는 collection명으로 사용됨.

- 만약 다른이름으로 지정하고 싶다면 세번째 인자에 그 값을 넣으면 됨.

Ref 1. https://www.zerocho.com/category/MongoDB/post/59a1870210b942001853e250

Ref 2. https://m.blog.naver.com/rwans0397/220696586520

 

 

#4. routes/index.js

 

module.exports = function(app, Exam)
{
    app.post('/create', function(req, res){
        var exam = new Exam();
        exam.stringA = req.body.stringA;
        exam.stringB = req.body.stringB;

        console.log(req);

        exam.save(function(err){
            if(err){
                // fail
                console.error(err);
                res.json({result: 0});
                return;
            }
            // Success
            res.json({result: 1});
        });
    });
}

- Mongoose를 사용하면 save()를 통해 Create를 수행할 수 있음. save가 호출되면 정의되어진 Model에 따라 MongoDB에 저장하게 됨.

 


3. 실행

 

#1. Mongo DB 실행

 

- 상세한 내용 다음 링크 참고 : https://hoonjo.tistory.com/21

 

[MongoDB] MongoDB 설치

1. MongoDB? 요약. # MongoDB는 대용량 데이터를 처리하기에 적합한 NoSQL DB이다. 더보기 NoSQL? No SQL, Not Only SQL, Non-Relational Operational Database SQL 등으로 불림. 기존의 관계형 데이터베이스(RDBM..

hoonjo.tistory.com

명령어

> mongod --dbpath  C:\MongoDB\db

D:\forStudy\nodejs_simaple_exam>mongod --dbpath  C:\MongoDB\db
2020-02-14T19:05:13.006+0900 I  CONTROL  [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
2020-02-14T19:05:13.802+0900 I  CONTROL  [initandlisten] MongoDB starting : pid=30076 port=27017 dbpath=C:\MongoDB\db 64-bit host=DESKTOP-AET4QEL
2020-02-14T19:05:13.803+0900 I  CONTROL  [initandlisten] targetMinOS: Windows 7/Windows Server 2008 R2
2020-02-14T19:05:13.813+0900 I  CONTROL  [initandlisten] db version v4.2.3
2020-02-14T19:05:13.826+0900 I  CONTROL  [initandlisten] git version: 6874650b362138df74be53d366bbefc321ea32d4
2020-02-14T19:05:13.827+0900 I  CONTROL  [initandlisten] allocator: tcmalloc
2020-02-14T19:05:13.835+0900 I  CONTROL  [initandlisten] modules: enterprise
2020-02-14T19:05:13.846+0900 I  CONTROL  [initandlisten] build environment:
2020-02-14T19:05:13.852+0900 I  CONTROL  [initandlisten]     distmod: windows-64
2020-02-14T19:05:13.856+0900 I  CONTROL  [initandlisten]     distarch: x86_64
2020-02-14T19:05:13.856+0900 I  CONTROL  [initandlisten]     target_arch: x86_64
2020-02-14T19:05:13.861+0900 I  CONTROL  [initandlisten] options: { storage: { dbPath: "C:\MongoDB\db" } }
2020-02-14T19:05:13.875+0900 I  STORAGE  [initandlisten] Detected data files in C:\MongoDB\db created by the 'wiredTiger' storage engine, so setting the active storage engine to 'wiredTiger'.
2020-02-14T19:05:13.876+0900 I  STORAGE  [initandlisten] wiredtiger_open config: create,cache_size=15821M,cache_overflow=(file_max=0M),session_max=33000,eviction=(threads_min=4,threads_max=4),config_base=fals
e,statistics=(fast),log=(enabled=true,archive=true,path=journal,compressor=snappy),file_manager=(close_idle_time=100000,close_scan_interval=10,close_handle_minimum=250),statistics_log=(wait=0),verbose=[recove
ry_progress,checkpoint_progress],
2020-02-14T19:05:13.957+0900 I  STORAGE  [initandlisten] WiredTiger message [1581674713:957375][30076:140731849657424], txn-recover: Recovering log 12 through 13
2020-02-14T19:05:14.057+0900 I  STORAGE  [initandlisten] WiredTiger message [1581674714:56576][30076:140731849657424], txn-recover: Recovering log 13 through 13
2020-02-14T19:05:14.159+0900 I  STORAGE  [initandlisten] WiredTiger message [1581674714:158752][30076:140731849657424], txn-recover: Main recovery loop: starting at 12/6144 to 13/256
2020-02-14T19:05:14.344+0900 I  STORAGE  [initandlisten] WiredTiger message [1581674714:343759][30076:140731849657424], txn-recover: Recovering log 12 through 13
2020-02-14T19:05:14.458+0900 I  STORAGE  [initandlisten] WiredTiger message [1581674714:457840][30076:140731849657424], txn-recover: Recovering log 13 through 13
2020-02-14T19:05:14.533+0900 I  STORAGE  [initandlisten] WiredTiger message [1581674714:533232][30076:140731849657424], txn-recover: Set global recovery timestamp: (0, 0)
2020-02-14T19:05:14.584+0900 I  RECOVERY [initandlisten] WiredTiger recoveryTimestamp. Ts: Timestamp(0, 0)
2020-02-14T19:05:14.604+0900 I  STORAGE  [initandlisten] Timestamp monitor starting
2020-02-14T19:05:14.622+0900 I  CONTROL  [initandlisten]
2020-02-14T19:05:14.623+0900 I  CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-02-14T19:05:14.623+0900 I  CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2020-02-14T19:05:14.625+0900 I  CONTROL  [initandlisten]
2020-02-14T19:05:14.625+0900 I  CONTROL  [initandlisten] ** WARNING: This server is bound to localhost.
2020-02-14T19:05:14.625+0900 I  CONTROL  [initandlisten] **          Remote systems will be unable to connect to this server.
2020-02-14T19:05:14.627+0900 I  CONTROL  [initandlisten] **          Start the server with --bind_ip <address> to specify which IP
2020-02-14T19:05:14.627+0900 I  CONTROL  [initandlisten] **          addresses it should serve responses from, or with --bind_ip_all to
2020-02-14T19:05:14.627+0900 I  CONTROL  [initandlisten] **          bind to all interfaces. If this behavior is desired, start the
2020-02-14T19:05:14.629+0900 I  CONTROL  [initandlisten] **          server with --bind_ip 127.0.0.1 to disable this warning.
2020-02-14T19:05:14.629+0900 I  CONTROL  [initandlisten]
2020-02-14T19:05:14.643+0900 I  SHARDING [initandlisten] Marking collection local.system.replset as collection version: <unsharded>
2020-02-14T19:05:14.649+0900 I  STORAGE  [initandlisten] Flow Control is enabled on this deployment.
2020-02-14T19:05:14.649+0900 I  SHARDING [initandlisten] Marking collection admin.system.roles as collection version: <unsharded>
2020-02-14T19:05:14.650+0900 I  SHARDING [initandlisten] Marking collection admin.system.version as collection version: <unsharded>
2020-02-14T19:05:14.655+0900 I  SHARDING [initandlisten] Marking collection local.startup_log as collection version: <unsharded>
2020-02-14T19:05:15.744+0900 I  FTDC     [initandlisten] Initializing full-time diagnostic data capture with directory 'C:/MongoDB/db/diagnostic.data'
2020-02-14T19:05:15.748+0900 I  SHARDING [LogicalSessionCacheRefresh] Marking collection config.system.sessions as collection version: <unsharded>
2020-02-14T19:05:15.748+0900 I  SHARDING [LogicalSessionCacheReap] Marking collection config.transactions as collection version: <unsharded>
2020-02-14T19:05:15.749+0900 I  NETWORK  [listener] Listening on 127.0.0.1
2020-02-14T19:05:15.749+0900 I  NETWORK  [listener] waiting for connections on port 27017
2020-02-14T19:05:16.005+0900 I  SHARDING [ftdc] Marking collection local.oplog.rs as collection version: <unsharded>

 

#2. Run!

- node 명령어를 통해 메인인 app을 run 시킴.

> node app

PS D:\forStudy\nodejs_simaple_exam> node app
(node:1884) DeprecationWarning: current URL string parser is deprecated, and will be removed in a future version. To use the new parser, pass option { useNewUrlParser: true } to MongoClient.connect.
(node:1884) DeprecationWarning: current Server Discovery and Monitoring engine is deprecated, and will be removed in a future version. To use the new Server Discover and Monitoring engine, pass option { useUnifiedTopology: true } to the MongoClient constructor.
Express server has started on port 8080
Connected to mongod server

 

#3. Request

 

- Post 방식으로 데이터 전송 후 정상적으로 값이 저장되었는지 확인하도록 함.

(요청은 크롬 확장프로그램 중 Talend를 사용하였음)

# Request URL
http://localhost:8080/create


# Request Body

{
  "stringA":"TEST",
  "stringB":"TEST1"
}

 

 

#4. Mongo DB 확인

 

PS C:\Users\line play> mongo
MongoDB shell version v4.2.3
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session { "id" : UUID("4906b1b9-a1e1-4b4a-b18a-77e986631baf") }
MongoDB server version: 4.2.3
Server has startup warnings:
2020-02-14T10:47:14.343+0900 I  CONTROL  [initandlisten]
2020-02-14T10:47:14.343+0900 I  CONTROL  [initandlisten] ** WARNING: Access control is not enabled for the database.
2020-02-14T10:47:14.343+0900 I  CONTROL  [initandlisten] **          Read and write access to data and configuration is unrestricted.
2020-02-14T10:47:14.344+0900 I  CONTROL  [initandlisten]
MongoDB Enterprise > use mongo_exam
switched to db mongo_exam
MongoDB Enterprise > show collections
exams
MongoDB Enterprise > db.exams.find()
{ "_id" : ObjectId("5e46733b13efb0075ccd9a85"), "stringA" : "TEST", "stringB" : "TEST1", "__v" : 0 }
MongoDB Enterprise >

 


4. 응용

 

#1. Route 쪼개기

 

- reoutes에 밑에 create.js, read.js, update.js, delete.js를 생성하고 각각의 CRUD를 구현하도록 함.

 

// Load Package
var express     = require('express');
var app         = express();
var bodyParser  = require('body-parser');
var mongoose    = require('mongoose');

// MongoDB
var db = mongoose.connection;
db.on('error', console.error);
db.once('open', function(){
    // CONNECTED TO MONGODB SERVER
    console.log("Connected to mongod server");
});

mongoose.connect('mongodb://localhost/mongo_exam');

// Model
var examModel = require('./models/exam');

// Body Parser
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());

// Port
var port = process.env.PORT || 8080;

// Router
// router = require('./routes')(app, examModel);
require('./routes/create.js')(app, examModel);
require('./routes/read.js')(app, examModel);
require('./routes/update.js')(app, examModel);
require('./routes/delete.js')(app, examModel);


// Run
var server = app.listen(port, function(){
    console.log("Express server has started on port " + port)
});

 

#2. CRUD 구현

 

- Create : 앞서 구현한 내용이므로 설명 생략

module.exports = function(app, Exam)
{
    app.post('/create', function(req, res){
        var exam = new Exam();
        exam.stringA = req.body.stringA;
        exam.stringB = req.body.stringB;

        console.log(req);

        exam.save(function(err){
            if(err){
                // fail
                console.error(err);
                res.json({result: 0});
                return;
            }
            // Success
            res.json({result: 1});
        });
    });

}

 

- Read : Read의 경우 find 함수를 이용하여 데이터를 읽어올 수 있음.

module.exports = function(app, Exam)
{
    app.get('/read', function(req,res){
        Exam.find(function(err, exams){
            if(err) return res.status(500).send({error: 'read fail'});
            res.json(exams);
        })
    });
}

 

http://localhost:8080/read

 

- Update : Update의 경우 Update할 대상을 find() 를 이용해 찾고 save()를 통해 저장하면 됨.

 

module.exports = function(app, Exam) {
    
    app.put('/update/:id', function(req, res){

        // FIND & UPDATE
        Exam.findById(req.params.id, function(err, exam) {
            // 값을 변경 후 exam에 저장
            exam.stringA = req.body.stringA;
            exam.stringB = req.body.stringB;

            // exam 저장
            exam.save(function (err) {
                if(err) res.status(500).json({error: 'Update Fail'});
                res.json({message: 'Update Complete'});
            });
        });

    });
}

 

# 실행

실행

더보기

Method : Put

URL : http://localhost:8080/update/{id값}

Body :

{ 
  "stringA":"TEST_A", 
  "stringB":"TEST_B" 
}

 

# 데이터 비교

Update 전 Update 후
{
  "stringA":"TEST",
  "stringB":"TEST1"
}
{
  "stringA":"TEST_A",
  "stringB":"TEST_B"
}

 

# 기본 로직에 Parameter에 대한 Null과 Error에 대한 Response를 추가하면 다음과 같음.

module.exports = function(app, Exam) {

    app.put('/update/:id', function(req, res){

        // FIND & UPDATE
        Exam.findById(req.params.id, function(err, exam) {

            if(err) return res.status(500).json({ error: 'Internal Server Error - Database (500)' });
            if(!exam) return res.status(404).json({ error: 'Not Found (404)' });

            // 값을 변경 후 exam에 저장
            if(req.body.stringA) exam.stringA = req.body.stringA;
            if(req.body.stringB) exam.stringB = req.body.stringB;


            // exam 저장
            exam.save(function (err) {
                if(err) res.status(500).json({error: 'Update Fail'});
                res.json({message: 'Update Complete'});
            });
        });

    });
}

 

- Delete : Delete의 경우 remove() 함수를 통해 구현할 수 있음.

module.exports = function(app, Exam) {
    app.delete('/delete/:id', function(req, res){
        Exam.remove({ _id: req.params.id }, function(err){
            if(err) return res.status(500).json({ error: 'Internal Server Error - Database (500)' });
        })
    });
}

 

# 실행

 

더보기

Method : Delete

URL : http://localhost:8080/update/http://localhost:8080/delete/{id값}

 

# 데이터 비교

Update 전 Update 후

마치며,

 

CRUD나 Routing은 기존의 언어에 비해 쉽고 간결함.

위 내용은 아래 블로그를 참고함. (자세히 정리되어있음)

https://velopert.com/594

 

[Node.JS] 강좌 11편: Express와 Mongoose를 통해 MongoDB와 연동하여 RESTful API 만들기 | VELOPERT.LOG

이번 강좌에서는 Mongoose 를 통하여 Node.js 에서 MongoDB와 연동하는것을 배워보겠습니다. 1. 소개 Mongoose는 MongoDB 기반 ODM(Object Data Mapping) Node.JS 전용 라이브러리입니다. ODM은 데이터베이스와 객체지향 프로그래밍 언어 사이 호환되지 않는 데이터를 변환하는 프로그래밍 기법입니다. 즉 MongoDB 에 있는 데이터를 여러분의 Application에서 JavaScript 객체로 사용 할 수 있

velopert.com

 

+ 코드 첨부함.

nodejs_simaple_exam.zip
2.22MB

'Study > NodeJS' 카테고리의 다른 글

[Node.js] Git 사용 & 서버 배포  (0) 2020.03.09
[Node.js] Simple Express Preject  (1) 2020.02.19
[Node.js] Mongo DB 사용  (2) 2020.02.11
[Node.js] 기본적인 MongoDB 연결과 확인  (4) 2020.02.07
[Node.js] Study. Hello World!  (0) 2020.02.06
공지사항
최근에 올라온 글
최근에 달린 댓글
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
글 보관함