I am exploring the Google APIs, mostly the Places API. Because the number of requests to the Google Places API is limited to 100,000, I am looking for ways to minimize the number of requests sent to the API. I was thinking of using a database to store previously received responses, so in the future I could retrieve them without making requests to the API and will do request to the API only in a case if the needed data had not been previously stored in my database.
According to Google API terms of use, specifically the section 10.1.3 Restrictions against Copying or Data Export, it is not allowed to store data indefinitely, but it is legal to cache it temporarily:
You must not pre-fetch, cache, or store any Content, except that you may store: (i) limited amounts of Content for the purpose of improving the performance of your Maps API Implementation if you do so temporarily (and in no event for more than 30 calendar days), securely, and in a manner that does not permit use of the Content outside of the Service; and (ii) any content identifier or key that the Maps APIs Documentation specifically permits you to store. For example, you must not use the Content to create an independent database of "places" or other local listings information.
I find this section not well explained. Can I store any data received by the API in my database for 30 days or only ids of places? Because in some other contexts I have read that it is only allowed to store the ids. I understood it this way: I can store places ids indefinitely, but can use the whole data only for 30 days.
Because I have been reading about Google APIs for only a couple of days, I have maybe missed some term of use, so I would be really thankful if you could help me.
Any suggestions how to minimize the number of calls to the APIs, or sharing some experiences related to real projects using those APIs will be really appreciated. Also if you could suggest me some alternative APIs which could provide similar functionality would be really helpful.
Thank You in advance!
From my experience with the Google Places API, your understanding is just about correct. Let me explain the two stipulations in my own words:
i) Without prefetching, or redistributing outside your application, you may cache API results for up to 30 days.
ii) You can use a place ID or key in your application specific data, but nothing else (e.g. if your app lets user's "check-in" places, you can store a list of place IDs where they've been on a user object and lookup the places as needed by ID, but you can't store a list of all the places with Google's names/details).
In order to reduce the number of API calls and accelerate my app, what I do is cache the nearby place calls in a simple key-value cache, where the key is the lat-lng pair rounded to a certain precision (so that calls within a certain radius will hit the cache) and the value is the entire JSON result string. Here is my code, which is Java running on Google's App Engine:
// Using 4 decimal places for rounding represents approximately 11 meters of precision
// http://gis.stackexchange.com/questions/8650/how-to-measure-the-accuracy-of-latitude-and-longitude
public static final int LAT_LONG_CACHE_PRECISION = 4;
public static final int CACHE_DURATION_SEC = 24 * 60 * 60; // one day in seconds
...
String cacheKey = "lat,lng:" + round(latitude) + "," + round(longitude);
asyncCache.put(cacheKey, dataJSON, Expiration.byDeltaSeconds(CACHE_DURATION_SEC), MemcacheService.SetPolicy.SET_ALWAYS);
...
private static double round(double value) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(LAT_LONG_CACHE_PRECISION, RoundingMode.HALF_UP);
return bd.doubleValue();
}
As for alternative APIs, I would suggest you look at the following:
Yelp API - provides bar/restaurant data that Google lacks
Facebook API - easy to use if you're already using Facebook's SDK
Factual: Places Crosswalk - aggregates and normalizes places data from many sources, including Facebook and Yelp, but not Google
Currently I'm only using Google Places API, but I'm planning on adding Yelp or Factual later to improve the results for the end user.