首页 > 解决方案 > 如何从 AWS lambda 调用基于 XML 的外部 rest API?

问题描述

我正在尝试从 AWS lambda 调用外部 API。我没有使用 node.js http 模块,因为我听说它很麻烦。所以我正在尝试使用 AWS 开发工具包来完成任务。请参阅https://boylesoftware.com/blog/calling-restful-apis-from-inline-aws-lambda-functions/。这段代码似乎大部分都可以工作,但我不确定,因为 API 应该返回和 XML 有效负载,但它没有。不会引发错误,但会在变量{}中返回一个空对象。data

我猜这与我注释掉的输出规范有关。我不太了解 SDK,不知道如何描述 XML 有效负载。我尝试将其切换为字符串无济于事。

当我通过 Postman 调用它时,我能够成功地从这个 API 接收 XML 有效负载。来自 API 的示例响应包含在我的 lambda 代码下方。

'use strict';

// load AWS SDK module, which is always included in the runtime environment
const AWS = require('aws-sdk');
const UTA = {
  token: process.env.uta_api_token
};

// define our target API as a "service"
const svc = new AWS.Service({

    // the API base URL
    endpoint: 'http://api.rideuta.com/SIRI/SIRI.svc',

    // don't parse API responses
    // (this is optional if you want to define shapes of all your endpoint responses)
    convertResponseTypes: false,

    // and now, our API endpoints
    apiConfig: {
        metadata: {
            protocol: 'rest-xml' // API returns XML
        },
        operations: {

            // GetStop stuff
            GetStop: {
                http: {
                    method: 'GET',
                    // note the placeholder in the URI
                    requestUri: 'StopMonitor'
                },
                input: {
                    type: 'structure',
                    required: [ 'auth', 'stopid', 'minutesout' ],
                    members: {
                        'auth': {
                            // send authentication header in the HTTP request header
                            location: 'uri',
                            locationName: 'usertoken',
                            sensitive: true
                        },
                        'stopid': {
                            // all kinds of validators are available
                            type: 'string',
                            // include it in the call URI
                            location: 'uri',
                            // this is the name of the placeholder in the URI
                            locationName: 'stopid'
                        },
                        'minutesout' : {
                            type : 'integer',
                            location : 'uri',
                            locationName : 'minutesout'
                        }
                    }
                },
                /*
                output: {
                    type: 'structure',
                    members:  {
                        'ResponseTimestamp' : {
                            location : 'body',
                            locationName : 'ResponseTimestamp'
                        }
                    }
                }
                */
            }
        }
    }
});

// disable AWS region related login in the SDK
svc.isGlobalEndpoint = true;

// and now we can call our target API!
exports.handler = function(event, context, callback) {

    // note how the methods on our service are defined after the operations
   //ontext.succeed('hello world');
    svc.getStop({
            auth: UTA.token,
            stopid: 'FR301084',
            minutesout : 600,
        }, (err, data) => {

            if (err) {
                console.error('>>> operation error:', err);
                return callback(err);
            }

            console.log('it worked');
            console.log(UTA.token);
            console.log(data);
            callback();
    });
};

