1. swig

node.js 의 기본 template 모듈은 ejs와 jade를 많이 사용한다.

ejs는 html 형식에 javascript가 embedding된 형식이라서 쉽게 익힐 수 있다.

하지만 template 상속을 지원하지 않는 단점이 있다.


jade는 html태그 형식이 완전히 바뀌어 익히는 데 조금 어려움이 있지만 

다양한 api를 제공하는 장점이 있다.


node.js swig 모델은 위의 두 모델의 장점만을 살린 모델이라고 할 수 있겠다.

template engine으로 html을 사용하며 다양한 api를 지원한다.


extends, import ,include...등등을 응용할 수 있다. 

http://paularmstrong.github.io/swig 을 참조.


2. request 

node.js는 server-side language 이다. 

보통 request를 받아서 처리하는 데, 다른 외부 서버에 request를 하는 경우가 있을 수 있다.

이럴 때 request 모듈을 사용하면 유용하다.

https://www.npmjs.com/package/request 을 참조


3. xml-mapping

xml 데이터 형식을 json으로 바꾸거나 다른 형식으로 바꾸어 주는 module이다.


4. iconv

encoding 형식을 변경해준다.

euc-kr 에서 utf8로 변경하기 위해 사용했다.


5. crypto 

비밀번호 암호화를 제공해주는 모듈이다.

api가 약간 복잡하여(?) 현재 bcrypt-nodejs를 쓰고 있지만,

node.js 공식 api에도 소개되어 있는 module인 만큼 꼭 써봐야 하겠다.


6. view-helper

보통 web project는 mvc pattern을 이용하여 프로젝트를 많이 한다.

view-helper 모듈은 view 단에서 reqest 객체를 접근하게 할 수 있는 모듈이다.

이외에 다른 여러가지 기능도 제공한다.


7. 내장 모듈 util

shallow copy를 위해서 내장 모듈 util를 사용하였다.

ex) var something = extend(기존내용,추가할내용);




블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

모듈 path 관리 기법.

https://gist.github.com/branneman/8048520

http://dogfeet.github.io/articles/2012/nodejs-modules.html

참고..


수많은 기법중 재미있는 모듈을 발견해서 이 방법으로 쓰기로 결정했다.


requirefrom 이라는 모듈이다. 


사용방법은 다음과 같다.


Simple usage anywhere in your node app:

requirefrom moudle을 호출하고..

    var lib = require('requirefrom')('lib');
    var myModule = lib('myModule');

For more complex usage, let's assume this example directory structure:

node_modules/
lib/
  components/
    framework/
      veiws/
        login.js
        signup.js
      models/
        user/
          index.js
  utlity/
    normalize/
      user.js
package.json

Any file in this project could then include these files with the following code:

node.js 프로젝트 내의 어떤파일도 아래 파일을 통해 require 할 수 있다.

이 rquirefrom이라는 모듈은 server.js(app.js)에서 선언한 뒤 글로벌하게 쓰이는 모듈이 아니다.

아래와 같이 따로 js 파일을 생성한뒤 이를 다시 require 시키는 것으로 보인다.

var
    requireFrom = require('requirefrom')
  , views = requireFrom('lib/components/framework/views/')
  , models = requireFrom('lib/components/framework/models/')
  , utility = requireFrom('lib/utility/')
 
  , loginForm = views('login.js')
  , signupForm = views('signup.js')
 
  , userModel = models('user')
 
  , normalizeUser = utility('normalize/user.js')



2015.02.13 수정 


위 방법은 해당파일에서만 적용되고 global 하게 적용이 안된다.

따라서 app.js server.js 에 다음과 같이 global function을 적용하여 쓰는것이 좋겠다.


global.controllers = function(name) {

    return require(__dirname + '/controllers/' + name);

}

global.models = function(name) {

    return require(__dirname + '/models/' + name);

}

global.config = function(name) {

    return require(__dirname + '/config/' + name);

}


이렇게 global function을 적용하고 나면 global 하게 다른파일에서도 사용가능하다.

또한, 이렇게 하면 require(....)이라고 명시하게 되던 모듈설정을 controllers(....), models(....), config(....)로 나타나게 되어 

