【问题标题】:Lambda Node JS Shopify API CallLambda 节点 JS Shopify API 调用
【发布时间】:2020-10-16 17:14:31
【问题描述】:

过去几天我一直在尝试解决这个问题,但没有运气,我对 Node Js 和 Lambda 还很陌生。我正在尝试使用 lambda 创建一个 API,当我调用这个新 API 时,我想在 Shopify 中创建一个新的重定向对象。我的函数中运行了以下代码

const http = require('https')

exports.handler = async (event) => {
    return httprequest().then((data) => {
        const response = {
            statusCode: 200,
            body: JSON.stringify(data),
        };
    return response;
    });
};
function httprequest() {
     var username = "shopify-api-private-username";
     var password = "shopify-api-private-password";
     var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
    
     return new Promise((resolve, reject) => {
        const options = {
            host: 'store-name.myshopify.com',
            path: '/admin/api/2020-04/redirects.json',
            port: 443,
            method: 'POST',
            headers: {
              'Authorization': auth,
              'Content-Type': 'application/json',
            },
            body: JSON.stringify({"redirect":{"path":"http://www.apple.com/forum","target":"http://forums.apple.com"}})
        };
        
        const req = http.request(options, (res) => {
            console.log(res);
            if (res.statusCode < 200 || res.statusCode >= 300) {
                return reject(new Error('statusCode=' + res.statusCode));
            }
            var body = [];
            res.on('data', function(chunk) {
                body.push(chunk);
            });
            res.on('end', function() {
                try {
                    body = JSON.parse(Buffer.concat(body).toString());
                } catch(e) {
                    reject(e);
                }
                resolve(body);
            });
        });
        req.on('error', (e) => {
          reject(e.message);
        });
        // send the request
       req.end();
    });
}

尽管我不断更改代码,但我不断收到以下错误。在响应中添加控制台日志后,我看到以下内容,不确定这是 Lambda/Node 响应还是 Shopify:

Function logs:
  servername: 'store-name.myshopify.com',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 11,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'store-name.myshopify.com',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: true,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: [HTTPParser],
      _httpMessage: [Circular],
      [Symbol(res)]: [TLSWrap],
      [Symbol(asyncId)]: 4,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'POST /admin/api/2020-04/redirects.json HTTP/1.1\r\n' +
      'Authorization: Basic base64code_replace_for_security_reasons=\r\n' +
      'Content-Type: application/json\r\n' +
      'Host: store-name.myshopify.com\r\n' +
      'Connection: close\r\n' +
      'Content-Length: 0\r\n' +
      '\r\n',
    _onPendingData: [Function: noopPendingOutput],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object],
      requests: {},
      sockets: [Object],
      freeSockets: {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'POST',
    insecureHTTPParser: undefined,
    path: '/admin/api/2020-04/redirects.json',
    _ended: false,
    res: [Circular],
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: HTTPParser {
      '0': [Function: parserOnHeaders],
      '1': [Function: parserOnHeadersComplete],
      '2': [Function: parserOnBody],
      '3': [Function: parserOnMessageComplete],
      '4': null,
      _headers: [],
      _url: '',
      socket: [TLSSocket],
      incoming: [Circular],
      outgoing: [Circular],
      maxHeaderPairs: 2000,
      _consumed: false,
      onIncoming: [Function: parserOnIncomingClient]
    },
    maxHeadersCount: null,
    reusedSocket: false,
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      authorization: [Array],
      'content-type': [Array],
      host: [Array]
    }
  },
  [Symbol(kCapture)]: false

任何帮助将不胜感激。提前谢谢你。

顺便说一句,我直接在一个新的 Lambda 函数上执行此操作。我唯一的文件是 index.js。

节点版本 Node.js 12.x

