Amazon Product Advertising API Tutorial


 

Before using the Product Advertising API, you need to get register and become an author.

To become a Product Advertising API developer, sign up or login.

After Login/Sign Up following will come out.

You need security credentials to call the Product Advertising API, authenticate requests, and identify yourself as the sender of a request. Two types of credentials are available:

AWS security credentials (access key ID and secret access key)

X.509 certificates

Amazon Product Advertising API Tutorial

After creating your security credentials ,you need to download it, and maintain the record of ACCESS_KEY,SECRAT_KEY as it will be needed to make request to the amazon for searching products.

Product Advertising API Operations

a. Find Items

Use the following Product Advertising API operations to return a list of items that satisfy your search criteria.

ItemSearch Find items that are sold on www.amazon.com by merchants and most sellers.
SimilarityLookup Find items that are similar to ones you’ve already found.

b.Find Out More About Specific Items

Once you use the Product Advertising API operations in the previous section to get a list of items that match your search criteria, you can use the following Product Advertising API operations to return additional information about specific items.

ItemLookup Returns descriptions of specified items.

Building up REST Request

a.Required Parameters

The parameters in the following table are required in every request.

Parameter

Value

Description

Service AWSECommerceService Specifies the Product Advertising API service
AWSAccessKeyId Your Amazon-assigned Access Key ID To register for an Access Key ID from the Amazon Web site, go tohttp://aws.amazon.com. Every Product Advertising API 4.0 request must contain either an Access Key ID or a Subscription ID but not both.
SubscriptionId Your Amazon-assigned subscription ID Every Product Advertising API 4.0 request must contain either an Access Key ID or a Subscription ID but not both. Starting with version 2005-10-05, Product Advertising API stopped distributing Subscription IDs. If you already have one, it will continue to work.
AssociateTag An Amazon-assigned Associate ID The AssociateTag enables product URLs returned by Product Advertising API to be tagged as originating from your Associates website. For your requesst to work and to receive a referral credit for a sale, you must include an AssociateTag value in all your requests. Be sure to specify the value correctly; no error is generated for incorrect values.
Operation Operation you wish to perform, for example,ItemLookup One of the Product Advertising API operation types.

b.General and Optional Parameters.

Parameter

Value

Description

MerchantId

An optional parameter that can be used to filter search results and offer listings to include only items sold by Amazon. By default, the API will return items sold by various merchants including Amazon.

The only valid optional value is “Amazon”.

ResponseGroup

Various

Specifies what subset of data to return. The API Reference Guide specifies the response groups that can be used with each operation..

Version

Various

Version of the Product Advertising API 4.0 WSDL. The default is 2011-08-01. If you want another version, including the latest, you must specify it in your request.

c.ItemSearch Request Structure

Below is the GET request structure for the product search api. One has to query this url for the retrieving the desired result.

d.	http://webservices.amazon.com/onca/xml?
e.	Service=AWSECommerceService&
f.	AWSAccessKeyId=[AWS Access Key ID]&
g.	Operation=ItemSearch&
h.	Keywords=Potter&
i.	SearchIndex=Books&
j.	&Timestamp=[YYYY-MM-DDThh:mm:ssZ]
k.	&Signature=[Request Signature]

d. ItemLookUp Request Structure

l.	http://webservices.amazon.com/onca/xml?
m.	Service=AWSECommerceService&
n.	AWSAccessKeyId=[AWS Access Key ID]&
o.	Operation=ItemLookUp&
p.	ItemId=xyz
q.	SearchIndex=Books&
r.	&Timestamp=[YYYY-MM-DDThh:mm:ssZ]
s.	&Signature=[Request Signature]

Building up Sample Project

Here is an sample example for building a amazon mobile app search .For building an sample app that search the mobile app feeded by Amazon Product Advertisement API.

• Create a Android Application Project.

amazon2

• Create a SignedRequestsHelper.java file, this code is for signing the REST request and generating the Signature, which is needed for authentication.

import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Iterator;
import java.util.Map;
import java.util.SortedMap;
import java.util.TimeZone;
import java.util.TreeMap;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;

import org.apache.commons.codec.binary.Base64;

public class SignedRequestsHelper {
  private static final String UTF8_CHARSET = "UTF-8";
  private static final String HMAC_SHA256_ALGORITHM = "HmacSHA256";
  private static final String REQUEST_URI = "/onca/xml";
  private static final String REQUEST_METHOD = "GET";

  // use xml-uk.amznxslt.com for xslt requests, or ecs.amazonaws.co.uk for others
  private String endpoint = "webservices.amazon.com"; // must be lowercase
 
