2017-03-01 5 views
0

最初のHAPI APIバックエンドを構築し、何か奇妙なものに遭遇しました。 (GET/api/item/{name}でエンドポイントに到達すると、コンソールでハンドラ関数が実行されていることがわかります。(mongoクエリ)、応答が送信されます(応答プラグインがあります)私は、別のパラメータでエンドポイントに再度ヒットした場合、最初のコールからの応答がすぐに出て、ハンドラ関数がヒットしていることがわかります。そして、実際には、クライアントは同じものを取得しています最初の呼び出しからのような応答後続のコールでハンドラの前にHAPI応答が送信されています

そして、私はここまで投稿する最も参考になるのかさえわからない

ここで(環境とウィンストンのための設定を欠落している)エントリポイントのjsの中で最もです:。。

const Hapi = require('hapi'); 
server = new Hapi.Server(); 

var mongo_connect = 'mongodb://' + options.mongo_creds + options.mongo_host + ':' + options.mongo_port + '/' + options.mongo_db; 
const dbOpts = { 
    url: mongo_connect, 
    settings: { 
     poolSize: options.mongo_pool 
    }, 
    decorate: true 
}; 

server.connection({ port: options.server_port }); 

var routes = require('./routes'); 

if (options.env === "dev") { 
    server.on('response', function (request) { 
     winston.log('verbose', `[launch_api] ${request.info.remoteAddress}: ${request.method.toUpperCase()} ${request.url.path} --> ${request.response.statusCode}`); 
    }); 
} 

server.register({ 
    register: require('hapi-mongodb'), 
    options: dbOpts 
}, function(err) { 
    if (err) { 
     winston.log('error', "[launch_api] Unable to register db pool"); 
     throw err; 
    } 

    server.route(routes); 

    server.start(function(err) { 

     if (err) { 
      throw err; 
     } 
     winston.log('info', `[launch_api] Server running at: ${server.info.port}`); 
    }); 
}); 

ルートは、ルートフォルダ内のindex.jsで一緒に引っ張られますが、各ファイルがようになりますされています。すべてはちょうどこのことから、簡潔にするために検索機能を示す(このような何かを見て

'use strict'; 
var controller = require('../controllers/item-controller') 

// Routes for Item 

module.exports = [ 
    { 
     method: 'POST', 
     path: '/api/item', 
     config: controller.create 
    }, 
    { 
     method: 'GET', 
     path: '/api/items', 
     config: controller.fetchAll 
    }, 
    { 
     method: 'GET', 
     path: '/api/item/{name}', 
     config: controller.find 
    } 
]; 

コントローラ)すでに

const Boom = require('boom'); 
const Joi = require('joi'); 
const Item = require('../models/item'); 

module.exports = { 
    find: { 
     handler: function(request, reply) { 
      Item.initFromName(request.params.name).then(function(newItem) { 
       if (newItem == null) { 
        reply(Boom.notFound()); 
       } 
       else { 
        reply(newItem); 
       } 
      }, function(err) { 
       reply(Boom.badImplementation()); 
      }); 
     } 
    } 
} 

長いです最後に、モデルは、えー、モデルをこのに従う傾向がある(再び、すべてのプロトタイプの拡張機能を切り出し、そしてちょうどこのルートでは1つのクラスの機能を維持する)

const deferred = require('deferred')() 
const winston = require('winston'); 

const collection_name = "items"; 


var Item = function() { 
    this.name = ""; 
    this.description = ""; 
}; 

// private 

function fillFromDB(obj, record) { 
    obj._id = record._id; 
    obj.name = record.name; 
    obj.description = record.description; 
} 

// Constructor 
module.exports.init = function() { 
    return new Item(); 
}; 

module.exports.initFromName = function(name) { 
    var item = new Item(); 
    const db = server.mongo.db; 
    db.collection(collection_name).findOne({name: name}).then(function(opResult) { 
      winston.log("debug","Item.loadFromName opResult is: " + opResult); 
     if (opResult != undefined) { 
      winston.log("debug","Item.loadFromName opResult json is: " + JSON.stringify(opResult)); 
      fillFromDB(item, opResult); 
      deferred.resolve(item); 
     } 
     else { 
      winston.log("debug","Resolving with null"); 
      deferred.resolve(); 
     } 
    }, function(err) { 
     winston.log("error", "Item.loadFromName mongo error: " + err); 
     deferred.reject(); 
    }); 
    return deferred.promise; 
}; 

だから、ではない名前のカールでエンドポイントに当たった場合、コレクションにはがありますが、期待通りの結果が得られます。私は、ある名前でヒットした場合、私はまだ404

この入力を取得:

$ curl -X GET http://192.168.99.100:3000/api/item/not_here 
{"statusCode":404,"error":"Not Found"} 
$ curl -X GET http://192.168.99.100:3000/api/item/here 
{"statusCode":404,"error":"Not Found"} 

は、このログを生成します。

debug: Item.loadFromName opResult is: null 
debug: Resolving with null 
verbose: [launch_api] 192.168.99.1: GET /api/item/not_here --> 404 
verbose: [launch_api] 192.168.99.1: GET /api/item/here --> 404 
debug: Item.loadFromName opResult is: [object Object] 
debug: Item.loadFromName opResult json is: {"_id":"58b622908ea4d1cee2f46462","name":"here","description":"this item is here"} 

注意を反対方向に動作することを、あまりにも。ノードを停止して開始し、存在する名前でエンドポイントにヒットした場合、後続のすべての呼び出しで同じオブジェクトが返されます。私はこのキャッシングがどこで起こっているのか分かりません。

+0

あなたの質問を要約すると、hapiは応答をキャッシュしているようですか? –

+0

ええ、私はちょうどそれを言ったはずでしたか? tl; dr :)しかし、私はキャッシングを有効にするために何もしていないし、スキャンしていたcatbox tutsの1つで、明示的に有効にしなければならないと思った。 – gbryant

+0

item変数はinitFromName関数のどこから来ますか?それは問題を引き起こしているかもしれません。また、defferedライブラリは何ですか?返信インタフェースを使用するときは、約束が正しくラップされる必要があります。 –

答えて

0

問題は、遅延オブジェクトのグローバルなインスタンス化でした。私がそれを見た場所はわかりませんが、それは悪い考えです。モデルで

は、機能であり、あなたの繰延オブジェクトを作成し、ちょうどその

const deferred = require('deferred'); 

必要とする最初の行を変更します。

module.exports.initFromName = function(name) { 
    const defer = deferred(); 
    var item = new Item(); 
    const db = server.mongo.db; 
    db.collection(collection_name).findOne({name: name}).then(function(opResult) { 
      winston.log("debug","Item.loadFromName opResult is: " + opResult); 
     if (opResult != undefined) { 
      winston.log("debug","Item.loadFromName opResult json is: " + JSON.stringify(opResult)); 
      fillFromDB(item, opResult); 
      defer.resolve(item); 
     } 
     else { 
      winston.log("debug","Resolving with null"); 
      defer.resolve(); 
     } 
    }, function(err) { 
     winston.log("error", "Item.loadFromName mongo error: " + err); 
     defer.reject(); 
    }); 
    return defer.promise; 
}; 
関連する問題