positive effect of knowing characteristic of module 을 지닌다. 


블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.


좋은 포스팅이 있어 공유한다.

http://nodeqa.com/nodejs_ref/65

블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

instance method는 document에 적용되는 method이며

static method는 model에 적용 되는 method이다.


일반적으로 instance method는 query로 찾은 document에 적용하는 method를 정의하기 위해 쓰고,

static method는 model을 통해 query를 하기위해 쓰인다. 


아래는 공식홈을 참조하였다.


'method' adds an instance method to documents constructed from Models

whereas 'static' adds static "class" methods to the Models itself

From the documentation:

Schema#method(method, [fn])

Adds an instance method to documents constructed from Models compiled from this schema.

var schema = kittySchema = new Schema(..);

schema.method('meow', function () {
  console.log('meeeeeoooooooooooow');
})


Schema#static(name, fn)

Adds static "class" methods to Models compiled from this schema.


var schema = new Schema(..);
schema.static('findByName', function (name, callback) {
  return this.find({ name: name }, callback);
});

'데이터베이스 > mongodb' 카테고리의 다른 글

mongoose static method vs instance method  (0) 2015.02.11
node.js mongoose에서의 virtual model  (0) 2015.02.10
mongodb에서의 join  (1) 2015.02.10
mongodb modeling  (0) 2015.02.09
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

http://git-scm.com/book/ko/v1 을 참고했다.


우선 git은 3가지 상태를 가진다. working directory,staging area,git directory 이다.

working directory에서 작업을 하다가 git add를 통해 staging area에 등록되고 git commit을 통해 repository에 등록된다.

이때 git add를 하지않은 즉 staging area에 없는 파일들은 commit을 해도 repository에 등록되지 않는다.

즉 untracked 상태이다. 


git 저장소를 만드는 명령어 : git init

git 저장소에 파일을 넣기 위한 명령어 : git add -> git commit 

현재 working directory 에 있는 모든 파일을 adding 하는 명령어 : git add .


아무것도 모르는 초보자들은 무슨 말인지 이해가 안될 수도 있다.

간단히 말해서 git init을 통해 지금 작업하고 있는 파일들을 저장할 폴더를 만들고 

git add 를 통해 저장할 파일들을 선별해 놓고 git commit을 통해 선별된 파일들을 저장할 폴더에 넣는다고 생각하면 되겠다.



working directory - 현재 작업중인 폴더. 이 폴더에서 git init 명령으로 git repository를 생성한다.

stage area - git add 명령어를 통해 staging된 구역. 나중에 commit할 자료의 모음이다.(git reset HEAD를 통해 다시 untrack상태로 복귀하게 할 수 있다.)

git directory - commit을 통해 최종적으로 git directory에 저장된다. 나중에 프로젝트를 다시 시작할 때에도 이 저장소(git repository로 부터 불러오게 된다.)




untracked - git add 하지 않은 파일들

unmodified - git add 하였으나 수정되지 않은 파일들.

modified - git add 하고 수정된 파일들.

staged - modified 된 파일들은 다시 staging(index)구역에 올려놓고 commit해야 한다.



cf.

커밋을 되돌리는 명령어 : $ git commit --amend

커밋을 했는데 Stage하는 것을 깜빡하고 빠트린 파일이 있으면 아래와 같이 고칠 수 있다:

$ git commit -m 'initial commit'
$ git add forgotten_file
$ git commit --amend

또 중요한 개념이 하나 있는데 이미 git add로 staging area에 올린 파일을 untracked 상태로 되돌릴 수 있다. 

이를 구현하는 명령어 : git reset head 파일명

이를 응용해서 일일이 파일을 넣지 않고 git add . 를 통해 모두 staging area에 올린 후에 git reset head로 불필요한 파일만 선택적으로 제거하면 되겠다.


다음 포스팅은 git branch에 대해 포스팅 하겠다.




'소프트웨어(tool) > git' 카테고리의 다른 글

git 간단한 사용법(1)  (0) 2015.02.10
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

mongoose 에서의 virtual model 에 대해서 알아보자.


virtual model 이란 collection에 정의 되지 않은 filed 이지만 정의된 field 처럼 사용할 수 있게 하는 기능이다. 


