블로그 이미지
윤영식
Full Stacker, Application Architecter, KnowHow Dispenser and Bike Rider

Publication

Category

Recent Post

2013. 9. 23. 11:40 NodeJS/Concept

Node.js 위에 기본적으로 Express.js를 많이 사용하지만 좀 더 추상화 되고 MVC 다운 프레임워크를 사용해 보고자. Express.js 및 Socket.io 와 다양한 데이터베이스를 추상화해서 사용할 수 있는 기능을 갖춘 Sails.js Framework을 사용해 보도록 한다. 



1. 사용 배경

  - Enterprise 급 MVC Framework : Express.js + Socket.io 기본 설정되어 사용

  - Waterline 이라는 adapter를 통하여 다양한 Database의 호환성 보장 

    + 흐름 : Model 객체 <-> Waterline <-> Databases 

    + 지원 데이터베이스 : MySql, PostgreSql, MongoDB, etc

    + 데이터베이스 연결을 하지 않으면 파일 또는 디스크에 백만개 밑으로 key:value 저장하는 node-dirty의 어뎁터를 사용한다

  - 손쉬운 설치 및 RESTful Web Services 개발

  - socket.io 및 redis 통합 

  - SPA (Single Page Application) 개발을 위한 client framework (backbone, ember, angular)의 adapter 제공 

    + Yeoman generator 제공 : Generator Sails AngularJS



2. 설치 및 사용

  - Yeoman을 기본 설치한다 : Yeoman 이해와 설치하기

  - "generator-sails-angular" 설치 후 "yo" 명령수행 : 빨간색의 Sails-angular 선택 (주의, sails 0.9.4 버전과 호환안됨)

// generator 설치

$ sudo npm install -g generator-sails-angular generator-angular


// yeoman 명령 수행

$ yo

[?] What would you like to do? (Use arrow keys)

 ❯ Run the Angular generator (0.3.1)

   Run the Backbone generator (0.1.7)

   Run the Bootstrap generator (0.1.3)

   Run the Express generator (0.1.0)

   Run the Generator generator (0.2.0)

   Run the Mocha generator (0.1.1)

   Run the Sails-angular generator (0.0.1)

   Update your generators

   Install a generator

   Find some help

   Get me out of here!


// 선택을 하면 Server에 Sails 환경과 Client에 AngularJS 환경이 동시에 설정된다 

// Client는 기본 Twitter bootstrap을 사용하고 Client 추가 Component는 "bower install <Component명칭>" 을 사용하여 설치한다 

// Server는 "npm install <module명칭>"을 사용하여 설치한다


  - "sails lift" 수행 (2013.09.23현재 0.9.4 버전으로 sails upgrade : sudo npm update sails -g )

$ sails lift

info:

info:

info:    Sails.js           <|

info:    v0.9.4              |\

info:                       /|.\

info:                      / || \

info:                    ,'  |'  \

info:                 .-'.-==|/_--'

