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.|
|Picture 2. Choosing proper MVC project template for API.|
- 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 http://foo.com/api/user/1 will return details for user with ID = 1 if we send a GET request.
- 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 serviceNow, 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<string, string> 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.
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:
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.