http://www.devexchanges.info/2016/10/getting-started-with-rest-consuming.html
In mobile development, building an applications whose content is static can be a bad idea. Instead, you should consider building applications that can display fresh content every time the user opens them. So, we usually get/request/update app data through Internet. The connection API could be Socket API or more popular is through web service (SOAP and REST).
As you can see on my blog, I had 2 posts about SOAP web service, you should take a glance first:
And this is first time I talk about REST API/web service. For the beginners like me, that might sound hard, but with more and more websites exposing their resources through REST APIs, it's actually quite easy.
REST is a simple way to organize interactions between independent systems. It's been growing in popularity since 2005, and inspires the design of services, such as the Twitter API. This is due to the fact that REST allows you to interact with minimal overhead with clients as diverse as mobile phones and other websites. In theory, REST is not tied to the web, but it's almost always implemented as such, and was inspired by HTTP. As a result, REST can be used wherever HTTP can.
The alternative is building relatively complex conventions on top of HTTP. Often, this takes the shape of entire new XML-based languages. The most illustrious example is SOAP. You have to learn a completely new set of conventions, but you never use HTTP to its fullest power. Because REST has been inspired by HTTP and plays to its strengths, it is the best way to learn how HTTP works.
After an initial overview, we'll examine each of the HTTP building blocks: URLs, HTTP verbs and response codes. We'll also review how to use them in a RESTful way. Along the way, we'll illustrate the theory with an example application, which simulates the process of keeping track of data related to a company's clients through a web interface.
REST asks developers to use HTTP methods explicitly and in a way that’s consistent with the protocol definition. This basic REST design principle establishes a one-to-one mapping between create, read, update, and delete (CRUD) operations and HTTP methods. According to this mapping:
In this tutorial, I'm going to show you how to use the classes and methods available in the Android SDK to connect to remote web servers and interact with them using their REST APIs.
After start a new Android Studio project, you must add Internet permission for your app in AndroidManifest.xml. So, add this line outside <application> tag:
<uses-permission android:name="android.permission.INTERNET" />
The Android platform does not allow you to run network operations on the main thread of the application. Therefore, all your networking code must belong to a background thread. The easiest way is make a subclass of AsyncTask
and in the main thread, invoking excute()
to start it:
private class GetDataTask extends AsyncTask<Void, Void, String> {
@Override
protected String doInBackground(Void... voids) {
//More code will be added here later
}
}
We will get data from URL, By using the openConnection()
method of the URL
class, you can quickly set up a connection to any REST endpoint. The return value of openConnection()
must be cast to an instance of either HttpURLConnection
or HttpsURLConnection
, depending on whether the endpoint is accessed over HTTP or HTTPS. Both HttpURLConnection
and HttpsURLConnection
allow you to perform operations such as adding request headers and reading responses.
Setting up a connection with the GitHub API's root endpoint:
// Create URL
URL githubEndpoint = new URL("https://api.github.com/");
// Create connection
HttpsURLConnection myConnection = (HttpsURLConnection) githubEndpoint.openConnection();
The next important step is adding headers for your GET request. By using setRequestProperty()
method multiple times, you can add multiple headers for your request:
myConnection.setRequestProperty("User-Agent", "my-rest-app-v0.1");
myConnection.setRequestProperty("Accept", "application/vnd.github.v3+json");
myConnection.setRequestProperty("Contact-Me", "wandered.vip.007@example.com");
Now, we must read the response message from API. Once you have passed all the request headers, you can check if you have a valid response using the getResponseCode()
method of the HttpURLConnection
object. If the HttpURLConnection
class gets a redirect response code, such as 200, it handles it automatically and follows the redirect. Therefore, usually, you will not have to write any extra code to check for redirects.
In case of no errors, you can now call the getInputStream()
method to get a reference to the input stream of the connection. The response data from REST API usually is JSON, therefore, instead of reading from the InputStream
object directly, I suggest you create an InputStreamReader
for it. After that, you can use/parse JSON data in your way:
if (myConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {//HTTP_OK code is 200
InputStream responseBody = myConnection.getInputStream();
InputStreamReader responseBodyReader = new InputStreamReader(responseBody, "UTF-8");
BufferedReader streamReader = new BufferedReader(responseBodyReader);
StringBuilder responseStrBuilder = new StringBuilder();
//get JSON String
String inputStr;
while ((inputStr = streamReader.readLine()) != null)
responseStrBuilder.append(inputStr);
myConnection.disconnect();
return responseStrBuilder.toString();
} else {
Log.d("Main", "error in connection");
return "";
}
Remember to invoke myConnection.disconnect()
to close the HttpURLConnection
.
For example, the JSON document returned by the root endpoint of GitHub's REST API with my account will be like this:
{
"current_user_url": "https://api.github.com/user",
"current_user_authorizations_html_url": "https://github.com/settings/connections/applications{/client_id}",
"authorizations_url": "https://api.github.com/authorizations",
"code_search_url": "https://api.github.com/search/code?q={query}{&page,per_page,sort,order}",
"emails_url": "https://api.github.com/user/emails",
"emojis_url": "https://api.github.com/emojis",
"events_url": "https://api.github.com/events",
"feeds_url": "https://api.github.com/feeds",
"followers_url": "https://api.github.com/user/followers",
"following_url": "https://api.github.com/user/following{/target}",
"gists_url": "https://api.github.com/gists{/gist_id}",
"hub_url": "https://api.github.com/hub",
"issue_search_url": "https://api.github.com/search/issues?q={query}{&page,per_page,sort,order}",
"issues_url": "https://api.github.com/issues",
"keys_url": "https://api.github.com/user/keys",
"notifications_url": "https://api.github.com/notifications",
"organization_repositories_url": "https://api.github.com/orgs/{org}/repos{?type,page,per_page,sort}",
"organization_url": "https://api.github.com/orgs/{org}",
"public_gists_url": "https://api.github.com/gists/public",
"rate_limit_url": "https://api.github.com/rate_limit",
"repository_url": "https://api.github.com/repos/{owner}/{repo}",
"repository_search_url": "https://api.github.com/search/repositories?q={query}{&page,per_page,sort,order}",
"current_user_repositories_url": "https://api.github.com/user/repos{?type,page,per_page,sort}",
"starred_url": "https://api.github.com/user/starred{/owner}{/repo}",
"starred_gists_url": "https://api.github.com/gists/starred",
"team_url": "https://api.github.com/teams",
"user_url": "https://api.github.com/users/{user}",
"user_organizations_url": "https://api.github.com/user/orgs",
"user_repositories_url": "https://api.github.com/users/{user}/repos{?type,page,per_page,sort}",
"user_search_url": "https://api.github.com/search/users?q={query}{&page,per_page,sort,order}"
}
To change the HTTP method of your HttpURLConnection
object, you must use its setRequestMethod()
method. For example, the following code snippet opens a connection to an endpoint that belongs to httpbin.org and sets its HTTP method to POST
:
URL httpbinEndpoint = new URL("https://httpbin.org/post");
HttpsURLConnection myConnection = (HttpsURLConnection) httpbinEndpoint.openConnection();
myConnection.setRequestMethod("POST");
The POST
requests are used to send data to the server. By writing to the output stream of the connection, you can easily add any data to the body of the POST
request. However, before you do so, you must make sure that you call the setDoOutput
method of the HttpURLConnection
object and give true
to it:
String myData = "message=Hello";
myConnection.setDoOutput(true);
myConnection.getOutputStream().write(myData.getBytes());
After that, you can call the getInputStream()
method to get a reference to the input stream of the connection like the GET
method above:
if (myConnection.getResponseCode() == HttpURLConnection.HTTP_OK) {
Log.i("Main", "getresponse code 200: ");
// Get InputStream
InputStream is = myConnection.getInputStream();
// Convert the InputStream into a string
String charset = "UTF-8";
BufferedReader r = new BufferedReader(new InputStreamReader(is, charset));
StringBuilder total = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
total.append(line);
}
byte[] bytes = total.toString().getBytes();
return new String(bytes, Charset.forName(charset));
} else {
// Server returned HTTP error code.
Log.d("Main", "server error");
}
} catch (IOException e) {
e.printStackTrace();
}
With this example, you can get this JSON data response:
{
"args": {},
"data": "",
"files": {},
"form": {
"message": "Hello"
},
"headers": {
"Accept-Encoding": "gzip",
"Content-Length": "13",
"Content-Type": "application/x-www-form-urlencoded",
"Host": "httpbin.org",
"User-Agent": "Dalvik/2.1.0 (Linux; U; Android 6.0; Android SDK built for x86_64 Build/MASTER)"
},
"json": null,
"origin": "192.168.1.1",
"url": "https://httpbin.org/post"
}
As you can see in the form
object of JSON response, the message you've just post is Hello
.
In this tutorial, you've learned the way to use HttpURLConnection
/HttpsURLConnection
in Android SDK to consume REST APIs. For the full code of this example, you can download by click the button below. It has 2 Activities
named HttpGetActivity
and HttpPostActivity
corresponding to 2 methods (GET and POST).
This is the basic and official way to consume a REST web service. Moreover, if you think this way is hard, you should give third-party libraries like Retrofit or Volley with this work, these libraries provide lots of convenient methods that allow you to make your code more concise and readable, the fact that, most of Android developers are using them! I will have some posts about this topic soon!