info:                 `--'-------'

info:    __---___--___---___--___---___--___

info:  ____---___--___---___--___---___--___-__

info:

info: Server lifted in `/Users/prototyping/sails/test`

info: To see your app, visit http://localhost:1337

info: To shut down Sails, press <CTRL> + C at any time.


debug: --------------------------------------------------------

debug: :: Mon Sep 23 2013 10:05:04 GMT+0900 (KST)

debug:

debug: Environment : development

debug: Port : 1337

debug: --------------------------------------------------------



3. Sails MVC 이해하기 

  - Model 

    + Waterline 이라는 Sails Adapter를 통하여 다양한 데이터베이스의 객체로 사용되어 진다 

    + 단, Waterline의 형식(JSON 포멧)에 맞추어서 Model을 정의한다 : 모든 데이터베이스에 추상화된 정의이다 

    + /config/adapters.js 파일에 Database 환경 설정을 한다 또한 관련 데이터 베이스 adapter를 설치해야 함 

       예) MongoDB 설치 

$ npm install sails-mongo --save

npm http 200 https://registry.npmjs.org/sails-mongo

npm http GET https://registry.npmjs.org/sails-mongo/-/sails-mongo-0.9.5.tgz

.. 중략 ..

    + /api/models/ 디렉토리 밑에 <Model>.js 파일이 위치한다

// model 생성  

$ sails generate model Person


// 생성 내역 : Model의 맨앞자는 자동으로 대문자로 변경됨 

$ /api/models> cat Person.js

/*---------------------

:: Person

-> model

---------------------*/

module.exports = {

attributes : {

// Simple attribute:

// name: 'STRING',


// Or for more flexibility:

// phoneNumber: {

// type: 'STRING',

// defaultValue: '555-555-5555'

// }

}

};/


// CRUD : 기본 Deferred Promised 지원 

생성 : Person.create

조회 : Person.findOne/find

갱신 : Person.update

제거 : Person.destroy



  - Controller

    + view와 model 사이의 제어 역할을 한다

    + /api/controllers/ 디렉토리에 위치함 

// comment controller 만들기 : 최종 명령 tag뒤에 스페이스가 있으면 안된다. 

// controller 뒤 첫번째 인자 : comment가 controller의 명칭

// controller 두번째 인자이후 : comment의 메소드 명칭들 열거  

$ sails generate controller comment create like tag 


// 결과 

$ /api/controllers> cat CommentController.js

/*---------------------

:: Comment

-> controller

---------------------*/

var CommentController = {

// To trigger this action locally, visit: `http://localhost:port/comment/create`

create: function (req,res) {

// This will render the view: /views/comment/create.ejs

res.view();

},


// To trigger this action locally, visit: `http://localhost:port/comment/like`

like: function (req,res) {

// This will render the view: /views/comment/like.ejs

res.view();

},


// To trigger this action locally, visit: `http://localhost:port/comment/tag`

tag: function (req,res) {

// This will render the view:/views/comment/tag.ejs

res.view();

}


};

module.exports = CommentController; 


// 브라우져 호출 

http://localhost:1337/comment/create (like, tag) 


  - Route

    + RESTful 호출을 uri를 제어하고 싶다면 Route를 지정한다 

    + /config/routes.js 파일안에 정의한다 

    + controller와 action을 정의한다 

    + home의 경우 

       1) /config/routes.js 에 하기와 같이 home 컨트롤러 정의 

       2) /api/controllers/HomeController.js 존재 : index액션(펑션) 존재

       3) /views/home/index.ejs 파일 존재 : 서버에서 rendering되어 클라이언트 응답 

// Routes

// *********************

// 

// This table routes urls to controllers/actions.

//

// If the URL is not specified here, the default route for a URL is:  /:controller/:action/:id

// where :controller, :action, and the :id request parameter are derived from the url

//

// If :action is not specified, Sails will redirect to the appropriate action 

// based on the HTTP verb: (using REST/Backbone conventions)

//

// action을 정의하지 않으면 다음의 기본 형식을 따른다 

// GET:     /:controller/read/:id

// POST:   /:controller/create

// PUT:      /:controller/update/:id

// DELETE:/:controller/destroy/:id

//

// If the requested controller/action doesn't exist:

//   - if a view exists ( /views/:controller/:action.ejs ), Sails will render that view

//   - if no view exists, but a model exists, Sails will automatically generate a 

//       JSON API for the model which matches :controller.

//   - if no view OR model exists, Sails will respond with a 404.

//