예를 들어

다음과 같이 스키마를 정의하고 모델을 만들어보자.


var personSchema = new
 Schema({
  name: {
    first: String,
    last: String
  }
});

// compile our model
var Person = mongoose.model('Person', personSchema);

// create a document
var bad = new Person({
    name: { first: 'Walter', last: 'White' }
});


그 모델에 따라 document를 만들게 된다. 

그렇다면 이 도큐먼트에서 참조할 수 있는 key는 schema를 정의할 때 정의한 key 밖에 없지만,

virtual을 이용하게 되면? virtual key를 이용해 schema에 포함되지 않을 키를 설정하고 구미에 맞게 function을 통해 다양한 활용이 가능하게 된다.


다음과 같이 virtual을 쓴다. 이렇게 virtual 메소드를 써서 새로운 키 name.full을 쓸 수 있게 된다. 


personSchema.virtual('name.full').get(function () {
  return this.name.first + ' ' + this.name.last;
});




Now, when we access our virtual "name.full" property, our getter function will be invoked and the value returned:


console.log('%s is insane', bad.name.full); // Walter White is insane


virtual 에는 setter 기능도 있는데, 다음과 같이 정의하면 된다.


bad.name.full = 'Breaking Bad';



Mongoose lets you do this as well through its virtual property setters:



personSchema.virtual('name.full').set(function (name) {
  var split = name.split(' ');
  this.name.first = split[0];
  this.name.last = split[1];
});

...

mad.name.full = 'Breaking Bad';
console.log(mad.name.first); // Breaking
console.log(mad.name.last);  // Bad

'데이터베이스 > mongodb' 카테고리의 다른 글

mongoose static method vs instance method  (0) 2015.02.11
node.js mongoose에서의 virtual model  (0) 2015.02.10
mongodb에서의 join  (1) 2015.02.10
mongodb modeling  (0) 2015.02.09
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

mongodb는 nosql이다. no sql이 아닌 not only sql 이다.

sql 처럼 테이블 조인을 할 수는 없지만 이와 비슷한 기능을 제공해 준다.


바로 collection간의 population이라는 기능이다. 


There are no joins in MongoDB but sometimes we still want references to documents in other collections. This is where population comes in.

Population is the process of automatically replacing the specified paths in the document with document(s) from other collection(s). We may populate a single document, multiple documents, plain object, multiple plain objects, or all objects returned from a query. Let's look at some examples.


var mongoose = require('mongoose')
  , Schema = mongoose.Schema
  
var personSchema = Schema({
  _id     : Number,
  name    : String,
  age     : Number,
  stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});

var storySchema = Schema({
  _creator : { type: Number, ref: 'Person' },
  title    : String,
  fans     : [{ type: Number, ref: 'Person' }]
});

var Story  = mongoose.model('Story', storySchema);
var Person = mongoose.model('Person', personSchema);




위와 같이 두개의 collection을 정의하여 놓는다.

psersonSchema는 stroySchema를 embedding하고 있다. 

즉 일대다 관계이다. storySchema도 역시 personSchema를 참조하고 있다. 

이 경우에 population을 구현해보자.

우선 새로운 document를 만들고 이를 save하면서 stroy document도 save한다. 



var aaron = new Person({ _id: 0, name: 'Aaron', age: 100 });

aaron.save(function (err) {
  if (err) return handleError(err);
  
  var story1 = new Story({
    title: "Once upon a timex.",
    _creator: aaron._id    // assign the _id from the person
  });
  
  story1.save(function (err) {
   
 if (err) return handleError(err);
    // thats it!
  });
})




그리고 다음과 같이 stroy collection에서 population을 구현할 수 있다.

_creator를 populating 함으로써 person객체를 받아와 객체안의 이름을 populating 하고 있는 것이다.



Story
.findOne({ title: 'Once upon a timex.' })
.populate('_creator')
.exec(function (err, story) {
  if (err) return handleError(err);
  console.log('The creator is %s', story._creator.name);
  // prints "The creator is Aaron"
})



'데이터베이스 > mongodb' 카테고리의 다른 글

