I am trying to reorganize my code to use Retrofit (from Volley) for some Foursquare API calls, but have not found a suitable example that shows how to specify a query parameter that has 2 comma separated values.
My base link is as follows:
public static final String VENUES_BASE_URL = "https://api.foursquare.com/v2/venues";
The rest of my URL looks like this:
"?ll=40.7,50.2&limit=50&radius=25000&v=20140909&venuePhotos=1&oauth_token=xxyyxx";
1st implementation for my interface:
public interface Fourquare { @GET("/explore?ll={p1},{p2}&limit=50&radius=25000&v=20140905&venuePhotos=1&oauth_token=xxyyxx") Response getVenues(@Path("p1") String param1, @Path("p2") String param2); }
And then I made a request like this:
RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(ConfigConstants.VENUES_BASE_URL) .build(); Fourquare fourquare = restAdapter.create(Fourquare.class); Response myResponse = fourquare.getVenues("50", "75");
However, the above gave me the following error:
retrofit.RetrofitError: Fourquare.getVenues: URL query string "ll={p1},{p2}&limit=50&radius=25000&v=20140905&venuePhotos=1&oauth_token=xxyyxx" must not have replace block.
2nd implementation (After looking at some SO answers using query parameters. NOTE: After I figure out the call to the ll? Parameter, I will get the token as a parameter):
@GET("/explore&limit=50&radius=25000&v=20140905&venuePhotos=1&oauth_token=xxyyxx") void getVenues(@Query("ll") String ll, Callback<String> cb);
With an actual call like this:
fourquare.getVenues("50,75", new Callback<String>() { @Override public void success(String s, Response response) { Log.d(TAG, "Successful run!"); } @Override public void failure(RetrofitError error) { Log.d(TAG, "Failed run!"); } });
In the above implementation, the error () method is always called, so there is still something wrong with my code. Can someone give some advice on how to properly make this call? I'm sure the problem is with "ll?" parameter.
Update: after enabling registration, this is the last URL I get from Retrofit: https://api.foursquare.com/v2/venues/explore&limit=50&radius=25000&v=20140909&venuePhotos=1&oauth_token=xxyyxx?ll=30.26%2C-97.74
It seems that Foursquare server does not like the ll parameter at the end of the URL, and it should be explicitly placed immediately after .. / v2 / venues / explore, since it works fine when it sends a request through the browser.
Any solutions to get around this API restriction?
3rd implementation (09/17/14) With the colriot sentence , I managed to resolve the 400 response code that I received with my previous implementation. I still have a speed problem in GSON, so I'm looking for suggestions on how to fix this. In particular, my implementation of Retrofit requires more time to display my results compared to Volley, so I wonder if there is a better way to implement a callback.
Foursquare Interface
public interface Fourquare { @GET("/explore?limit=50&radius=25000&v=20140909&venuePhotos=1&oauth_token=xxyyxx") void getVenues(@Query("ll") String ll, Callback<Object> cb); }
RestAdapter call
RestAdapter restAdapter = new RestAdapter.Builder() .setEndpoint(ConfigConstants.VENUES_BASE_URL) .build(); Foursquare foursquare = restAdapter.create(Foursquare.class); foursquare.getVenues("30.26,-97.74", new Callback<Object>() { @Override public void success(Object o, Response response) { Log.d(TAG, "Success!"); // Parse response GsonBuilder gsonBuilder = new GsonBuilder(); Gson gson = gsonBuilder.create(); JsonParser parser = new JsonParser(); String response2 = gson.toJson(o); JsonObject data = parser.parse(response2).getAsJsonObject(); // Populate data model MetaResponse metaResponse = gson.fromJson(data.get("meta"), MetaResponse.class); VenuesExploreResponse myResponse = gson.fromJson(data.get("response"), VenuesExploreResponse.class); // Store results from myResponse in List } @Override public void failure(RetrofitError error) { Log.d(TAG, "Failures!"); } });
Currently, the problem with the above callback implementation is that it takes longer (about 1 second) to analyze and display the results than using Volley. The GsonBuilder / Gson / JsonParser block is exactly the same as in my Volley onResponse (String response) method, except for this intermediate object response2, so most definitely this intermediate / extra step is the bottleneck. I am looking for suggestions on how best to implement Gson parsing. If this is better than a new / separate question, I will do it.