module.exports.routes = {

// To route the home page to the "index" action of the "home" controller:

'/' : {

controller : 'home'

}


// If you want to set up a route only for a particular HTTP method/verb 

// (GET, POST, PUT, DELETE) you can specify the verb before the path:

// 'post /signup': {

// controller : 'user',

// action : 'signup'

// }


// Keep in mind default routes exist for each of your controllers

// So if you have a UserController with an action called "juggle" 

// a route will be automatically exist mapping it to /user/juggle.

//

// Additionally, unless you override them, new controllers will have 

// create(), find(), findAll(), update(), and destroy() actions, 

// and routes will exist for them as follows:

/*


// Standard RESTful routing

// (if index is not defined, findAll will be used)

'get /user': {

controller : 'user',

action : 'index'

},

'get /user/:id': {

controller : 'user',

action : 'find'

},

'post /user': {

controller : 'user',

action : 'create'

},

'put /user/:id': {

controller : 'user',

action : 'update'

},

'delete /user/:id': {

controller : 'user',

action : 'destroy'

}

*/

};


  - View

    + Sails는 기본 ejs를 사용한다 

    + /views/ 밑에 위치한다 

    + Partial 파일을 include 할 수 있다 

    + 메인 파일 : layout.ejs 

   


  - Adapter

    + 데이터베이스를 바꾸고 싶다면 /config/adapters.js 에서 내용을 바꾼다 : MongoDB를 사용한다면 mongo adapter를 설치해야 한다

// Configure installed adapters

// If you define an attribute in your model definition, 

// it will override anything from this global config.

module.exports.adapters = {


// If you leave the adapter config unspecified 

// in a model definition, 'default' will be used.

'default': 'memory',

// In-memory adapter for DEVELOPMENT ONLY

// (data is NOT preserved when the server shuts down)

        // Sails-dirty는 Node-Dirty의 Adapter를 memory or disk에 JSON 을 저장하는 store이다. 백만개 밑으로 저장시 사용

memory: {

module: 'sails-dirty',

inMemory: true

},


// Persistent adapter for DEVELOPMENT ONLY

// (data IS preserved when the server shuts down)

// PLEASE NOTE: disk adapter not compatible with node v0.10.0 currently 

// because of limitations in node-dirty

// See https://github.com/felixge/node-dirty/issues/34

disk: {

module: 'sails-dirty',

filePath: './.tmp/dirty.db',

inMemory: false

},


// MySQL is the world's most popular relational database.

// Learn more: http://en.wikipedia.org/wiki/MySQL

mysql: {

module : 'sails-mysql',

host : 'YOUR_MYSQL_SERVER_HOSTNAME_OR_IP_ADDRESS',

user : 'YOUR_MYSQL_USER',

password : 'YOUR_MYSQL_PASSWORD',

database : 'YOUR_MYSQL_DB'

}

};

   + generator-sails-angular 를 yeoman통하여 설치하였다면 SPA를 개발하는 것이므로 실제로 ejs 쓸 일이 거의 없고, Client 단에서 AngularJS 정의에 따라 Routing과 View Control이 발생한다. 따라서 Controller를 통하여 수행할 action에서 response.view() 하는 것이 아니라, response.json(<JSON Object>) 만을 응답으로 주면 될 것으로 보인다. 또한 업무적인 처리는 action에서 구현하면 된다   

   + response.send(형식)

res.send(); // 204

res.send(new Buffer('wahoo'));

res.send({ some: 'json' });

res.send('<p>some html</p>');

res.send('Sorry, cant find that', 404);

res.send('text', { 'Content-Type': 'text/plain' }, 201);

res.send(404);

   + response.json(형식)

res.json(null);

res.json({ user: 'tj' });

res.json('oh noes!', 500);

res.json('I dont have that', 404);


