Отправка HTTP-запроса Post с узла на сервис Foxx (ArangoDB)
Я пытаюсь отправить почтовый запрос с узла + экспресс-сервера в сервис 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)
Со стороны Foxx я получаю запрос, но в журналах говорится, что у него нет тела:
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. Это нормально, что я не могу указать тело запроса для тестирования?
2 ответа
Я думаю, что причина в том, что вы не указали в конечной точке Foxx, что в качестве элемента.post ожидается тело.
Мне потребовалось некоторое время, чтобы выработать способ определения Foxx MicroServices, и я прочитал несколько примеров кода ArangoDB, прежде чем остановился на шаблоне.
Чтобы помочь вам начать, я представил, как быстро смоделировать код Foxx MicroService таким образом, чтобы он был расширяемым, позволяя вам отделить ваши маршруты от ваших моделей.
Используйте их в качестве примеров, чтобы ваш пример работал.
Я сделал предположение, что есть две коллекции документов, 'Drop' и 'Bot' с коллекцией ребер, которая присоединяется к ним, и называется 'VisitedBy'.
Все эти файлы хранятся на вашем Foxx 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:
Вы можете узнать больше об использовании joi для определения структур данных здесь.
Требуется немного привыкнуть к joi, но как только вы получите несколько хороших рабочих примеров, вы сможете определить отличные определения данных для входящих и исходящих данных.
Надеюсь, это поможет, мне было трудно получить базовую модель кода MicroService, которая давала понять, как все работает, я уверен, что многое можно сделать для этого примера, но это должно стать хорошей отправной точкой.
Как объяснил Дэвид Томас в своем ответе, мне нужно было указать формат тела в моем коде маршрутизатора (сторона 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')