mongoose static method vs instance method  (0) 2015.02.11
node.js mongoose에서의 virtual model  (0) 2015.02.10
mongodb에서의 join  (1) 2015.02.10
mongodb modeling  (0) 2015.02.09
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

지금 껏 나는 express의 본질인 connect middleware에 대해서 정확하게 이해하지 못하고 node.js를 사용해 온 것 같다.

미들웨어를 잘 설명하는 답변을 찾아 포스팅한다.

In most frameworks you get a request and you want to return a response. Because of the async nature of Node.js you run into problems with nested call backs if you are doing non trivial stuff. To keep this from happening Connect.js (Express.js is a layer on top of connect) has something that is called middleware which is a function with 2, 3 or 4 parameters.

대부분의 프레임워크에서는 request와 response가 있다. node.js의 비동기적인 특성 때문에 nested callback 문제에 부딪힐 수 있다(정확히 무슨말인지 이해가 안감)..

이를 위해서 Express는 미들웨어를 제공한다..

function (<err>, req, res, next) {}

Your Express.js app is a stack of these functions.

enter image description here

위의 그림이 명쾌하게 설명해주고 있다. request가 들어오면 built-in middleware가 실행되고(express는 네가지 미들웨어를 가진다. 

 

그 다음 router middleware가 실행된다. 이 시점에서 stack 에 있는 여러 routing function을 실행할 수 있다.  이렇게 한 스택에 있는 function을 사용하기 위해서 사용되는 메소드가 next()이다. 

The router is special, it's middleware that lets you execute one or more middleware for a certain url. So it's a stack inside a stack.

router는 특별하다. 그 것은 특정한 url에 들어온 요청을 한개이상의  middleware를 써서 실행하게 도와준다.  그렇기 때문에 stack안의 stack구조를 갖게된다.

So what does next do? Simple, it tells your app to run the next middleware. But what happens when you pass something to next? Express will abort the current stack and will run all the middleware that has 4 parameters.

그렇다면 next가 하는 역할은 무엇일까? 

expressjs 공식홈에 자세한 설명이 나와있다.


Middleware is a function with access to the request object (req), the response object (res), and the next middleware in line in the request-response cycle of an Express application, commonly denoted by a variable named next. Middleware can:

  • Execute any code.
  • Make changes to the request and the response objects.
  • End the request-response cycle.
  • Call the next middleware in the stack.

If the current middleware does not end the request-response cycle, it must call next() to pass control to the next middleware, otherwise the request will be left hanging.

하나의 미들웨어는 request object 와 response object에 접근하는 function이다. req-res 사이클에서 next 미들웨어에도 접근할 수 있다. 이렇게 한 스택안에 여러가지의 routing middleware가 있을 때 next middleware에 접근할 수 있는 function이 next()이다... 

그렇다면 응용 예를 하나 보겠다.

app.param() 메소드를 통한 응용인데 ...

app.param()은 공식홈에서 이렇게 가이드를 하고 있다.

Add callback triggers to route paramters, where name is the name of the parameter or an array of them, and function is the callback function. The parameters of the callback function are the request object, the response object, the next middleware, and the value of the parameter, in that order.

For example, when :user is present in a route path, you may map user loadig logic to automatically provide req.user to the route, or perform validations on the parameter input.

첫번째 인자에 parameter를 주는데 이 파라미터가 next를 통해 다음 미들웨어를 호출할때 index로 쓰인다. 무슨 말인고 하면, 아래와 같이 app.param('user' 라고 user 파라미터를 주었다면 next를 통해 다음 라우팅 미들웨어를 실행할 때 user파라미터를 가지는 middleware가 실행되는 것이다.

app.param('user', function(req, res, next, id) {

  // try to get the user details from the User model and attach it to the request object
  User.find(id, function(err, user) {
    if (err) {
      next(err);
    } else if (user) {
      req.user = user;
      next();
    } else {
      next(new Error('failed to load user'));
    }
  });
});


따라서 아래와 같이 응용을 할 수 있게 되는데,  param을 통해 load 미들웨어를 실행하고 id를 파라미터로 가지는 미들웨어를 next()를 통해 선택적으로 실행한다. 즉 id 파라미터를 가지는 url로 들어오는 모든 요청은 aritcles.load 미들웨어를 거쳐 실행된다. 


app.param('id', articles.load); app.get('/articles', articles.index); app.get('/articles/new', auth.requiresLogin, articles.new); app.post('/articles', auth.requiresLogin, articles.create); app.get('/articles/:id', articles.show); app.get('/articles/:id/edit', articleAuth, articles.edit); app.put('/articles/:id', articleAuth, articles.update); app.delete('/articles/:id', articleAuth, articles.destroy);






블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.

modeling in mongodb don't same to modeling in sql.

몽고db에서의 모델링은 sql의 모델링과 다르다. 

몽고 db에서의 모델링은 2가지 방법이 있다. 

Multiple-Collection방법과 Embedde 방법.

공식홈에서는 이렇게 가이드를 하고 있다.

1) 1:1 관계인 경우.

{
   _id: "joe",
   name: "Joe Bookreader"
}

{
   patron_id: "joe",
   street: "123 Fake Street",
   city: "Faketon",
   state: "MA",
   zip: "12345"
}

위와 같이 1:1 관계에 잇는 document의 경우 

{
   _id: "joe",
   name: "Joe Bookreader",
   address: {
              street: "123 Fake Street",
              city: "Faketon",
              state: "MA",
              zip: "12345"
            }
}

위와 같이 embedding하는 모델링을 쓸 경우 더욱 효율적인 쿼리를 할 수 있게 된다.

2) one to many case