* Redis나 데이터베이스의 외부 인터페이스 라이브러리는 Custom Adapter 개발을 수행한다. (만드는 방법



3. MongoDB 연결하여 RESTful 호출 테스트 

  - mongodb 환경설정 : sails-mongo 어뎁터가 설치되어 있어야 함 

$ cd config && vi adapters.js  이동하여 mongodb 설정 입력


////////////////////////

// adapters.js 수정 내역 

module.exports.adapters = {

  // If you leave the adapter config unspecified 

  // in a model definition, 'default' will be used.

  'default': 'mongo',


  // In-memory adapter for DEVELOPMENT ONLY

  memory: {

    module: 'sails-memory'

  },


  // Persistent adapter for DEVELOPMENT ONLY

  // (data IS preserved when the server shuts down)

  disk: {

    module: 'sails-disk'

  },


  // sails v.0.9.0

  mongo: {

    module   : 'sails-mongo',

    host     : 'localhost',

    port     : 27017,

    user     : '',

    password : '',

    database : 'sailsdb'

  }

};

  

  - Person model 수정

// ProjectName/models/Person.js  수정 내역 

module.exports = {

  attributes: {

  name: 'string',

  phone: 'string',

  address: 'string',

  sex: 'string',

  etc: 'string' 

  }

};


  - PersonController의 create 수정 : Promise 구문 형식 사용가능  

// ProjectName/controllers/PersonController.js  수정 내역

module.exports = {

  create: function (req,res) {

    Person.create({ 

      name: req.param('name'),

      phone: req.param('phone'),

      address: req.param('address'),

      sex: req.param('sex'),

      etc: req.param('etc')

    }).done(function(err, person){

      if(err) throw err;

      res.json(person);

    });

  },

  .. 중략 ..

}


  - Postman을 통하여 호출 테스트 : Postman chrome extension을 설치한다. 


  - mongo shell 에서 person collection 조회 : model이 mongodb에서 collection과 맵핑된다  

///////////////////

// mongo shell 확인 

mongo

MongoDB shell version: 2.4.5

connecting to: test

show dbs

local 0.078125GB

sailsdb 0.203125GB

use sailsdb

switched to db sailsdb

show collections

person

system.indexes

> db.person.find();

{ "name" : "도원", "phone" : "1004", "address" : "seoul", "sex" : "man", "etc" : "developer", "createdAt" : ISODate("2013-09-23T02:28:51.281Z"), "updatedAt" : ISODate("2013-09-23T02:28:51.281Z"), "_id" : ObjectId("523fa76377e9f89562000001") }



4. MongoDB의 _id를 sequence number로 바꾸기 

  - "_id" : ObjectId("523fa76377e9f89562000001") 라고 나오는 것을 "_id" : 1 씩 증가하는 정수로 바꾸기 

  - 최대한 sails-mongo adapter의 api를 사용하여 구현한다 

  - sequence document 만들기 

> db.seq.insert(

 {

   _id: 'personid',

   seq: 0

 });

> db.seq.find();

{ "_id" : "personid", "seq" : 0 }


  - Sails Model을 정의한다 

$ sails generate model seq

$ cd models && vi Seq.js


// Seq.js 내역 

// _id를 통하여 여러 model의 sequence 값을 구분하기 위해 사용한다 

module.exports = {

  attributes: {

  _id: 'string',

  seq: 'integer'

  }

};


  - Person의 모델에서 명시적으로 _id 를 integer로 정의한다 

module.exports = {

  attributes: {

  _id: 'integer',

  name: 'string',

  phone: 'string',

  address: 'string',

  sex: 'string',

  etc: 'string'

  }

};


  - PersonController.js 내역 수정 : Gist 소스 파일

  /**

   * /person/create

   */ 

  create: function (req,res) {

      // seq 번호를 얻어온다 

      Seq.find({_id: 'personid'}).done(function(err, seqObj) {

        if(err) throw err;

        // 배열임을 주의  

        var seqNo = seqObj[0].seq;

        seqNo++;

        console.log('>>> seqNo is', seqNo);

        

        // insert시에 _id 값을 넣어준다 

        Person.create({ 

          _id: seqNo, 

          name: req.param('name'),

          phone: req.param('phone'),

          address: req.param('address'),

          sex: req.param('sex'),

          etc: req.param('etc')

        }).done(function(err, person){

          if(err) throw err;

          res.json(person);

        });


       // sails-mongo의 api에 한번에 select & update해주는 findAndModify 메소드가 없는 관계로 seqNo를 update해준다 

        Seq.update({_id: 'personid'}, {seq: seqNo}).done(function(err, seqObj){

          if(err) throw err;

        })

      });

  },


  - Postman으로 테스트 데이터를 입력한다 


  - mongo shell로 mongodb에 저장된 내역을 확인해 보자 

// postman통하여 데이터를 2개 넣었을 경우 

> db.seq.find();

{ "_id" : "personid", "seq" : 2, "updatedAt" : ISODate("2013-09-23T09:47:29.548Z") }


> db.person.find();

{ "_id" : 1, "name" : "윤도원-8", "phone" : "1004", "address" : "목동", "sex" : "사람", "etc" : "모비콘 블로깅", "createdAt" : ISODate("2013-09-23T09:45:36.391Z"), "updatedAt" : ISODate("2013-09-23T09:45:36.391Z") }

{ "_id" : 2, "name" : "윤도원-9", "phone" : "1004", "address" : "목동", "sex" : "사람", "etc" : "모비콘 블로깅", "createdAt" : ISODate("2013-09-23T09:47:29.547Z"), "updatedAt" : ISODate("2013-09-23T09:47:29.547Z") }

>

 

 

5. Sails를 통항 WebApp 만들기

  - SailsCast Site 참조

  - SailsCast GitHub 소스

  - 유튜브 동영상 25 강좌 보기


 

<참조>

  - Sails.js + AngularJS + MongoDB 데모

  - MongoDB auto increment Sequence Field 방법

  - Mongoose Sequence Table 통한 auto increment plugin  : express 와 mongoose 사용시 해당 plugin을 사용

posted by 윤영식
2013. 8. 12. 17:39 Dev Environment/Docker

가상머신 관리도구인 Vagrant를 통하여 Node.js + MongoDB 개발환경을 구축해 본다.



1. 설치 

  - VirtualBox 다운로드 및 설치

  - Vagrant 다운로드 및 설치

  - Vagrant 환경 설정

    + 프로젝트 디렉토리를 하나 만든다. 또는 기존 Project가 있으면 디렉토리로 이동한다. VirtualBox에 원하는 이미지를 다운로드하여 설치한다. 이미지는 Vagrant에서 패키징한 Box를 다운로드할 수 있는 별도 사이트 제공한다 

    + Box는 기본설정과 OS가 설치된 VM 템플릿 이미지이다 

// 형식 : vagrant box add [title] [download-url] 

$ vagrant box add centos64 http://developer.nrel.gov/downloads/vagrant-boxes/CentOS-6.4-x86_64-v20130427.box

Downloading or copying the box...

    + 프로젝트를 초기화 한다

vagrant init centos64


// 결과 : 환경설정 파일 1개 생성됨 

Vagrantfile 



2. 가상머신 기동

  - Vagrant 통해 가상머신 기동하기 

// 기동

$ vagrant up

Bringing machine 'default' up with 'virtualbox' provider...

[default] Importing base box 'centos64'...

[default] Matching MAC address for NAT networking...

[default] Setting the name of the VM...

[default] Clearing any previously set forwarded ports...

[default] Creating shared folders metadata...

[default] Clearing any previously set network interfaces...

[default] Preparing network interfaces based on configuration...

[default] Forwarding ports...

[default] -- 22 => 2222 (adapter 1)

[default] Booting VM...

[default] Waiting for VM to boot. This can take a few minutes.

[default] VM booted and ready for use!

[default] Mounting shared folders...

[default] -- /vagrant


// VirtualBox VM이 자동으로 수행된 것을 볼 수 있다 

// VM 들어가기 : 같은 디렉토리면 ssh를 n개까지 open 가능 

// ssh를 통하여 별도의 VM 으로 들어갈 수가 있는 것이다. 

// 단, vagrant init [title] 된 Vagrantfile 파일이 같은 디렉토리에 있어야 함

$ vagrant ssh

Welcome to your Vagrant-built virtual machine.

[vagrant@localhost ~]$ 


// 정지

$ vagrant halt



3. Node.js & MongoDB, etc 개발환경 구축하기 

  - 제일 먼저 yum update 수행, 프로젝트 파일과 관계없는 운영 미들웨어 및 데이터베이스 설정이다. 

  - CentOS 64bit Node.js 설치하기 

    + 컴파일해서 설치함

  - CentOS 64bit MongoDB 설치하기 

  - CentOS 64bit Git 설치하기

  - Yeoman work flow 환경도 설치

    + yeoman, grunt, bower 설치 : sudo npm install -g yo grunt-cli bower

    + yeoman generator 설치 : sudo npm install -g generator-webapp

  - Sails.js Framework 기반 개발을 위하여 설치

    + sudo npm install -g sails@0.8.9

    + 버전 지정안하면 최신 버전인 0.9.5 설치됨



4. 애플리케이션 활용하기 

  - 개발환경을 구축하고 자신의 로컬머신에 있는 프로젝트 파일을 VM에도 설치해야 하는가?

    재배포 필요없이 로컬에 있는 파일을 VM에 sync folder 기능을 이용하여 Share 할 수 있다 

  - 프로젝트 파일 공유 : Vagrantfile 내역 (참조)

// 형식 

config.vm.synced_folder "[내 로컬머신의 디렉토리 절대경로]", "[VM에 로딩할 절대경로와 가상디렉토리명 지정]"


// 설정 예

config.vm.synced_folder "/Users/development/smart-solutions/SmartStatistics", "/home/vagrant/SmartStatistics"


// VM reloading 및 결과 

/Users/development/smart-solutions/SmartStatistics> vagrant reload

[default] Attempting graceful shutdown of VM...

[default] Setting the name of the VM...

.. 중략 ..

[default] Mounting shared folders...

[default] -- /vagrant

[default] -- /home/vagrant/SmartStatistics


/Users/development/smart-solutions/SmartStatistics> vagrant ssh

Last login: Mon Aug 12 08:09:35 2013 from 10.0.2.2

Welcome to your Vagrant-built virtual machine.

[vagrant@localhost ~]$ sudo iptables -F

[vagrant@localhost ~]$ cd SmartStatistics/

[vagrant@localhost SmartStatistics]$ pwd

/home/vagrant/SmartStatistics

  - 로컬과 VM의 파일을 서로 Share하였고 서버를 뛰우면 VM에서도 동일 Port로 뜰 것이다. 예) Sails는 default 1337 port를 사용한다 

     VM은 1337 port 를 사용하고 로컬 머신은 1338 port를 사용해서 port forwarding을 한다. 

     즉, 로컬 머신의 브라우져에서 http://localhost:1338 호출하면 VM의 1337 port를 통하여 서비스가 이루어진다(Port Forwarding)

  - 포트 충돌 해결 : Vagrantfile 내역 (참조)

