czwartek, 20 czerwca 2013

Creating API with MVC ApiController part 1 (with introducing to MVC design pattern)

Introduction to MVC

In the last few years a software architecture changed very heavily. From desktop (forms) application which were very popular in Windows XP users move to SOA and now completely start using web based solution hosting in a cloud. Of course such evolution is not something bad, just the opposite in my opinion because web based application are highly scalable, better secured and available from each place in the Earth where user has an Internet connection. Such a big changes in software architecture cause that also programming model has to change. As response for this need, IT companies start working for on new technologies and improving existing ones. APIs became very popular tool  in a developer hands and whole communication became much more lightweight (by switching from XML to JSON) - mainly because the emerging market of mobile devices.

In a new MVC version 4 also Microsoft introduce some improvements which allow developers creating web services (APIs) in well known MVC environment - let`s start the with an ApiController.

Many of ASP.NET developers are familiar with MVC  pattern because it`s very popular and also very easy to understand. The key thing/process (Picture 1.) which need to be understand is that based on URL an controller process user request and fill a model properties (optional) and then generate a view (with model data). After rendering HTML (view) its time for user interaction which will be finish when user send new request (synchronous or asynchronous) to the server - such request will be handle by a proper controller.To understand how URL address is translated into controller action please take a look here. Let`s take a look  at he each component general definition:
  • A Model  - represents the underlying, logical structure of data in a software application and the high-level class associated with it. This object model doesn`t contain any information about the user interface and also doesn`t contains any business logic.
  • A View - is a collection of HTML tags representing the elements in the user interface.
  • A Controller - represents the classes connecting the model and the view, and is used to communicate between classes in the model and view.

Picture 1. General schema o MVC pattern model.
MVC design pattern looks very easy, don`t you think? So why not extend this website technology to handle API for any kind of solution. To achieve this goal first of all we need to create a simple MVC project.First of all open Visual Studio 2012 and add new project of type ASP.NET MVC 4 Application (type some details like project name) and then select Basic application (Picture 2.).

Picture 2. Choosing proper MVC project template for API.
After creating a new project we should top for a while to understand project architecture (Picture 3.) which in details becomes from MVC architecture. There is a few folder which need to be described:
  • App_Start: store files with classes which logic will be executed on application start (not for session start). The file which is the most important from API creation point of view is WebApiConfig.cs .  Inside it, in Register function default configuration for routing exists. By default all our API calls will be located at URL template like http://website_address/api/controller_name/optional_id for example will return details  for user with ID = 1 if we send a GET request.
Code Snippet
  1. public static void Register(HttpConfiguration config)
  2.      {
  3.          config.Routes.MapHttpRoute(
  4.              name: "DefaultApi",
  5.              routeTemplate: "api/{controller}/{id}",
  6.              defaults: new { id = RouteParameter.Optional }
  7.          );
  8.      }

  • Controllers: stores files with all controllers in the project. It`s very important to be familiar with controllers naming convention. By default controller name consist with two parts: prefix and 'Controller' sufix and in the URL we pass only prefix name (case insensitive). So if our controller has name like UserContoller we should use  api/user/  instead api/usercontroller/ in request URL.
  • Models: this folder stores inforrmation about custom classes which will be used for passing data to the views.
  • Views: stores all views but in pure API approach are useless.

Picture 3. Default project architecture.

Creating first RESTfull service

Now, we are more or less familiar with the project structure now we are on good way to start creating our REST API. First thing in all process is adding a new Controller (Picture 4.) to our project - it can be done by selecting Add -> Controllers and in new windows selecting ''API controller with empty read/write actions".

Picture 4. Adding new ApiController to Controllers folder.

By default a new empty controller is a simple class which derives from ApiContoller base class. Inside this class we create several test functions, which manipulate on simple generic Dictionary<string,string>, as follow:

  • Dictionary<stringstring> Get(): [HttpGet] returns whole dictionary from fake DB context.
  • string Get(string id): [HttpGet] returns single value basen on dictionary key.
  • void Post(string id, string value):[HttpPost] create a new key-value pair.
  • void Put(string id, string value): [HttpPut] updates existing key-value pair.
  • void Delete(string id): [HttpDelete] removes existing key-value pair based on a key.

Code Snippet
  1. /// <summary>
  2.   /// Unsecured, very simple API for manipulating directory.
  3.   /// </summary>
  4.   public class SimpleController : ApiController
  5.   {
  6.       // GET api/simple
  7.       public Dictionary<string, string> Get()
  8.       {
  9.           return FakeDbContext.Instance.Dictionary;
  10.       }
  12.       // GET api/simple/5
  13.       public string Get(string id)
  14.       {
  15.           return FakeDbContext.Instance.Dictionary.FirstOrDefault(c => c.Key == id).Value;
  16.       }
  18.       // POST http://localhost:38828/api/simple?id=1&value=5
  19.       public void Post(string id, string value)
  20.       {
  21.           FakeDbContext.Instance.Dictionary.Add(id, value);
  22.       }
  24.       // PUT api/simple?id=1&value=5
  25.       public void Put(string id, string value)
  26.       {
  27.           FakeDbContext.Instance.Dictionary.Remove(id);
  28.           FakeDbContext.Instance.Dictionary.Add(id, value);
  29.       }
  31.       // DELETE api/simple/5
  32.       public void Delete(string id)
  33.       {
  34.           FakeDbContext.Instance.Dictionary.Remove(id);
  35.       }
  36.   }

As you can see in this example I have non descriptive function name (Get, Post, etc.). I decide to do that to show you easy you can create own API service. One thing you need to be aware of is HTTP method which you are using to send a request - and there is only a few in common usage. Those methods are automatically mapped to the function name as I presented in the example, above but in a real world scenario you need to create much more descriptive function names. However if we change default function names we need to 'show' framework which method is suitable to handle specific type of method. We can do that by specifying one of the following function attributes:
Now it`s worth to test out solution - this is very easy and all you need to do is run the solution and send request using one of the HTTP methods to following URL template:
{Method}  http://{local_address}:{local_port}/api/simple
for example

