2017-02-23 146 views
0

我試圖從節點+ express服務器向Arangodb上的我的Foxx服務發送post請求。發送來自節點的HTTP Post請求到Foxx服務(ArangoDB)

在節點方面:

var route = arangopi + '/edge/' + col.name ; 
var body = {data: data, from: fromId, to: toId} ; 
console.log('|| body :', route, body) ; 

>> || body : http//XXX/_db/my-DB/my-foxx-service/path/to/visitedBy { data: { isBackup: true, text: '', isHint: true, continuance: 3441.5 }, from: 'Drop/27237133', to: 'Bot/41116378' } 

return requestify.post (route, body) 

在福克斯的一面,我收到了請求,但日誌告訴我,它沒有身體:

router.post('/path/to/:param', function (req, res) { 
    console.log ('|| body :', req.body) 
    var data = req.body ; 
    var result = api.DoSomething (req.stateParams.param, data) 
    res.send(result) 
}) 
.response(joi.object().required(), 'Entry stored in the collection.') 
.summary('Summary') 
.description('Description') 

>> || body : [Object { "binarySlice" : function binarySlice() { [native code] }, "asciiSlice" : function asciiSlice() { [native code] }, "base64Slice" : function base64Slice() { [native code] }, "ucs2Slice" : function ucs2Slice() { [native code] }, "hexSlice" : f... 

在節點方面我也試過'請求'模塊。

return request.post(route, {form:body}, function (error, response, body) { 
    console.log('error:', error); 
    console.log('statusCode:', response && response.statusCode); 
    console.log('body:', body); 
    return response ; 
}); 

而且我從Foxx那裏得到相同的日誌。

我該怎麼做?

下面是我在Foxx界面上的操作截圖。我無法指定請求主體進行測試是否正常?

enter image description here

+0

你從Node.js的側試過這樣:'回報requestify.post(路線,JSON.stringify(體));' –

+0

@DavidThomas謝謝,我試過,但它沒有工作 – user6403833

+0

在福克斯方面,你如何在req.body上嘗試使用JSON.stringify或JSON.parse。你也可以嘗試[request](https://github.com/request/request)模塊,我用它從node.js調用Foxx服務,並沒有任何問題,運行良好。 –

回答

3

我想原因是因爲你沒有在福克斯終點規定,有預期的。員額的部分身體。

我花了一段時間才弄出一個定義Foxx MicroServices的方法,並在解決某個模式之前,通讀了大量的ArangoDB示例代碼。

爲了幫助您入門,我已經提供瞭如何以可擴展的方式快速模擬Foxx MicroService代碼,使您能夠將模型與路線分開。

以這些爲例來讓你的例子工作。

我已經假設有兩個文檔集合'Drop'和'Bot',邊集合將它們連接起來稱爲'VisitedBy'。

所有這些文件都存儲在您的福克斯的microService:

main.js

'use strict'; 
module.context.use('/v1/visitedBy', require('./routes/visitedBy'), 'visitedBy'); 

routes/visitedBy.js

'use strict'; 
const request = require('@arangodb/request'); 
const joi = require('joi'); 
const createRouter = require('@arangodb/foxx/router'); 
const VisitedBy = require('../models/visitedBy'); 

const visitedDataSchema = joi.object().required().description('Data that tracks a visited event'); 

const router = createRouter(); 
module.exports = router; 


/********************************************* 
* saveVisitedBy 
* Path Params: 
* none 
* Query Params: 
* none 
* Body Params: 
* body   (required) The data that is used to record when something is visited 
*/ 
router.post('/', function (req, res) { 
    const visitedData = req.body; 
    const savedData = VisitedBy.saveVisitedByData(VisitedBy.fromClient(visitedData)); 
    if (savedData) { 
    res.status(200).send(VisitedBy.forClient(savedData)); 
    } else { 
    res.status(500).send('Data not saved, internal error'); 
    } 
}, 'saveVisitedBy') 
    .body(visitedDataSchema, 'visited data') 
    .response(VisitedBy.savedDataSchema, 'The response after the data is saved') 
    .summary('Save visited data') 
    .description('Save visited data'); 

models/visitedBy.js

'use strict'; 
const _ = require('lodash'); 
const joi = require('joi'); 
const db = require('@arangodb').db; 
const visitedByEdgeCollection = 'VisitedBy'; 

/* 
Schema for a response after saving visitedBy data 
*/ 
const savedDataScema = { 
    id: joi.string(), 
    data: joi.object(), 
    _from: joi.string(), 
    _to: joi.string() 
}; 

module.exports = { 
    savedDataSchema: savedDataScema, 

    forClient(obj) { 
    // Implement outgoing transformations here 
    // Remove keys on the base object that do not need to go through to the client 
    if (obj) { 
     obj = _.omit(obj, ['_id', '_rev', '_oldRev', '_key']); 
    } 

    return obj; 
    }, 

    fromClient(obj) { 
    // Implement incoming transformations here 
    return obj; 
    }, 

    saveVisitedByData(visitedData) { 
    const q = db._createStatement({ 
     "query": ` 
      INSERT { 
       _from: @from, 
       _to: @to, 
       data: @data, 
       date: DATE_NOW() 
      } IN @@col 
      RETURN MERGE ({ id: NEW._id }, NEW) 
     ` 
    }); 
    q.bind('@col', visitedByEdgeCollection); 
    q.bind('from', visitedData.from); 
    q.bind('to', visitedData.to); 
    q.bind('data', visitedData.data); 

    const res = q.execute().toArray(); 

    return res[0]; 
    } 
}; 

您的服務應該是這樣的揚鞭接口: Swagger view of service

您可以瞭解更多有關使用淳佳來定義數據結構here

它需要一些習慣joi,但一旦你得到了一些很好的工作示例,你可以定義傳入和傳出數據的很好的數據定義。

我希望這會有所幫助,我很難獲得一個基本的MicroService代碼模型,它明確瞭如何操作,我相信在這個例子中可以做很多事情,但它應該是一個很好的起點。

+0

謝謝大衛,它爲我工作! – user6403833

+0

很高興你可以得到它,與福克斯祝你好運! –

0

正如David Thomas在他的回答中解釋的那樣,我需要在我的路由器代碼(Foxx端)中指定一個主體格式。

簡而言之:

const bodySchema = joi.object().required().description('Data Format'); 

router.post('/path/to/:param', function (req, res) { 
    var data = req.body ; 
    var result = api.DoSomething (req.stateParams.param, data) 
    res.send(result) 
}) 
.body(bodySchema, 'Body data') 
.response(joi.object().required(), 'Entry stored in the collection.') 
.summary('Summary') 
.description('Description')