// 형식 

config.vm.network :forwarded_port, guest: [VM에서 사용할 port번호], host: [내 로컬머신에서 사용할 port 번호]


// 설정 예 

config.vm.network :forwarded_port, guest: 1337, host: 1338


// VM reloading 및 결과

/Users/development/smart-solutions/SmartStatistics> vagrant reload

[default] Attempting graceful shutdown of VM...

[default] Setting the name of the VM...

[default] Forwarding ports...

.. 중략 ..

[default] -- 22 => 2222 (adapter 1)

[default] -- 1337 => 1338 (adapter 1)

[default] Booting VM...

[default] Mounting shared folders...

[default] -- /vagrant

[default] -- /home/vagrant/SmartStatistics

 

- vagrant VM

[vagrant@localhost SmartStatistics]$ netstat -na | grep 1337

tcp        0      0 0.0.0.0:1337                0.0.0.0:*                   LISTEN


- local my machine

/Users/development/smart-solutions/SmartStatistics> netstat -na|grep 1338

tcp4       0      0  *.1338                 *.*                    LISTEN

  - 테스트 수행 : port forwarding이 안될 경우 "sudo iptables -F" 를 통하여 강제 재설정을 해준다. 그리고 다시 curl 수행하여 체크 

// curl 이용하여 호출을 했는데 결과값이 나오지 않으면 iptables 에 대한 설정을 해준다 

