How to consume a RESTful API in c#

What is rest API

REST

REST stands for Representational State Transfer

Restful system consists of

a client who requets for the resources.
a server who as the resources.

Representational state transfer (REST) is a software architectural style that defines a set of constraints to be used for creating Web services. RESTful Web services allow the requesting systems to access and manipulate textual representations of Web resources by using a uniform and predefined set of stateless operations.

REST stands for Representational State Transfer and is an architectural style. It defines how applications communicate over the HyperText Transfer Protocol (HTTP). REST APIs involve requests and responses. You make a request to a resource stored on a server and the server responds with the requested information.

A Restful system consists of a

  • client who requests for the resources.
  • server who has the resources.

Architectural Constraints of REST

There are six architectural constraints which makes any web service.
The only optional constraint of REST architecture is code on demand.

The uniform interface constraint defines the interface between clients and servers. It simplifies and decouples the architecture, which enables each part to evolve independently.
Uniform interface is a key constraint that differentiate between a REST API and a non REST API.

There are four guidelines principles of Uniform Interface:

  • Resource-Based
    Each resource must have a specific and cohesive URI.
  • Resource representation
    How the resource will be returned to the client. This representation can be in HTML, XML, JSON, TXT and more.
  • Self-descriptive Messages
    Each message includes enough information to describe how to process the message so that the server can easily analyse the request.
  • Hypermedia as the Engine of Application State (HATEOAS)
    Needs to include links for each response so that the client can discover other resources easily.

The uniform interface separates clients from servers, therefore clients are not concerned with data storage, this remains internal to each server. Servers are not concerned with the user interface or user state so that servers can be simpler and more scalable and
the client doesn’t need to know anything about business logic.

One client can send multiple request to the server but each of them must be independent. The client must include on ever request all  the necessary information so that the server can understand it and process it accordingly. 

Because many clients access the same server and are often requesting the same resource, it is necessary that these responses might be cached to improve availability and performance. But sometimes there is a chance, that users may receive stale data.

A client cannot tell whether it is connected directly to the end server or to an intermediary along the way. Intermediary servers may improve system availability by enabling load balancing and by providing shared caches.

This is an optional feature. It allows the customer to run some code on demand.

HTTP Methods

GET

Retrieve data from specified resource.

POST

Submit data to be processed to a specified resource.

PUT

Update a specified resource.

DELETE

Delete a specified resource.

HEAD

Same as GET but does not return a body.

OPTIONS

Returns the supported HTTP methods.

PATCH

Update partial resources.

How to consume a RESTful API in c#

overview

Json.Net

Information about Serialization and Deserialization

C# console application

Creating a c# console application

For demonstrational purpose we’re programming a c# console application. For our application we need a REST API. I’ve used in this example JSONPlaceholder which is a fake online REST API for testing and prototyping.

What is Json.Net

Json.Net is a third party library which helps conversion between JSON and .NET objects. The JsonSerializer converts .NET objects into their Json equivalent text and JsonDeserializer converts json text to objects by mapping the .NET object property names to the JSON property names. Json.Net is open source, free for commercial purpose and can be easily installed in the NuGet Package Manager.

JSON Serialization

Converts a .NET object to JSON format text.

string json = JsonConvert.Serialize(object); 

JSON Deserialization

Converts JSON format text to a .NET object.

Type object = JsonConvert.DeserializeObject<Type>(json); 

Creating a C# console application

Now, create a new c# console app (.NET Framework) and add a new class. (In our example, ApiHelper)

For sending HTTP requests and receiving HTTP response we’re using the class HttpClient.

Properties
baseAddress
Gets or Sets the base address of URI of the Internet Resource used when sending requests. 
DefaultRequestHeaders
Gets the headers which should be sent with each request. 

ApiHelper class

namespace rest_api
{
    public abstract class ApiHelper {
    
        public static HttpClient ApiClient { get; set;}
        
        public static void InitzializeClient() {
            ApiClient = new HttpClient();
            
            string baseUrl = $"https://jsonplaceholder.typicode.com/";
            
            ApiClient.DefaultRequestHeaders.Accept.Clear();
            ApiClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
            ApiClient.BaseAddress = new Uri(baseUrl);
        }
    }
} 

