New Amazon Product Advertising API V5 for Node

Previously I had written some node.js code that would taken an Amazon ASIN and store data related to the product in a Postgres database for use in some websites.

I noticed this had stopped working and after some investigation found the API I was using had been replaced with the new v5 version. More information about V5 can be found here.

This is a pretty major change and the API now returns JSON responses instead of XML.

Old XML API version: node-apac

I had previously used this project from GitHub:

and mapping the XML to JSON using the camaro library:

paapi5-nodejs-sdk

Since there is such a big difference in the API, I started looking for alternatives. Amazon provide an list of "SDK"s here:

I downloaded the official Node.js "SDK" and it seemed to be a sample project that is not really an SDK and the code provided didn't seem very nice and quite old school.

After going back to investigate, there seems to be an npm package:

and GitHub repository:

I am a bit confused as this official SDK doesn't seem to be from a user linked to Amazon.

I decided to try it in the hopes it would be better supported in future than other projects that might not be so lucky.

I normally use TypeScript and many times wonder if the configuration and type wrangling are worth the pain, but that is a different story.

Turns out if I ran the sample JavaScript code with node:

node sampleGetItemsApi.js

it would work fine. But this downloaded version from the zip file does not actually use the npm package paapi5-nodejs-sdk and contains the source code itself. Changing this code to use paapi5-nodejs-sdk and it fails.

I took that same code and ran it in my Jest test as TypeScript using the paapie5-nodejs-sdk import and it would fail. Maybe the download is out of sync with the npm package? There seems to be some link between them as the reason I found there was a package is due to it being mentioned in the README.md of the download zip file from Amazon.

Internally the error seemed to be:

The "chunk" argument must be of type string or an instance of Buffer. Received an instance of Object

and my test case output:

Warning: superagent request was sent twice, because both .end() and .then() were called. Never call .end() if you use promises

      152 | }
      153 |
    > 154 | api.getItems(getItemsRequest).then(
          |                               ^
      155 |   function (data) {
      156 |     onSuccess(data)
      157 |   },

      at Request.then (node_modules/superagent/lib/request-base.js:235:15)
      at Object. (sampleGetItems-v5.jest.ts:154:31)

    console.warn
      Warning: .end() was called twice. This is not supported in superagent

      152 | }
      153 |
    > 154 | api.getItems(getItemsRequest).then(
          |                               ^
      155 |   function (data) {
      156 |     onSuccess(data)
      157 |   },

      at Request.Object..Request.end (node_modules/superagent/lib/node/index.js:768:13)
      at Object. (sampleGetItems-v5.jest.ts:154:31)

    console.log
      Error calling PA-API 5.0!

      at onError (sampleGetItems-v5.jest.ts:141:11)

    console.log
      Printing Full Error Object:
      {
       "code": "ERR_INVALID_ARG_TYPE"
      }

      at onError (sampleGetItems-v5.jest.ts:142:11)

    console.log
      Status Code: undefined

      at onError (sampleGetItems-v5.jest.ts:143:11)

paapi5-typescript-sdk

While trying to figure out if TypeScript was the actual problem (it appears not to be), I found this other project. It is unofficial, but the API is much cleaner and the code for the same sample is much smaller. This actually ran and worked, so I am going with this for now.

sampleGetItemsApi.js example code changed to using paapi5-typescript-sdk

import { GetItemsRequest, PartnerType, Host, Region } from 'paapi5-typescript-sdk'

const request = new GetItemsRequest(
{
  ItemIds: ["059035342X", "B00X4WHP5E", "B00ZV9RDKK"],
  Condition: "New",
  Resources: [
    "Images.Primary.Medium",
    "ItemInfo.Title",
    "Offers.Listings.Price",
  ]
},
"",
PartnerType.ASSOCIATES,
'',
'',
Host.UNITED_STATES,
Region.UNITED_STATES
)

const data = await request.send()

Other JavaScript Options

I also found two other JavaScript open source projects that seem like potential options if you don't like TypeScript: