Consuming REST services with HttpClient

If we have an app that displays data, the chances are that it comes from somewhere outside the device, say somewhere like the Internet.

Getting ready

To work with JSON responses, we need to install the Newtonsoft.Json NuGet package or the Json.NET component. This is an advanced JSON parser; however, we can make use of the DataContractJsonSerializer type or any other serializer for JSON.

How to do it...

In order to obtain data from the Internet or a local network, we use HTTP requests. In this recipe, we access data from http://jsonplaceholder.typicode.com/posts/1:

  1. Access JSON data from the HTTP location in the form:
    {
      "userId": 1,
      "id": 1,
      "title": "sunt aut facere repellat provident occaecati",
      "body": "quia et suscipit
    suscipit recusandae conse"
    }
  2. For any Internet communication, we need to request permission from Android:
    [assembly: UsesPermission(Manifest.Permission.Internet)]
  3. Then, to access the data from the remote source, we make use of HttpClient and the GetStringAsync() method:
    using (var client = new HttpClient()) {
      var uri = "http://jsonplaceholder.typicode.com/posts/1";
      var result = await client.GetStringAsync(uri);
    }
  4. We can try and parse the result ourselves, or we could create a .NET type that will be used to deserialize it:
    public class Post {
      public int Id { get; set; }
      public int UserId { get; set; }
      public string Title { get; set; }
      [JsonProperty("body")]
      public string Content { get; set; }
    }
  5. Now it is time to map the JSON string to the .NET type:
    var post = JsonConvert.DeserializeObject<Post>(result);

If we want to send data to the server, we can do something similar, but instead of doing a GET, we do a POST to http://jsonplaceholder.typicode.com/posts:

  1. First, we have to create our object that we want to send:
    var newPost = new Post {
      UserId = 12,
      Title = "My First Post",
      Content = "This is some real deep stuff in here!"
    };
  2. Once we have our data, we must serialize it into JSON:
    var jsonData = JsonConvert.SerializeObject(newPost);
  3. After that, we need to create the HTTP content and header that we are going to send. Because we are sending JSON data, we specify the content type as "application/json":
    var content = new StringContent(
      jsonData, Encoding.UTF8, "application/json");
  4. Finally, we send the serialized object:
    var uri = "http://jsonplaceholder.typicode.com/posts";
    var result = await client.PostAsync(uri, content);

Doing a POST will return a result from the server, which we use to determine whether everything went well:

  1. We can use the EnsureSuccessStatusCode() method to throw an exception if there is a problem:
    result.EnsureSuccessStatusCode();
  2. Or we can check the IsSuccessStatusCode property for a successful result:
    var success = result.IsSuccessStatusCode;
  3. If there is data in the content of the response, we can read it out of the Content property:
    var resultString = await result.Content.ReadAsStringAsync();
    var post = JsonConvert.DeserializeObject<Post>(resultString);

How it works...

There are many ways for an app to communicate with the outside world. These include technologies used on the Internet, such as HTTP and FTP, as well as via more local technologies such as Bluetooth or NFC. However, one of the most common and most frequently used is HTTP.

HTTP is a way in which two devices can communicate, often through a network such as the Internet. Messages are sent out and received by a server. The server then responds with another message. Data can be transferred via HTTP and is used to provide data from a server to a local app, and vice versa.

Note

The HttpClient property provides a very simple and easy-to-use interface for sending and receiving data over HTTP or HTTPS.

If we want to send an HTTP message, we can make use of the HttpClient property provided by .NET. To request data from a server, all we have to do is request it via the GetStringAsync() method, passing the URI of the resource. There are other types that can be received easily, such as byte arrays via the GetByteArrayAsync() method or a Stream instance via the GetStreamAsync() method. If we want more control over how the request is sent and handled, we can use the GetAsync() method. We can then process the result of these methods using a serializer or parser.

If we want to send data to the server, we have several other methods such as the PostAsync() method or the PutAsync() method. These methods take both the URI and the content that needs to be sent. We typically use POST to send data to the server, but some servers handle PUT messages differently, which we may want. We may want the server to do something different when using PUT.

The content sent to the server is wrapped in an HttpContent type. This type contains the various headers as well as the actual body that we want to send to the server. Headers are used to describe the content as well as how to handle the request. A header can include the content type, content length, or any authorization requirements. The body is the data that we wish to send. The body could be anything, but in most cases, we would serialize the data and send it. We have to be sure that we send the data in a format that the server can understand, for example in XML or JSON.

Note

It is important that the HTTP content is in a format that is understood by the server, otherwise the response will be an error code.

Once the server has received our message, whether through GET or POST, it will respond with a code specifying whether there were errors or not. We can then use this code and respond to the user accordingly.

It is important to remember that sending data over the network is very slow compared to normal CPU operations. Thus, to avoid any app performance issues, we carry out network operations on a separate thread. This is very easy to do with the async and await keywords in C#. The compiler will automatically rewrite our code to start a new thread.

Tip

Sending data over a network is slow and should be done on a separate thread.

As transferring data wirelessly requires battery, and possibly mobile data, it is important that we try and cache what we can. Caching will reduce the need for communication, thus reducing the load on the battery as well as the amount of data consumed.

Another battery-saving technique is prefetching. Prefetching requests data before it is actually needed to reduce the number of requests it has to make later. Each time the wireless controller is woken up, battery is consumed to restore the controller. If we bundle all our requests into a single request, the controller only has to be woken once instead of multiple times.

Tip

Caching and prefetching can be used to reduce battery consumption and data usage as well as improve app performance.

See also

  • The Obtaining a network state recipe
  • The Handling network state changes recipe
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.22.248.208