JSONPlaceholder

For demonstrational purpose we’re using the resource /users from JSONPlaceholder.

At first we need to create classes for our users.
If you’re lazy, with Json2Csharp you can convert any json object easily to a c# class.

 

[
  {
    "id": 1,
    "name": "Leanne Graham",
    "username": "Bret",
    "email": "Sincere@april.biz",
    "address": {
      "street": "Kulas Light",
      "suite": "Apt. 556",
      "city": "Gwenborough",
      "zipcode": "92998-3874",
      "geo": {
        "lat": "-37.3159",
        "lng": "81.1496"
      }
    },
    "phone": "1-770-736-8031 x56442",
    "website": "hildegard.org",
    "company": {
      "name": "Romaguera-Crona",
      "catchPhrase": "Multi-layered client-server neural-net",
      "bs": "harness real-time e-markets"
    }
  },
  {
    "id": 2,
    "name": "Ervin Howell",
    "username": "Antonette",
    "email": "Shanna@melissa.tv",
    "address": {
      "street": "Victor Plains",
      "suite": "Suite 879",
      "city": "Wisokyburgh",
      "zipcode": "90566-7771",
      "geo": {
        "lat": "-43.9509",
        "lng": "-34.4618"
      }
    },
    "phone": "010-692-6593 x09125",
    "website": "anastasia.net",
    "company": {
      "name": "Deckow-Crist",
      "catchPhrase": "Proactive didactic contingency",
      "bs": "synergize scalable supply-chains"
    }
  },
...
] 

Classes

Person class

namespace rest_api
{
    class Person {
        public int id { get; set; }
        public string name { get; set; }
        public string username { get; set; }
        public string email { get; set; }
        public Address address { get; set; }
        public string phone { get; set; }
        public string website { get; set; }
        public Company company { get; set; }
    }
} 

Address class

namespace rest_api
{
    class Address
    {
        public string street { get; set; }
        public string suite { get; set; }
        public string city { get; set; }
        public string zipcode { get; set; }
        public Geo geo { get; set; }

    }
} 

Company class

namespace rest_api
{
    class Company
    {
        public string name { get; set; }
        public string catchPhrase { get; set; }
        public string bs { get; set; }
    }
} 

Geo class

namespace rest_api
{
    class Geo
    {
        public string lat { get; set;  }
        public string lng { get; set;  }

    }
} 

Main program

namespace rest_api
{
    class Program {
       
        public static async Task GetUsers(){
            string url = $"users/";
         
            using (HttpResponseMessage response = await ApiHelper.ApiClient.GetAsync(url)) {
             
                if(response.IsSuccessStatusCode) {
                    string result = await response.content.ReadAsStringAsync();
                     
                    Console.WriteLine("result: " + result);
                    Console.WriteLine("\n--------------------\n");
                    
                    List<Person> people = JsonConvert.DeserializeObject<List<Person>>(result);
                    
                    foreach(Person person in people) {
                        Console.WriteLine("name: " + person.name);
                        Console.WriteLine("username: " + person.username);
                        Console.WriteLine("street: " + person.address.street);
                        Console.WriteLine("city: " + person.address.city);
                        Console.WriteLine("\n--------------------\n");
                    }
                }
                else {
                    Console.WriteLine("failed: " + response);
                }
            }
        }
        
        static async Task Main(string[] args) {
            Console.WriteLine("Application started");
            Console.WriteLine("\n--------------------\n");
            
            ApiHelper.InitializeClient();
            
            await GetUsers();
            
            Console.WriteLine("\n--------------------\n");
            Console.WriteLine("Application finished");
            Console.ReadLine();
        }
    }
} 

2 thoughts on “How to consume a RESTful API in c#”

  1. We are a gгoup of volunteers and starting ɑ brand new scheme in our community.
    Yoᥙr site ⲟffereⅾ us ԝith νaluable information to work on. You have done an impressive ϳob and our entire group can be grateful to you.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top