  // change this so reads from properties file
  private String awsAccessKeyId = "AKIAJBVTJSNL6UC7CY5A";
  private String awsSecretKey = "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";

  private SecretKeySpec secretKeySpec = null;
  private Mac mac = null;

  public SignedRequestsHelper() throws UnsupportedEncodingException, NoSuchAlgorithmException, InvalidKeyException {
    byte[] secretyKeyBytes = awsSecretKey.getBytes(UTF8_CHARSET);
    secretKeySpec =
      new SecretKeySpec(secretyKeyBytes, HMAC_SHA256_ALGORITHM);
    mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
    mac.init(secretKeySpec);
  }

  public String sign(Map<String, String> params) {
    params.put("AWSAccessKeyId", awsAccessKeyId);
    params.put("Timestamp", timestamp());

    SortedMap<String, String> sortedParamMap =
      new TreeMap<String, String>(params);
    String canonicalQS = canonicalize(sortedParamMap);
    String toSign =
      REQUEST_METHOD + "\n"
      + endpoint + "\n"
      + REQUEST_URI + "\n"
      + canonicalQS;

    String hmac = hmac(toSign);
    String sig = percentEncodeRfc3986(hmac);
    String url = "http://" + endpoint + REQUEST_URI + "?" +
    canonicalQS + "&Signature=" + sig;

    return url;
  }

  private String hmac(String stringToSign) {
    String signature = null;
    byte[] data;
    byte[] rawHmac;
    try {
      data = stringToSign.getBytes(UTF8_CHARSET);
      rawHmac = mac.doFinal(data);
      Base64 encoder = new Base64();
      signature = new String(encoder.encode(rawHmac));
    } catch (UnsupportedEncodingException e) {
      throw new RuntimeException(UTF8_CHARSET + " is unsupported!", e);
    }
    return signature;
  }

  private String timestamp() {
    String timestamp = null;
    Calendar cal = Calendar.getInstance();
    DateFormat dfm = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
    dfm.setTimeZone(TimeZone.getTimeZone("GMT"));
    timestamp = dfm.format(cal.getTime());
    return timestamp;
  }

  private String canonicalize(SortedMap<String, String> sortedParamMap)
{
    if (sortedParamMap.isEmpty()) {
      return "";
    }

    StringBuffer buffer = new StringBuffer();
    Iterator<Map.Entry<String, String>> iter =
      sortedParamMap.entrySet().iterator();

    while (iter.hasNext()) {
      Map.Entry<String, String> kvpair = iter.next();
      buffer.append(percentEncodeRfc3986(kvpair.getKey()));
      buffer.append("=");
      buffer.append(percentEncodeRfc3986(kvpair.getValue()));
      if (iter.hasNext()) {
        buffer.append("&");
      }
    }
    String cannoical = buffer.toString();
    return cannoical;
  }

  private String percentEncodeRfc3986(String s) {
    String out;
    try {
      out = URLEncoder.encode(s, UTF8_CHARSET)
      .replace("+", "%20")
      .replace("*", "%2A")
      .replace("%7E", "~");
    } catch (UnsupportedEncodingException e) {
      out = s;
    }
    return out;
  }
}

• Create a java file for passing the GET request parameters building the query parameters. UrlParameterHandler.java file is responsible for maintaining the record of the parameters in Map

Where Map key corresponds to parameter key and Map Value corresponds to query parameter valid value.

import java.util.HashMap;
import java.util.Map;

public class UrlParameterHandler {

	public static UrlParameterHandler paramHandler;
	private UrlParameterHandler() {}
	
	
	public static synchronized UrlParameterHandler getInstance(){
		if(paramHandler==null){
			paramHandler=new UrlParameterHandler();
			return paramHandler;
		}
		return paramHandler; 				
	}
	
	public  Map<String,String> buildMapForItemSearch(){
		Map<String, String> myparams = new HashMap<String, String>();
		myparams.put("Service", "AWSECommerceService");
		myparams.put("Operation", "ItemSearch");
		myparams.put("Version", "2009-10-01");
		myparams.put("ContentType", "text/xml");
		myparams.put("SearchIndex", "MobileApps");//for searching mobile apps
		myparams.put("Keywords", "games");
		myparams.put("AssociateTag", "apps");
		myparams.put("MaximumPrice","1000");
		myparams.put("Sort","price");
		myparams.put("ResponseGroup", "Images,Small");
		return myparams;
	}
	
}

• Now we have the request URL builder set ready for the querying the Amazon api. As we are going to make a GET request to the REST API thus we have to build use AsycTask for doing this ,as for calling a network operation we have to use this in background thread.