【问题讨论】:

  • 400 响应表示您正在向此 api 发送Bad Request,请检查您的请求数据。
  • 我是 Node 新手,我想知道 res.on.data 和 res.on.end 部分之间的区别是什么?我看到这两个部分都与身体一起工作。我已经在 Postman 上实现了这个并且工作正常。当我在两个部分都执行 console.log 时,终端部分没有打印任何内容,谢谢
  • @Carlos on data 会一一捕获数据块。 On end 让您知道不会有更多数据出现,因此整个请求已被读取并可以处理。甚至可以使用 axios 之类的客户端库,这将帮助您提出正确的请求。
  • 在本地运行此代码是否有效?如果不能,您可以在 Postman 中运行请求吗?
  • 我从 Postman 开始,以确保请求和字段都正常,一旦正常,我就启动了 Lambda 函数。然后,我从其他 Stackoverflow 答案中获得了一个 NodeJS 示例,并将其用作模板。过去几天一直在尝试调试。

标签: node.js aws-lambda shopify shopify-api shopify-api-node


【解决方案1】:

您的代码无法正常工作的简短解释是因为错误请求,正如 cmets 中正确指出的那样。这是一个错误的请求,因为您实际上并没有随请求一起发送有效负载。您从 Stack Overflow 获得的代码可能用于 GET 请求,而简单地将 body 属性添加到 options 对象将不起作用。因为根据Node.js docs for HTTPSoptions 对象没有任何名为 body 的属性。

根据Node.js docs for HTTP request,您需要使用write函数发送POST数据。

// Write data to request body
req.write(postData);

要修复您的代码,请添加内容长度属性并写入帖子数据。检查代码 cmets。

    const http = require('https')
    
    exports.handler = async (event) => {
        return httprequest().then((data) => {
            const response = {
                statusCode: 200,
                body: JSON.stringify(data),
            };
        return response;
        });
    };
    function httprequest() {
         var username = "shopify-api-private-username";
         var password = "shopify-api-private-password";
         var auth = 'Basic ' + Buffer.from(username + ':' + password).toString('base64');
        
         return new Promise((resolve, reject) => {
            const data = JSON.stringify({"redirect":{"path":"http://www.apple.com/forum","target":"http://forums.apple.com"}});
            const options = {
                host: 'store-name.myshopify.com',
                path: '/admin/api/2020-04/redirects.json',
                port: 443,
                method: 'POST',
                headers: {
                  'Authorization': auth,
                  'Content-Type': 'application/json',
                  'Content-Length': data.length // Added content length
                }
            };
            
            const req = http.request(options, (res) => {
            console.log(res);
            if (res.statusCode < 200 || res.statusCode >= 300) {
                return reject(new Error('statusCode=' + res.statusCode));
            }
            var body = [];
            res.on('data', function(chunk) {
                body.push(chunk);
            });
            res.on('end', function() {
                try {
                    body = JSON.parse(Buffer.concat(body).toString());
                } catch(e) {
                    reject(e);
                }
                resolve(body);
            });
        });
        req.on('error', (e) => {
          reject(e.message);
        });
        // send the request
        // write POST data
        req.write(data)
       req.end();
    });
}

我已经验证了这段代码,它在本地和 AWS Lambda 函数中都能正常工作。如果您现在收到 422,则表示已经添加了重定向。

除此之外,请考虑使用Shopify API Node.js,它可以提供更好的错误处理、速率限制和其他所需功能。你也可以看看Shopify's Official Node library

【讨论】:

  • Hi Bilal,你是 100% 正确的,通过添加写入函数和数据长度,代码执行成功。肯定会研究 Node Shopify API。感谢您的帮助。
  • 您链接的 npm 包不是官方 Node.js 库,而是第三方库(尽管 Shopify 认可并在其开发文档中列出)。 This here 是官方的。 GitHub repo here.
猜你喜欢
  • 1970-01-01
  • 2015-11-15
  • 1970-01-01
  • 1970-01-01
  • 2021-09-11
  • 1970-01-01
  • 2021-04-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多