从节点向 Foxx 服务 (ArangoDB) 发送 HTTP Post 请求 [英] Sending HTTP Post request from node to Foxx service (ArangoDB)

查看:21
本文介绍了从节点向 Foxx 服务 (ArangoDB) 发送 HTTP Post 请求的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从节点 + 快递服务器向我在 Arangodb 上的 Foxx 服务发送发布请求.

I am trying to send a post request from a node + express server to my Foxx service on 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 端,我收到了请求,但日志告诉我它没有正文:

On the Foxx side, I receive the request but the logs tell me it has no 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...

在节点方面,我也尝试了请求"模块.

On the node side I also tried the 'request' module.

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 那里得到了同样的日志.

And I get the same logs from Foxx.

我做错了什么?

这是我在Foxx界面上的操作截图.无法指定测试请求正文是否正常?

Here is a screenshot of my operation on the Foxx interface. Is it normal that I cannot specify a request body for testing ?

推荐答案

我认为原因是因为您没有在 Foxx 的结束点指定预期作为 .post 一部分的正文.

I think the reason is because you haven't specified in the end point in Foxx that there is a body expected as part of the .post.

我花了一段时间才找到定义 Foxx 微服务的方法,在确定模式之前,我阅读了大量 ArangoDB 示例代码.

It took me a while to work out a way of defining Foxx MicroServices, and I read through a number of ArangoDB example code before I settled on a pattern.

为了帮助您入门,我提供了如何以可扩展的方式快速模拟 Foxx 微服务代码,从而允许您将路由与模型分开.

To help you get started, I've provided how I would quickly mock up the Foxx MicroService code in a way that is extensible, allowing you to separate your Routes from your Models.

使用这些作为例子来让你的例子工作.

Use these as examples to get your example working.

我已经假设有两个文档集合,Drop"和Bot",其中一个边缘集合将它们连接起来,称为VisitedBy".

I've made assumptions that there are two document collections, 'Drop' and 'Bot' with an edge collection that joins them called 'VisitedBy'.

所有这些文件都存储在您的 Foxx 微服务上:

All these files are stored on your 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 界面中应如下所示:

Your service should look like this in the Swagger interface:

您可以在此处了解有关使用 joi 定义数据结构的更多信息.

习惯 joi 需要一点时间,但是一旦您获得一些好的工作示例,您就可以为传入和传出数据定义出色的数据定义.

It takes a bit getting used to joi, but once you get some good working examples you can define great data definitions for incoming and outgoing data.

我希望这会有所帮助,我很难得到一个基本的微服务代码模型来清楚地说明事情是如何运作的,我相信这个例子可以做很多事情,但它应该是一个很好的起点.

I hope this helps, it was difficult for me getting a basic MicroService code model that made it clear how things operated, I'm sure a lot can be done for this example but it should be a good starting spot.

这篇关于从节点向 Foxx 服务 (ArangoDB) 发送 HTTP Post 请求的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