<?xml version="1.0" encoding="utf-8"?>
<Siri version="1.3" xmlns="http://www.siri.org.uk/siri">
    <ResponseTimestamp>2019-02-16T22:37:24.1431014-07:00</ResponseTimestamp>
    <StopMonitoringDelivery version="1.3">
        <ResponseTimestamp>2019-02-16T22:37:24.1431014-07:00</ResponseTimestamp>
        <ValidUntil>2019-02-16T22:37:34.1431014-07:00</ValidUntil>
        <MonitoredStopVisit>
            <RecordedAtTime>2019-02-16T22:37:24.1431014-07:00</RecordedAtTime>
            <MonitoredVehicleJourney>
                <LineRef>750</LineRef>
                <DirectionRef>SOUTHBOUND</DirectionRef>
                <FramedVehicleJourneyRef>
                    <DataFrameRef>2019-02-16T00:00:00-07:00</DataFrameRef>
                    <DatedVehicleJourneyRef>3706978</DatedVehicleJourneyRef>
                </FramedVehicleJourneyRef>
                <PublishedLineName>FRONTRUNNER</PublishedLineName>
                <OriginRef>FR601084</OriginRef>
                <DestinationRef>FR801164</DestinationRef>
                <Monitored>True</Monitored>
                <VehicleLocation>
                    <Longitude>-111.9306</Longitude>
                    <Latitude>41.004124</Latitude>
                </VehicleLocation>
                <ProgressRate>1</ProgressRate>
                <CourseOfJourneyRef>18084</CourseOfJourneyRef>
                <VehicleRef>113</VehicleRef>
                <MonitoredCall>
                    <StopPointRef>FR301084</StopPointRef>
                    <VisitNumber>1</VisitNumber>
                    <VehicleAtStop>false</VehicleAtStop>
                    <Extensions>
                        <EstimatedDepartureTime>136</EstimatedDepartureTime>
                        <Direction>To Provo</Direction>
                        <Distance>9644.7823876475977</Distance>
                    </Extensions>
                </MonitoredCall>
                <Extensions>
                    <LastGPSFix>2019-02-16T22:37:16</LastGPSFix>
                    <Scheduled>False</Scheduled>
                    <Bearing>129.54093468554098</Bearing>
                    <Speed>79.829126894854753</Speed>
                    <DestinationName>Provo</DestinationName>
                </Extensions>
            </MonitoredVehicleJourney>
            <MonitoredVehicleJourney>
                <LineRef>750</LineRef>
                <DirectionRef>NORTHBOUND</DirectionRef>
                <FramedVehicleJourneyRef>
                    <DataFrameRef>2019-02-16T00:00:00-07:00</DataFrameRef>
                    <DatedVehicleJourneyRef>3706927</DatedVehicleJourneyRef>
                </FramedVehicleJourneyRef>
                <PublishedLineName>FRONTRUNNER</PublishedLineName>
                <OriginRef>FR801164</OriginRef>
                <DestinationRef>FR601084</DestinationRef>
                <Monitored>True</Monitored>
                <VehicleLocation>
                    <Longitude>-111.904274</Longitude>
                    <Latitude>40.625053</Latitude>
                </VehicleLocation>
                <ProgressRate>1</ProgressRate>
                <CourseOfJourneyRef>18124</CourseOfJourneyRef>
                <VehicleRef>108</VehicleRef>
                <MonitoredCall>
                    <StopPointRef>FR301081</StopPointRef>
                    <VisitNumber>1</VisitNumber>
                    <VehicleAtStop>false</VehicleAtStop>
                    <Extensions>
                        <EstimatedDepartureTime>2912</EstimatedDepartureTime>
                        <Direction>To Ogden</Direction>
                        <Distance>132285.03109158284</Distance>
                    </Extensions>
                </MonitoredCall>
                <Extensions>
                    <LastGPSFix>2019-02-16T22:37:20</LastGPSFix>
                    <Scheduled>False</Scheduled>
                    <Bearing>10.410927719684226</Bearing>
                    <Speed>79.067224214902424</Speed>
                    <DestinationName>Ogden</DestinationName>
                </Extensions>
            </MonitoredVehicleJourney>
        </MonitoredStopVisit>
        <Extensions>
            <StopName>FARMINGTON STATION</StopName>
            <StopLongitude>-111.903667000</StopLongitude>
            <StopLatitude>40.987266000</StopLatitude>
            <StopLocation>Utah</StopLocation>
        </Extensions>
    </StopMonitoringDelivery>
</Siri>

标签: aws-sdk-js

解决方案


如果要处理响应,则 convertResponseTypes 需要设置为 true。


推荐阅读