Integrating A Web Service Into An Application Is A Common Scenario
Integrating A Web Service Into An Application Is A Common Scenario
This article
demonstrates how to consume a RESTful web service from a Xamarin.Forms application.
Representational State Transfer (REST) is an architectural style for building web services.
REST requests are made over HTTP using the same HTTP verbs that web browsers use to
retrieve web pages and to send data to servers. The verbs are:
GET – this operation is used to retrieve data from the web service.
POST – this operation is used to create a new item of data on the web service.
PUT – this operation is used to update an item of data on the web service.
PATCH – this operation is used to update an item of data on the web service by
describing a set of instructions about how the item should be modified. This verb
is not used in the sample application.
DELETE – this operation is used to delete an item of data on the web service.
Web service APIs that adhere to REST are called RESTful APIs, and are defined using:
A base URI.
HTTP methods, such as GET, POST, PUT, PATCH, or DELETE.
A media type for the data, such as JavaScript Object Notation (JSON).
RESTful web services typically use JSON messages to return data to the client. JSON is a
text-based data-interchange format that produces compact payloads, which results in
reduced bandwidth requirements when sending data. The sample application uses the
open source NewtonSoft JSON.NET library to serialize and deserialize messages.
The simplicity of REST has helped make it the primary method for accessing web
services in mobile applications.
When the sample application is run, it will connect to a locally hosted REST service, as
shown in the following screenshot:
Note
In iOS 9 and greater, App Transport Security (ATS) enforces secure connections between
internet resources (such as the app's back-end server) and the app, thereby preventing
accidental disclosure of sensitive information. Since ATS is enabled by default in apps
built for iOS 9, all connections will be subject to ATS security requirements. If
connections do not meet these requirements, they will fail with an exception.
ATS can be opted out of if it is not possible to use the HTTPS protocol and secure
communication for internet resources. This can be achieved by updating the
app's Info.plist file. For more information see App Transport Security.
The majority of the URIs include the TodoItem ID in the path. For example, to delete
the TodoItem whose ID is 6bb8a868-dba1-4f1a-93b7-24ebce87e243, the client sends a
DELETE request to http://hostname/api/todoitems/6bb8a868-dba1-4f1a-93b7-24ebce87e243 .
For more information about the data model used in the sample application,
see Modeling the data.
When the Web API framework receives a request it routes the request to an action.
These actions are simply public methods in the TodoItemsController class. The
framework uses a routing table to determine which action to invoke in response to a
request, which is shown in the following code example:
C#Copy
config.Routes.MapHttpRoute(
name: "TodoItemsApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { controller="todoitems", id = RouteParameter.Optional }
);
The routing table contains a route template, and when the Web API framework receives
an HTTP request, it tries to match the URI against the route template in the routing
table. If a matching route cannot be found the client receives a 404 (not found) error. If
a matching route is found, Web API selects the controller and the action as follows:
The REST service uses basic authentication. For more information see Authenticating a
RESTful web service. For more information about ASP.NET Web API routing, see Routing
in ASP.NET Web API on the ASP.NET website. For more information about building the
REST service using ASP.NET Core, see Creating Backend Services for Native Mobile
Applications.
The HttpClient class is used to send and receive requests over HTTP. It provides
functionality for sending HTTP requests and receiving HTTP responses from a URI
identified resource. Each request is sent as an asynchronous operation. For more
information about asynchronous operations, see Async Support Overview.
The HttpClient instance is declared at the class-level so that the object lives for as long
as the application needs to make HTTP requests, as shown in the following code
example:
C#Copy
public class RestService : IRestService
{
HttpClient _client;
...
public RestService ()
{
_client = new HttpClient ();
}
...
}
Retrieving Data
C#Copy
public async Task<List<TodoItem>> RefreshDataAsync ()
{
...
var uri = new Uri (string.Format (Constants.TodoItemsUrl, string.Empty));
...
var response = await _client.GetAsync (uri);
if (response.IsSuccessStatusCode)
{
var content = await response.Content.ReadAsStringAsync ();
Items = JsonConvert.DeserializeObject <List<TodoItem>> (content);
}
...
}
If the HTTP operation was successful, the content of the response is read, for display.
The HttpResponseMessage.Content property represents the content of the HTTP response,
and the HttpContent.ReadAsStringAsync method asynchronously writes the HTTP content
to a string. This content is then converted from JSON to a List of TodoItem instances.
Creating Data
C#Copy
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
var uri = new Uri (string.Format (Constants.TodoItemsUrl, string.Empty));
...
var json = JsonConvert.SerializeObject (item);
var content = new StringContent (json, Encoding.UTF8, "application/json");
if (response.IsSuccessStatusCode)
{
Debug.WriteLine (@"\tTodoItem successfully saved.");
}
...
}
201 (CREATED) – the request resulted in a new resource being created before
the response was sent.
400 (BAD REQUEST) – the request is not understood by the server.
409 (CONFLICT) – the request could not be carried out because of a conflict on
the server.
Updating Data
C#Copy
public async Task SaveTodoItemAsync (TodoItem item, bool isNewItem = false)
{
...
response = await _client.PutAsync (uri, content);
...
}
C#Copy
public async Task DeleteTodoItemAsync (string id)
{
var uri = new Uri (string.Format (Constants.TodoItemsUrl, id));
...
var response = await _client.DeleteAsync (uri);
if (response.IsSuccessStatusCode)
{
Debug.WriteLine (@"\tTodoItem successfully deleted.");
}
...
}
204 (NO CONTENT) – the request has been successfully processed and the
response is intentionally blank.
400 (BAD REQUEST) – the request is not understood by the server.
404 (NOT FOUND) – the requested resource does not exist on the server.