2016-06-11 3 views
2

REST API를보다 쉽게 ​​사용할 수 있도록 첫 번째 node.js 패키지를 작성 중이며 패키지를 사용하는 사람이 다음을 수행 할 수 있도록 패키지를 포맷하는 데 문제가 있습니다. 그들의 응용 프로그램. 나의 현재 설정에서NPM 패키지 설치를 작성하는 방법

var Water= require("water-reservation"); 

var water = Water({username: myusername, password: mypassword}); 

// Problem here because Water({}) needs to do a REST call to get a bearer 
// token to use the API I am trying to simplify. Thus, it tries to 
// get_water(callabck) before the bearer_token var is set in my package. 

water.get_water(function(err, result){ 
    if(err){ 
     console.log(err); 
     console.log("----------------------------------------------"); 
    } 
    else{ 
     console.log(result); 
     console.log("----------------------------------------------"); 
    } 
}); 

나는 내 REST 패키지에 대한 호출을 모두 사용 무기명 토큰을 얻을 수있는 사용자의 사용자 이름과 암호를 가지고 가고 REST 엔드 포인트에 전달합니다. 비동기 특성은 내 패키지에서 bearer_token 변수를 설정하기 전에 사용자 파일에서 get_water를 호출합니다. 내가 전술 한 바와 같이 사용자가 패키지를 사용할 수 있도록 설정을 할 수있는 방법을 찾기 위해 노력하고

var request = require('request'); 
var bearer_token = ""; 
var api_url = ""; 

var Water = function(credentials){ 
    api_url = credentials.api_url; 
    var username = credentials.username; 
    var password = credentials.password; 

    get_bearer_token(username, password, function(err, access_token){ 
     bearer_token = access_token; 
    }); 
}; 

function get_bearer_token(username, password, callback){ 
    var request_options = { 
     url: api_url + "/auth", 
     method: "GET", 
     'auth': { 
      'user': username, 
      'pass': password 
     } 
    }; 

    request(request_options, function(err, res, body){ 
     if(err) { 
      return callback("Water Initialization Error: " + err, null); 
     } 
     else { 
      return callback(null, body); 
     } 
    }); 
} 

// Get water 
Water.prototype.get_water = function(callback) { 
    var request_options = { 
     url: api_url + "/water", 
     method: "GET", 
     'auth': { 
      'bearer': bearer_token 
     } 
    }; 

    request(request_options, function(err, res, body){ 
     if(err) { 
      return callback(err, null); 
     } 
     else{ 
      return callback(null, body); 
     } 
    }); 
}; 

// more package functions... 

module.exports = Water; 

: 여기

처럼 내 패키지 모습입니다. 나는 그 스타일을 설정하지는 않지만 사용자가 이해하고 사용하는 것이 가장 쉬운 것 같다.

이 문제를 해결할 수있는 유일한 방법은 콜백을 Water ({})에 추가하는 것이지만 사용자가 콜백에 관련된 모든 물 관련 코드를 래핑하도록하는 것은 엉망이됩니다. 예를 들어 Twitter 패키지를 보면이 작업을 수행 할 수 있다는 것을 알고 있지만 어떻게 처리했는지 계속 감안할 수 있습니다. 어떤 도움을 주시면 감사하겠습니다.

+0

은'노드 twitter' 패키지는 어떤을하지 않는 것 : 그것을 사용하려면

var request = require('request'); var Water = function (credentials) { this.api_url = credentials.api_url; this.username = credentials.username; this.password = credentials.password; return this; }; Water.prototype.get_bearer_token = function (callback) { // We already have the bearer token, so return straight away if (this.bearer_token) return callback(null, this.bearer_token); var self = this; var request_options = { url: this.api_url + "/auth", method: "GET", 'auth': { 'user': this.username, 'pass': this.password } }; request(request_options, function(err, res, body){ if(err) { return callback("Water Initialization Error: " + err, null); } else { self.bearer_token = body; return callback(null, body); } }); } // Get water Water.prototype.get_water = function(callback) { var self = this; this.get_bearer_token(function (err, token) { if (err) return callback(err); var request_options = { url: self.api_url + "/water", method: "GET", 'auth': { 'bearer': token } }; request(request_options, function(err, res, body){ if(err) { return callback(err, null); } else{ return callback(null, body); } }); }); }; // more package functions.. module.exports = Water; 

을 프로토 타입 함수에서 비동기 요청. – gnerkus

+1

아마 내가 사용자가 자신의 무기명 토큰을 제공하고 설치에서 휴식 요청을하지 말았어야합니다. , 나는 그들이 패키지를 사용하기 쉽게하기 위해 토큰을 얻음으로써 도움이되기를 원할 것이다. –

답변

1

요청할 때 토큰을받는 책임을 위임해야합니다. 그렇게하면 패키지가 즉시 초기화됩니다. 더 효율적으로 만들려면 토큰을 처음 가져올 때 캐시 할 수 있습니다. 여기 예를했습니다,하지만 당신은 비동기 같은 것을 사용하여 정돈 수 :

var Water = require('water-reservation'); 

var water = new Water({ 
    username: 'username', 
    password: 'pass', 
    api_url: 'http://example.com' 
}); 

water.get_water(function (err, res) { 

}); 
+0

멋진 솔루션과 예제 덕분에! 그래서이 패키지로 만든 모든 함수에 대해 토큰'this.get_bearer_token (function (err, token) {};)을 얻는 콜백을 포함해야합니다. 모든 메소드에서 같은 콜백을 반복하지 않도록하는 방법이 있는지 궁금합니다. 가독성을 높이고 중복성을 줄입니다. –

+0

중첩 콜백을 피하려면 async waterfall (또는 promises)을 사용하여 병합을 병합 할 수 있습니다. 그러나, 그것이 단지 무기명 토큰을 얻고 나서 요청을하면, 나는 아마 괴롭히지 않을 것입니다. – MrWillihog