2013년 5월 19일 일요일

Meteor에서 REST API를 사용하는 방법 #2

server쪽 API를 router package를 사용해 쓰다보면 header 같은 걸 다루거나 할땐 너무 단순하게 만들어서 곤란할 수 있다.
이전에도 다룬 적(http://spectrumdig.blogspot.kr/2012/08/meteor-rest.html)이 있지만 __meteor_bootstrap__ 객체를 통해 접근하면 node.js 식의 접근이 가능하다.

Meteor update와 함께 Npm 객체가 생겼으니 이를 이용해 connect 객체를 사용해보자
http://www.slideshare.net/cjoudrey/building-your-first-node-app-with-connect-express
위 슬라이드를 한번 보면 이해에 도움이 될 것이다.

WebApp.connectHandlers 가 connect.createServer()라는 걸 기억하면 된다.



connect = Npm.require 'connect'
server = WebApp.connectHandlers
server.use connect.router (app)->
app.get '/info', (req,res)->
res.end "info"
app.get '/user/:id', (req,res)->
res.end "user id: #{req.params.id}"

이와 같은 코드를 server 디렉토리에 안에 넣거나 Meteor.isServer일때 실행하도록 하자.
파일 업로드나 쿼리 문자열 처리(ex: ?a=1&b=c)하려면
각각 bodyParser(http://www.senchalabs.org/connect/bodyParser.html) 와 query(http://www.senchalabs.org/connect/query.html)를 추가하는 것이 좋다.
위의 해당 링크에 보면 소스까지 공개 해놓아서 이해하기 쉬우니 필요한게 있으면 추가해보자. (가령 logger라든지...)



connect = Npm.require 'connect'
server = WebApp.connectHandlers
server.use connect.bodyParser()
server.use connect.query()
server.use connect.router (app)->
app.get '/info', (req,res)->
res.end "info"
app.get '/user/:id', (req,res)->
res.end "user id: #{req.params.id}"
app.post '/user', (req, res)->
res.end "user name: #{req.body.user.name}"
app.get '/search', (req,res)->
res.end "search : #{req.query.q}"



$ curl -d '{"user":{"name":"tj"}}' -H "Content-Typeon" http://localhost:3000/user
user name: tj


$ curl http://localhost:3000/search?q=something
search : something

위 두개의 curl 명령은 각각 bodyParser와 query모듈이 없으면 오류를 발생한다. body와 query 객체가 request 객체 안에 없으니까.

Npm이 그랬던 것 처럼 __meteor_bootstrap__.app 도 세련되게 포장해야하지 않나 싶은데 그건 또 그때 일 :)


* Updatehttps://github.com/tmeasday/meteor-router/blob/master/lib/router_server.js 소스를 보니 기존의 __meteor_bootstrap__.app 이 WebApp.connectHandlers 로 바뀌었다.
만일 패키지를 만들었고 그것이 이전 버전과 하위 호환을 유지하고 싶다면 require와 connect.createServer에 대해

@require = if Npm? then Npm.require else __meteor_bootstrap__.require
@server = if WebApp?.connectHandlers? then WebApp.connectHandlers else __meteor_bootstrap__.app

과 같이 정의해서 쓰는 것도 좋겠다.