Dealing with Facebook User Location in Spring

I am currently developing an application that permits users to login via their Facebook accounts, and I am using Spring on the back-end side. In particular, Spring Social helps me to communicate with Facebook, wrapping the Graph API.

Since the application needs to know the whereabouts of a user, it is useful for me knowing the user location or hometown, when these informations are setted and the user choose to set their visibility to public. The first step in the process of reading the informations is to require the access to them. The application runs on iOS, and when it requests an access token to Facebook, it has to specify both user_location and user_hometown permissions. Without them, I would not be able to read neither the user’s location or the user’s hometown.

When the application finally gets the token and send it to the back-end, I start collecting informations from the user’s profile. Regarding the location or hometown, I am interested in knowing the country where the user is located or is from, and since I will handle l10n directly on the application, I just need Facebbok to tell me the country code of user’s location and hometown.

The documentation of Graph API specifies that this information, the country code, can be read at this address:

https://graph.facebook.com/v2.6/LOCATION_ID?fields=location{country_code}

where the LOCATION_ID is, obviously, the id read from user’s location or hometown.
Searching is Spring Social documentation, I found that the FacebookTemplate has no API implementation for the location service. I have to use the RestOperations interface in order to send Facebook my request and handle the result.

And here started my headhaches. The Graph API requires the authentication, so I had to add the access token to the query string of the service. In order to have a clean code, I’ve set a constant, containing my url, with some placeholders where I need to put some values:

The brackets could give some problems using String.format(), so I encoded them in their relative entities:

The double % is needed to escape the % character, or a String.format would consider %7B and %7D as placeholders too. Everything is ready for building the request and consuming the service. Assuming that I have an object of type org.springframework.social.facebook.api.User, called user, and the access token, of type String, in a variable called token, I build the final path:

Everything seems clear. Spring’s documentation tells me that a RestOperations has the useful getForObject method. This method, though, encodes every entity in the given url. In my initial url I wrote %7B to encode an open bracket. The method getForObject, encoding the %, would transform the %7B into %%7B, and it would be totally wrong. Instead of that method signature, then, I had to prefere the one accepting an URI instead of a String.

Now, building an URI from a String containing an url is pretty simple, but I had to consider that the url would be encoded by the URI’s constructor. I also had to encode the dot in the url, so the initial constant became like this:

This request would return an object with a location and and id. The location itself would contains a country_code. I built a couple of DTOs, so I could read the response in a nice way. Here are both the DTOs and the full code used to make the request.

The same can be done with the user’s hometown, knowing that its id get be obtained with user.getHometown().getId(). In this code I used two custom DTOs because I only needed the country’s code, and not other informations. The Graph API supports a lot more of fields, so the same request can be done with more parameters and modifying the DTOs.