Here is the code for parsing the responce..

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import android.util.Log;

public class Parser {
	/** ---------------------  Search TAG --------------------- */
	private static final String KEY_ROOT="Items";
	private static final String KEY_REQUEST_ROOT="Request";
	private static final String KEY_REQUEST_CONTAINER="IsValid";
	private static final String KEY_ITEM="Item";
	private static final String KEY_ID="ASIN";
	private static final String KEY_ITEM_URL="DetailPageURL";
	private static final String KEY_IMAGE_ROOT="MediumImage";
	private static final String KEY_IMAGE_CONTAINER="URL";
	private static final String KEY_ITEM_ATTR_CONTAINER="ItemAttributes";
	private static final String KEY_ITEM_ATTR_TITLE="Title";		
	
	private static final String VALUE_VALID_RESPONCE="True";
	
	//Tags
	//Items,Request,IsValid,Item,ASIN,DetailPageURL,MediumImage,URL,ItemAttributes,Title


	public NodeList getResponceNodeList(String service_url) {
		String searchResponce = this.getUrlContents(service_url);
		Log.i("url",""+service_url);
		Log.i("responce",""+searchResponce);
		Document doc;
		NodeList items = null;
		if (searchResponce != null) {
			try {
				doc = this.getDomElement(searchResponce);
				items = doc.getElementsByTagName(KEY_ROOT);
				Element element=(Element)items.item(0);
				if(isResponceValid(element)){
					items=doc.getElementsByTagName(KEY_ITEM);
				}
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
		return items;
	}	

	public SearchObject getSearchObject(NodeList list,int position){
		SearchObject object=new SearchObject();
		Element e=(Element)list.item(position);
		object.setUrl(this.getValue(e, KEY_ITEM_URL));
		object.setId(this.getValue(e, KEY_ID));
		object.setImageUrl(this.getValue((Element)(e.getElementsByTagName(KEY_IMAGE_ROOT).item(0))
				, KEY_IMAGE_CONTAINER));
		object.setTitle(this.getValue((Element)(e.getElementsByTagName(KEY_ITEM_ATTR_CONTAINER).item(0))
				, KEY_ITEM_ATTR_TITLE));		
		return object;
	}
	
	public boolean isResponceValid(Element element){		
		NodeList nList=element.getElementsByTagName(KEY_REQUEST_ROOT);
		Element e=(Element)nList.item(0);
		if(getValue(e, KEY_REQUEST_CONTAINER).equals(VALUE_VALID_RESPONCE)){
			return true;
		}
		return false;
	}
	
	/** In app reused functions */

	private String getUrlContents(String theUrl) {
		StringBuilder content = new StringBuilder();
		try {
			URL url = new URL(theUrl);
			URLConnection urlConnection = url.openConnection();
			BufferedReader bufferedReader = new BufferedReader(
					new InputStreamReader(urlConnection.getInputStream()), 8);
			String line;
			while ((line = bufferedReader.readLine()) != null) {
				content.append(line + "");
			}
			bufferedReader.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
		return content.toString();
	}

	public Document getDomElement(String xml) {
		Document doc = null;
		DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
		try {

			DocumentBuilder db = dbf.newDocumentBuilder();

			InputSource is = new InputSource();
			is.setCharacterStream(new StringReader(xml));
			doc = (Document) db.parse(is);

		} catch (ParserConfigurationException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		} catch (SAXException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		} catch (IOException e) {
			Log.e("Error: ", e.getMessage());
			return null;
		}

		return doc;
	}

	public final String getElementValue(Node elem) {
		Node child;
		if (elem != null) {
			if (elem.hasChildNodes()) {
				for (child = elem.getFirstChild(); child != null; child = child
						.getNextSibling()) {
					if (child.getNodeType() == Node.TEXT_NODE
							|| (child.getNodeType() == Node.CDATA_SECTION_NODE)) {
						return child.getNodeValue();
					}
				}
			}
		}
		return "";
	}

	public String getValue(Element item, String str) {
		NodeList n = item.getElementsByTagName(str);
		return this.getElementValue(n.item(0));
	}
}

So implement this parser in your application to get the search result.

++++++++++++++++++

We have considerable experience in developing apps using Amazon API.

Over the years we have developed several advanced Amazon based Android and iPhone components, code modules and Frameworks that can work as plug and play solutions for developing new apps that will substantially reduce the app development cost and time.

Contact us

to discuss your Amazon based mobile application development project

Posted in All Tutorials, Android Tutorials | Tagged | Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Powered By: wpnova.com