用于更新Strapi Return的产品的自定义API 405

发布于 2025-02-10 08:32:30 字数 6552 浏览 2 评论 0原文

我目前正在设置Strapi V4,以在收到我的PIM的另一个请求后,通过PUT请求更新产品集合。

我刚刚使用Strapi生成CLI生成了自定义API,并基本上设置了两个功能,以在我的控制器中执行上述任务以进行更新产品路由。

"use strict";

var axios = require("axios");
var qs = require("qs");

function getUpdates() {
  var baseLinkerData = qs.stringify({
    method: "getInventoryProductsList",
    parameters: '{"inventory_id": 3807}',
  });
  var config = {
    method: "post",
    url: "https://api.baselinker.com/connector.php",
    headers: {
      "X-BLToken": `${process.env.BL_TOKEN}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    data: baseLinkerData,
  };

  axios(config)
    .then(function (response) {
      // const updates = JSON.stringify(response.data.products);
      const updates = response.data.products;
      // console.log(updates);
      updateProducts(updates);
    })
    .catch(function (error) {
      console.log(error);
    });
}

function updateProducts(productList) {
  // Prepare a request

  for (const [key, value] of Object.entries(productList)) {

    // Mapping of the product data
    var data = JSON.stringify({
      data: {
        id: value.id,
        ean: value.ean ? value.ean : null,
        sku: value.sku ? value.sku : null,
        name: value.name,
        quantity: value.stock ? parseInt(value.stock.bl_5076) : 0,
        price_brutto: value.prices ? parseFloat(value.prices["3624"]) : 0,
      },
    });
    console.log(data);

   // Config for the request
    var config = {
      method: "put",
      url: `${process.env.MY_HEROKU_URL}/api/products/${key}`,
      headers: {
        Authorization: process.env.STRAPI_API_AUTH,
        "Content-Type": "application/json",
      },
      data: data,
    };

    // Send the request

    axios(config)
      .then(function (response) {
        console.log(JSON.stringify(response.data));
      })
      .catch(function (error) {
        console.log(error);
      });
    // });
  }
}
/**
 * A set of functions called "actions" for `update-products`
 */

module.exports = {
  exampleAction: async (ctx, next) => {
    try {
      getUpdates();
      ctx.body = "ok";
    } catch (err) {
      ctx.body = err;
    }
  },
};

使用此代码,我会收到405错误:


Error: connect EMFILE 00.000.00.000:443 - Local (undefined:undefined)
    at internalConnect (net.js:934:16)
    at defaultTriggerAsyncIdScope (internal/async_hooks.js:452:18)
    at GetAddrInfoReqWrap.emitLookup [as callback] (net.js:1077:9)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:73:8) {
  errno: -24,
  code: 'EMFILE',
  syscall: 'connect',
  address: '00.000.00.000',
  port: 443,
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
      Authorization: 'process.env.BEARER',
      'User-Agent': 'axios/0.24.0',
      'Content-Length': 82
    },
    method: 'put',
    url: 'https://sampleurl.herokuapp.com/api/products/16611',
    data: '{"data":{"id":21847637,"ean":null,"sku":null,"name":"GRA O TRON Winter is here – Kubek termiczny","quantity":1,"price_brutto":55.99}}'
    },
  request: <ref *1> Writable {
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      prefinished: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: true,
      errored: null,
      closed: false
    },
    _events: [Object: null prototype] {
      response: [Function: handleResponse],
      error: [Function: handleRequestError]
    },
    _eventsCount: 2,
    _maxListeners: undefined,
    _options: {
      maxRedirects: 21,
      maxBodyLength: 10485760,
      protocol: 'https:',
      path: '/api/products/16611',
      method: 'PUT',
      headers: [Object],
      agent: undefined,
      agents: [Object],
      auth: undefined,
      hostname: 'sampleurl.herokuapp.com',
      port: null,
      nativeProtocols: [Object],
      pathname: '/api/products/16611'
    },
    _ended: false,
    _ending: true,
    _redirectCount: 0,
    _redirects: [],
    _requestBodyLength: 82,
    _requestBodyBuffers: [ [Object] ],
    _onNativeResponse: [Function (anonymous)],
    _currentRequest: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: false,
      _headerSent: true,
      socket: [TLSSocket],
      _header: 'PUT /api/products/16611 HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/json\r\n' +
        'Author^Cse,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'sampleurl.herokuapp.com',
      protocol: 'https:',
      _redirectable: [Circular *1],
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    _currentUrl: 'https://sampleurl.herokuapp.com/api/products/16611',
    [Symbol(kCapture)]: false
  },
  response: undefined,
  isAxiosError: true,
  toJSON: [Function: toJSON]
}

我只是无法缠绕我的头,我也想知道,当数据已经拔出数据时,如果不使用API​​,将是另一种更新集合的方式使用第一个请求?

谢谢!

I'm currently setting up Strapi V4 to update products collection with a PUT request after receiving another request from my PIM.

I have just generated a custom API using strapi generate CLI and basically set up two functions to do the above mentioned task within my controller for update-products route.

"use strict";

var axios = require("axios");
var qs = require("qs");

function getUpdates() {
  var baseLinkerData = qs.stringify({
    method: "getInventoryProductsList",
    parameters: '{"inventory_id": 3807}',
  });
  var config = {
    method: "post",
    url: "https://api.baselinker.com/connector.php",
    headers: {
      "X-BLToken": `${process.env.BL_TOKEN}`,
      "Content-Type": "application/x-www-form-urlencoded",
    },
    data: baseLinkerData,
  };

  axios(config)
    .then(function (response) {
      // const updates = JSON.stringify(response.data.products);
      const updates = response.data.products;
      // console.log(updates);
      updateProducts(updates);
    })
    .catch(function (error) {
      console.log(error);
    });
}

function updateProducts(productList) {
  // Prepare a request

  for (const [key, value] of Object.entries(productList)) {

    // Mapping of the product data
    var data = JSON.stringify({
      data: {
        id: value.id,
        ean: value.ean ? value.ean : null,
        sku: value.sku ? value.sku : null,
        name: value.name,
        quantity: value.stock ? parseInt(value.stock.bl_5076) : 0,
        price_brutto: value.prices ? parseFloat(value.prices["3624"]) : 0,
      },
    });
    console.log(data);

   // Config for the request
    var config = {
      method: "put",
      url: `${process.env.MY_HEROKU_URL}/api/products/${key}`,
      headers: {
        Authorization: process.env.STRAPI_API_AUTH,
        "Content-Type": "application/json",
      },
      data: data,
    };

    // Send the request

    axios(config)
      .then(function (response) {
        console.log(JSON.stringify(response.data));
      })
      .catch(function (error) {
        console.log(error);
      });
    // });
  }
}
/**
 * A set of functions called "actions" for `update-products`
 */

module.exports = {
  exampleAction: async (ctx, next) => {
    try {
      getUpdates();
      ctx.body = "ok";
    } catch (err) {
      ctx.body = err;
    }
  },
};

With this code I am getting the 405 error:


Error: connect EMFILE 00.000.00.000:443 - Local (undefined:undefined)
    at internalConnect (net.js:934:16)
    at defaultTriggerAsyncIdScope (internal/async_hooks.js:452:18)
    at GetAddrInfoReqWrap.emitLookup [as callback] (net.js:1077:9)
    at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:73:8) {
  errno: -24,
  code: 'EMFILE',
  syscall: 'connect',
  address: '00.000.00.000',
  port: 443,
  config: {
    transitional: {
      silentJSONParsing: true,
      forcedJSONParsing: true,
      clarifyTimeoutError: false
    },
    adapter: [Function: httpAdapter],
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    maxBodyLength: -1,
    validateStatus: [Function: validateStatus],
    headers: {
      Accept: 'application/json, text/plain, */*',
      'Content-Type': 'application/json',
      Authorization: 'process.env.BEARER',
      'User-Agent': 'axios/0.24.0',
      'Content-Length': 82
    },
    method: 'put',
    url: 'https://sampleurl.herokuapp.com/api/products/16611',
    data: '{"data":{"id":21847637,"ean":null,"sku":null,"name":"GRA O TRON Winter is here – Kubek termiczny","quantity":1,"price_brutto":55.99}}'
    },
  request: <ref *1> Writable {
    _writableState: WritableState {
      objectMode: false,
      highWaterMark: 16384,
      finalCalled: false,
      needDrain: false,
      ending: false,
      ended: false,
      finished: false,
      destroyed: false,
      decodeStrings: true,
      defaultEncoding: 'utf8',
      length: 0,
      writing: false,
      corked: 0,
      sync: true,
      bufferProcessing: false,
      onwrite: [Function: bound onwrite],
      writecb: null,
      writelen: 0,
      afterWriteTickInfo: null,
      buffered: [],
      bufferedIndex: 0,
      allBuffers: true,
      allNoop: true,
      pendingcb: 0,
      prefinished: false,
      errorEmitted: false,
      emitClose: true,
      autoDestroy: true,
      errored: null,
      closed: false
    },
    _events: [Object: null prototype] {
      response: [Function: handleResponse],
      error: [Function: handleRequestError]
    },
    _eventsCount: 2,
    _maxListeners: undefined,
    _options: {
      maxRedirects: 21,
      maxBodyLength: 10485760,
      protocol: 'https:',
      path: '/api/products/16611',
      method: 'PUT',
      headers: [Object],
      agent: undefined,
      agents: [Object],
      auth: undefined,
      hostname: 'sampleurl.herokuapp.com',
      port: null,
      nativeProtocols: [Object],
      pathname: '/api/products/16611'
    },
    _ended: false,
    _ending: true,
    _redirectCount: 0,
    _redirects: [],
    _requestBodyLength: 82,
    _requestBodyBuffers: [ [Object] ],
    _onNativeResponse: [Function (anonymous)],
    _currentRequest: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 7,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      destroyed: false,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      _defaultKeepAlive: true,
      useChunkedEncodingByDefault: true,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: null,
      _hasBody: true,
      _trailer: '',
      finished: false,
      _headerSent: true,
      socket: [TLSSocket],
      _header: 'PUT /api/products/16611 HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Content-Type: application/json\r\n' +
        'Author^Cse,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      host: 'sampleurl.herokuapp.com',
      protocol: 'https:',
      _redirectable: [Circular *1],
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    _currentUrl: 'https://sampleurl.herokuapp.com/api/products/16611',
    [Symbol(kCapture)]: false
  },
  response: undefined,
  isAxiosError: true,
  toJSON: [Function: toJSON]
}

I just can't wrap my head around this, also I was wondering what would be another way to update the collection without using API when the data is already pulled with the first request?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

蓝颜夕 2025-02-17 08:32:30

我通过使用这两个呼叫来做到这一点 - 取决于我的控制哈希值以及是否存在产品。

await strapi.db.query('api::product.product').update(query)
await strapi.db.query('api::product.product').create(query)

更新和创建的查询是相同的 - 但是创建一个没有“在哪里”参数。

const query = {
  where: {
    id: existing_products[new_data.import_code].id
  },
  data: {
    ...new_data,
    import_date_time: new Date().toISOString(),
    import_hash: hash
  }
}

另外 - 注意哈希值 - 我从“ new_data”进行计算,并且仅在它们不同时导入 - 因此,如果什么都没有更改,我就不必更新记录。

I do it by using these two calls - depending on my control hash value and if product exists or not.

await strapi.db.query('api::product.product').update(query)
await strapi.db.query('api::product.product').create(query)

The queries for update and create are the same - but the create one does not have “where” parameter.

const query = {
  where: {
    id: existing_products[new_data.import_code].id
  },
  data: {
    ...new_data,
    import_date_time: new Date().toISOString(),
    import_hash: hash
  }
}

Also - notice the hash value - I calculate it from “new_data” and import only if they are different - so I do not have to update the record if nothing has changed.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文