일대다 관계인 경우에는 embedding 방식과 multiple collection 방식으로 나뉘게 된다. 

일대일 경우인 경우에는 embedding 했을때 embedding된 데이터가 동적으로 계속해서 늘어나지 않기 때문에 document의 사이즈를 걱정할 필요가 없다. 

하지만 one to may case의 경우에는 embedding 된 데이터의 크기가 계속해서 증가하게 될 경우. document의 사이즈 제한을 넘기는 경우 골치가 아픈일이 생기게 된다. 

mongodb 공식홈에서도 documents in MongoDB must be smaller than the maximumBSON document size

라고 설명하고 있다. collection안의 document는 Bson maximm보다 작아야 한다.

그렇다면 embedding방식의 데이터와 multiple collection을 어떻게 구분하여 써야 할까?

So, separate collections are good if you need to select individual documents, need more control over querying, or have huge documents.

Embedded documents are good when you want the entire document, the document with a $slice of comments, or with no comments at all.

seperate collection(multiple collection)은 

 1. query의 다양성

 2. 위에서 말했듯이 document 의 사이즈가 무척 클때.. 

embedded document는

 1. 성능 issue가 있을 때..(속도가 빠르다)

 2. slice를 통해 range 쿼리를 할 때 유용(paging 처리를 구현할때 유용)

일반적인 룰(general rule)은 

As a general rule, if you have a lot of "comments" or if they are large, a separate collection might be best.

Smaller and/or fewer documents tend to be a natural fit for embedding.

만약 많은 예)코멘트(댓글) 이나 dccument 사이즈 크기가 클 경우에는 seperate collection이 유리하고 그렇지 않은 경우에는  embedding이 유리하다.

현재 내가 제작하고 있는 사이트는 

1. 회원정보

2. 회원들의 글 

3. 회원들의 댓글 

크게 세가지 collection이 필요할 것으로 예상된다.

그런데 댓글의 경우 아무리 많은 양이 달려도 16mb 를 넘지 않을 것으로 에상되어 

3을 2에 embedding 시키고 두개의 collection으로 구현하려고 한다.

Don't freak out, The Complete Works of William Shakespeare is around 5.5MB

(세익스피어의 완본의 크기가 5.5mb 이니까 16mb 만큼의 댓글을 달지는 않겠지..)

'데이터베이스 > mongodb' 카테고리의 다른 글

mongoose static method vs instance method  (0) 2015.02.11
node.js mongoose에서의 virtual model  (0) 2015.02.10
mongodb에서의 join  (1) 2015.02.10
mongodb modeling  (0) 2015.02.09
블로그 이미지

종환 Revolutionist-JongHwan

github.com/alciakng 항상 겸손하자.