/Users/development/smart-solutions/SmartStatistics> curl -v http://localhost:1338/

* About to connect() to localhost port 1338 (#0)

*   Trying ::1...

* Connection refused

*   Trying 127.0.0.1...

* connected

* Connected to localhost (127.0.0.1) port 1338 (#0)


// vagrant ssh (port forwarding이 안될 경우)

// 하기 명령을 .bash_profile 에 넣어서 자동화 한다 

/Users/development/smart-solutions/SmartStatistics> vagrant ssh

Last login: Mon Aug 12 08:09:35 2013 from 10.0.2.2

Welcome to your Vagrant-built virtual machine.

[vagrant@localhost ~]$ sudo iptables -F

  - 로컬 머신의 브라우져에서 호출 : "http://localhost:1338"



5. Package 만들기 

  - 기존에 쓰던 VM 이미지를 Vagrant의 Box로 만들어서 개발환경을 미리 패키징할 수 있다  

// 형식 : vagrant package --base <target> --output <output>.box



6. Provisioning 하기

   

  - Vagrant up 수행시 최초 실행되는 매크로 관리 도구인 Chef를 사용한다

  - Chef Solo Provisioning 을 하면 Chef Server가 필요없이 사용할 수 있다 

  - Opscode Cookbooks 에서 원하는 receipe 를 내려받아서 설정해 놓으면 자동 실행된다 



<참조>

  - Vagrant 설치 및 기동

  - SKPlanet의 Vagrant 설치 및 자료

  - Vagrant, Chef 살펴보기 

  - Chef Server 설치하기 튜토리얼

  - KTH의 Chef 블로깅

    


posted by 윤영식
2013. 5. 7. 09:37 NodeJS/Concept

서비스 또는 솔루션을 만들기 위해 Node.js와 Express.js를 선택하였다면  그 다음 고민은 애플리케이션 개발을 위하여 필요한 스택을 선정하는 일이다. 크게는 로깅, 환경설정, 통신등 기본적인 부분들을 직접 개발하지 말고 이미 만들어진 바퀴를 공짜로 구해서 달아보자 



1. 준비하기 

  - Programming Javascript Application Book 책의 내용을 발췌한 것이다 

  - Node 버전관리 NVM 설치 

    + https://github.com/creationix/nvm

    + 설치 : nvm install [버전]

    + 수행 : nvm run [버전]

    + 확인 : nvm ls  (설치된 버전 목록을 보여줌)

    + 가능 : nvm ls-remote (설치 가능 버전 목록을 보여줌)

  - nvm 설치 명령 : git 사전 설치요구 : 수행시 nvm.sh 에 syntax오류가 나오면 nvm.sh을 copy하고 기존것 삭제후 다시 paste하여 만듦

$ curl https://raw.github.com/creationix/nvm/master/install.sh | sh


    + 기타 명령들 

$ nvm help


Node Version Manager


Usage:

    nvm help                          Show this message

    nvm install [-s] <version>  Download and install a <version>

    nvm uninstall <version>     Uninstall a version

    nvm use <version>           Modify PATH to use <version>

    nvm run <version> [<args>]  Run <version> with <args> as arguments

    nvm ls                            List installed versions

    nvm ls <version>             List versions matching a given description

    nvm ls-remote                 List remote versions available for install

    nvm deactivate                Undo effects of NVM on current shell

    nvm alias [<pattern>]      Show all aliases beginning with <pattern>

    nvm alias <name> <version>    Set an alias named <name> pointing to <version>

    nvm unalias <name>                Deletes the alias named <name>

    nvm copy-packages <version> Install global NPM packages contained in <version> to current version


Example:

    nvm install v0.4.12            Install a specific version number

    nvm use 0.2                    Use the latest available 0.2.x release

    nvm run 0.4.12 myApp.js   Run myApp.js using node v0.4.12

    nvm alias default 0.4        Auto use the latest installed v0.4.x version


  - 프로젝트 만들고 초기화 하기 

    + 디렉토리 만들고 해당 디렉토리로 이동

    + npm init 수행하여 package.json 파일 만들기 : 이름, 버전, 설명, 키워드, 저장소위치, 라이센스 및 기타 정보등을 입력한다 

$ mkdir basic && cd basic

$ npm init

This utility will walk you through creating a package.json file.

It only covers the most common items, and tries to guess sane defaults.


See `npm help json` for definitive documentation on these fields

and exactly what they do.


Use `npm install <pkg> --save` afterwards to install a package and

save it as a dependency in the package.json file.


Press ^C at any time to quit.

name: (basic) JavaScript-Programming

version: (0.0.0) 0.0.1

description: This is a javascript programming

entry point: (index.js)

test command: grunt test

git repository: https:/github.com/ysyun/javascriptacular

keywords: angularjs

author: yun dowon

license: (BSD) MIT

About to write to /Users/prototyping/express/basic/package.json:


{

  "name": "JavaScript-Programming",

  "version": "0.0.1",

  "description": "This is a javascript programming ",

  "main": "index.js",

  "scripts": {

    "test": "grunt test"

  },

  "repository": {

    "type": "git",

    "url": "https:/github.com/ysyun/javascriptacular"

  },

  "keywords": [

    "angularjs"

  ],

  "author": "yun dowon",

  "license": "MIT"

}



Is this ok? (yes)

npm WARN package.json JavaScript-Programming@0.0.1 No README.md file found!

$ ls -lart

-rw-r--r--  1 nulpulum  staff  360  5  7 09:22 package.json

drwxr-xr-x  3 nulpulum  staff  102  5  7 09:22 .


  - 모듈 설치시에 package.json 파일에 자동 기록을 위하여 npm install --save [module] 처럼 --save 옵션을 준다 



2. 준비할 스택들

  • Mout Like Underscore / LoDash. Stuff that should probably be included in JavaScript.

  • Express Web application framework.

  • Nconf Application config.

  • Hogan Mustache for express. (Jade 또는 EJS 를 써도 됨)

  • Superagent Communicate with APIs.

  • Socket.io Realtime communications (websockets).

  • Q Promises.

  • Async Asynchronous functional utilities.

  • Bunyan Logging. (Winston도 많이 사용)

  • Tape Testing. (Mocha, Karma 도 사용)

  • Cuid Better than guid/uuid for web applications.

  • Derby.js Add realtime, collaborative MVC to express. (Sails.js 또는 Bone.js 도 사용)

  • Node-http-proxy Proxy your service APIs.



3. Express 사용하기 

  - Routing 을 이용한다

  - Middleware를 통하여 중간에 Hooking 하여 처리하고 다음으로 next() 호출 넘기는 use 를 사용한다 

// Add some data to the request object that your other
// midleware and routes can use.
app.use(function (req, res, next) {
  req.foo = 'bar';
  next();

});

    + 전체 예제 

'use strict';
var express = require('express'),
 
  // Create app instance.
  app = express(),
 
  // Use the `PORT` environment variable, or port 44444
  port = process.env.PORT || 44444;
 
// The new middleware adds the property `foo` to the request
// object and sets it to 'bar'.
app.use(function (req, res, next) {
  req.foo = 'bar';
  next();
});
 
app.get('/', function (req, res) {
  res.setHeader('Content-Type', 'text/plain');
 
  // Send the value passed from the middleware, above.
  res.end(req.foo);
});
 
app.listen(port, function () {
  console.log('Listening on port ' + port);

});


// 결과 : use를 설정한 순서대로 처리된다 

$ curl http://localhost:44444/
bar



4. SailsJS

  - 난 sails를 Full Stack Server Side Data-Oriented API Framework 이라고 말하고 싶다.

  - Front-end 단이 SPA로 개발될 경우

  - Back-end를 API 서버로 확장함 

  - Node.js + Express.js + MongoDB 와 연결 및 JSON Memory DB 사용가능

    + sails-angularjs-yeoman 의 로그인 데모

    + sails-mongodb 연결

    + sails-redis 연결



<참조>

   - 원문 : Getting start with Node and Express 

   - middleware의 next() 사용법 : Node.js의 connect 이해하기

   - AngularJS와 MongoDB 연결 Bridge


posted by 윤영식
prev 1 next