POST http://localhost:38828/api/simple?id=1&value=5

If someone of you is not familiar with sending HTTP requests by using other than GET (you send a GET request when you type some URL  into browser address window) I can recommend very easy in use HTTP client (extension for Chrome) called Postman.

One more interesting thing is, as we can see on example presented below (Picture 3.), we are also able to modify result format just by manipulating value of the Accept header parameter. By passing response Accept header with value application/xml  or application/json we are changing whole response format.

Picture 3. Testing simple API with results formatted as XML and JSON.
Whole source code of the project is available here.

Thank you.

sobota, 15 czerwca 2013

Asynchronous actions in ASP.NET

An asynchronous operations become very popular in modern programming because by using its developers can take full advantage of multicore processors and perform several operation at the same time. Multithreding exists in ASP.NET since 2.0 version but it was very sophisticated to use it. However starting from .NET 4.5, ASP.NET is fully compatible with all these great features.

To demonstrate how to start with the asynchronous operation in ASP.NET 4.5 I`ve created very simple solution which consist of three projects (Picture 1.):
  • AsyncPageService - REST service based on a ApiController; provides function which will be called by the website.
  • AsyncPageWebsite - main ASP.NET website.
  • Contracts - contains shared type between service and website.

Picture 1. Solution projects.
In my solution data is served by very simple REST web service, which is build by using ApiController from ASP.NET MVC. Inside this I`ve created two controllers (first return N random integers and the second return hardcoded list of an Contracts.User - which is shared type from an Contracts library)  for a GET  requests and decided to stay with a default service configuration so response format (XML or JSON) relay on header 'accept' value with XML by default. Below I presented action for generating random N random numbers - where N is determined by input function parameter with default value equals to 10.

Code Snippet
  1. namespace RestApi.Controllers
  2. {
  3.     using System;
  4.     using System.Collections.Generic;
  5.     using System.Collections.ObjectModel;
  6.     using System.Web.Http;
  8.     using System.Web.Mvc;
  9.     using MVC = System.Web.Mvc;
  11.     public class RandomController : ApiController
  12.     {
  13.         public List<int> GetRandomNumbers(int count = 10)
  14.         {
  15.             var result = new List<int>();
  16.             var random = new Random();
  17.             var tempRandom = 0;
  19.             for (var i = 0; i < count; i++)
  20.             {
  21.                 tempRandom = random.Next(0, 32);
  22.                 result.Add(tempRandom);
  23.             }
  25.             return result;
  26.         }
  27.     }
  28. }

After  web services is ready it`s time to present how we can use it. To demonstrate working code I`ve created a Default.aspx page and put all logic in Page_Load function. This function has additional keyword 'async' in the function signature because it needs to working with asynchronous calls. Inside that function body firstly HTTP client has been created to allow communication between web service and website. Secondly, to return JSON format from web service accept header need to be set to "application/json". Later in the code both endpoints are called by using build in asynchronous function GetStringAsync (JSON is always a string) - return type of the both calls is Task type. Next we need to wait until both until task complete and this functionality is provided by a built-in Task.WhenAll function with await keyword - code will block in this line until both task finish. When both requests completed results of the tasks need to be deserialized to a proper objects type by using DeserializeObject extension function and target types will be use as DataSource for the a page controls.

Last thing that needs to be done in Default.aspx is setting a new page property Async="true" to notify ASP.NET that page might handle asynchronous calls.

Code Snippet
  2. namespace AsyncPageWebsite
  3. {
  4.     using Contracts;
  5.     using System;
  6.     using System.Collections.Generic;
  7.     using System.Diagnostics;
  8.     using System.Net.Http;
  9.     using System.Threading.Tasks;
  11.     public partial class Default : System.Web.UI.Page
  12.     {
  13.         private HttpClient client;
  15.         protected async void Page_Load(object sender, EventArgs e)
  16.         {
  17.             // Creating HTTP Client for handling requests.
  18.             this.client = new HttpClient();
  20.             // Setting return type from web service to JSON format.
  21.             this.client.DefaultRequestHeaders.Accept.Add(new System.Net.Http.Headers.MediaTypeWithQualityHeaderValue("application/json"));
  23.             // Calling both services in asynchonous actions.
  24.             var getTeenRandomResultTask= this.client.GetStringAsync("http://localhost/AsyncPageService/api/random");
  25.             var getUsersListStringTask = this.client.GetStringAsync("http://localhost/AsyncPageService/api/user");
  27.             // Wait until all task finish.
  28.             await Task.WhenAll(getTeenRandomResultTask, getUsersListStringTask);
  30.             // Deserializing strings from tasks results.
  31.             var teenRandomResultList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<string>>(getTeenRandomResultTask.Result);
  32.             var userList = Newtonsoft.Json.JsonConvert.DeserializeObject<List<User>>(getUsersListStringTask.Result);
  34.             // Bind IEnumerable types to the proper controls.
  35.             rRandomNumbers.DataSource = teenRandomResultList;
  36.             gvUsers.DataSource = userList;
  38.             // Call the DataBind for whole page - cause call DataBind for each control on page.
  39.             this.DataBind();
  40.         }
  41.     }
  42. }

Thank you.

Source code is available here.

Read more: