Returning XML in response from Loopback Remote Method

折月煮酒 提交于 2019-12-02 08:50:35

问题


I am using the Loopback Connector REST (1.9.0) and have a remote method that returns XML:

   Foo.remoteMethod
   (  
      "getXml",
      {
         accepts: [            
            {arg: 'id', type: 'string', required: true }
         ],
         http: {path: '/:id/content', "verb": 'get'},
         returns: {"type": "string", root:true},
         rest: {"after": setContentType("text/xml") }         
      }
   )

The response always returns an escaped JSON string:

"<foo xmlns=\"bar\"/>" 

instead of

<foo xmlns="bar"/>

Note that the response does have the content-type set to text/xml.

If I set my Accept: header to "text/xml", I always get "Not Acceptable" as a response.

If I set

"rest": {
  "normalizeHttpPath": false,
  "xml": true
}

In config.json, then I get a 500 error:

SyntaxError: Unexpected token <

I think that the "xml: true" property is simply causing a response parser to try to convert JSON into XML.

How can I get Loopback to return the XML in the response without parsing it? Is the problem that I am setting the return type to "string"? If so, what it the type that Loopback would recognize as XML?


回答1:


You need to set toXML in your response object (more on that in a bit). First, set the return type to 'object' as shown below:

Foo.remoteMethod
(  
  "getXml",
  {
     accepts: [            
        {arg: 'id', type: 'string', required: true }
     ],
     http: {path: '/:id/content', "verb": 'get'},
     returns: {"type": "object", root:true},
     rest: {"after": setContentType("text/xml") }         
  }
)

Next, you will need to return a JSON object with toXML as the only property. toXML should be a function that returns a string representation of your XML. If you set the Accept header to "text/xml" then the response should be XML. See below:

Foo.getXml = function(cb) {
  cb(null, {
    toXML: function() {
      return '<something></something>';
    }
  });
};

You still need to enable XML in config.json because it's disabled by default:

"remoting": {
  "rest": {
    "normalizeHttpPath": false,
    "xml": true
  }
}

See https://github.com/strongloop/strong-remoting/blob/4b74a612d3c969d15e3dcc4a6d978aa0514cd9e6/lib/http-context.js#L393 for more info on how this works under the hood.




回答2:


I recently ran into this with trying to create a dynamic response for Twilio voice calling in Loopback 3.x. In the model.remoteMethod call, explicitly specify the return type and content type as follows:

model.remoteMethod(
    "voiceResponse", {
        accepts: [{
            arg: 'envelopeId',
            type: 'number',
            required: true
        }],
        http: {
            path: '/speak/:envelopeId',
            "verb": 'post'
        },
        returns: [{
            arg: 'body',
            type: 'file',
            root: true
        }, {
            arg: 'Content-Type',
            type: 'string',
            http: {
                target: 'header'
            }
        }],

    }
)

Have your method return both the xml and the content type via the callback function. Note that the first argument in the callback is to return an error if one exists:

model.voiceResponse = function(messageEnvelopeId, callback) {

    app.models.messageEnvelope.findById(messageEnvelopeId, {
        include: ['messages']
    }).then(function(res) {
        let voiceResponse = new VoiceResponse();
        voiceResponse.say({
                voice: 'woman',
                language: 'en'
            },
            "This is a notification alert from your grow system. " + res.toJSON().messages.message
        )

        callback(null,
            voiceResponse.toString(), // returns xml document as a string
            'text/xml'
        );
    });
}


来源:https://stackoverflow.com/questions/31171438/returning-xml-in-response-from-loopback-remote-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!