2017-02-23 4 views
0

Ich versuche, eine Post-Anfrage von einem Knoten + Express-Server zu meinem Foxx-Dienst auf Arangodb zu senden.Senden HTTP-Post-Anfrage von Knoten zu Foxx-Dienst (ArangoDB)

Auf der Knotenseite:

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) 

Auf der Seite Foxx, erhalte ich die Anfrage, aber die Protokolle sagen Sie mir, es hat keinen Körper:

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... 

Auf der Knotenseite Ich habe auch versucht die "Anfrage" Modul.

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 ; 
}); 

Und ich bekomme die gleichen Protokolle von Foxx.

Was mache ich falsch?

Hier ist ein Screenshot meiner Operation auf der Foxx-Schnittstelle. Ist es normal, dass ich einen Anfragetext zum Testen nicht angeben kann?

enter image description here

+0

Haben Sie schon versucht, diese von der node.js Seite: 'return requestify.post (Route, JSON.stringify (Körper));' –

+0

@DavidThomas Dank ich das versucht, aber es hat nicht funktioniert – user6403833

+0

Wie wäre es auf der Foxx-Seite, versuchen Sie JSON.stringify oder JSON.parse auf dem req.body. Sie könnten auch das [request] (https://github.com/request/request) -Modul versuchen, ich benutze es, um Foxx-Dienste von node.js aufzurufen und hatte keine Probleme, läuft gut. –

Antwort

3

Ich denke, der Grund ist, weil Sie nicht in dem Endpunkt in Foxx angegeben haben, dass es ein Körper als Teil des .post erwarten ist.

Es hat eine Weile gedauert, bis ich einen Weg gefunden hatte, Foxx MicroServices zu definieren, und ich las eine Reihe von ArangoDB-Beispielcodes, bevor ich mich auf ein Muster festlegte.

Um Ihnen den Einstieg zu erleichtern, habe ich Ihnen vorgestellt, wie ich schnell den Foxx MicroService-Code auf eine erweiterbare Weise nachbearbeiten kann, damit Sie Ihre Routen von Ihren Modellen trennen können.

Verwenden Sie diese Beispiele, um Ihr Beispiel zum Laufen zu bringen.

Ich habe Annahmen gemacht, dass es zwei Dokumentensammlungen gibt, 'Drop' und 'Bot' mit einer Kantensammlung, die sie verbindet, 'VisitedBy' genannt.

Alle diese Dateien sind auf Ihrem Foxx Micro gespeichert:

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]; 
    } 
}; 

Ihr Dienst sollte in der Swagger-Schnittstelle wie folgt aussehen: Swagger view of service

Sie können erfahren Sie mehr über joi mit here Datenstrukturen zu definieren.

Es ist ein bisschen gewöhnungsbedürftig, aber sobald Sie ein paar gute Arbeitsbeispiele bekommen, können Sie großartige Datendefinitionen für eingehende und ausgehende Daten definieren.

Ich hoffe, das hilft, es war schwierig für mich, ein grundlegendes MicroService-Code-Modell zu bekommen, das klar machte, wie die Dinge funktionierten, ich bin sicher, dass für dieses Beispiel eine Menge getan werden kann, aber es sollte ein guter Startpunkt sein.

+0

Danke David, es hat für mich geklappt! – user6403833

+0

Froh, dass du es mitmachen kannst, viel Glück mit Foxx! –

0

Wie David Thomas in seiner Antwort erklärte, musste ich in meinem Router-Code (Foxx-Seite) ein Body-Format angeben.

Kurz:

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')