Saturday, 7 July 2018

ASP.Net Web API: Create, Deploy to Azure and Manage Using Azure API Management

Contents
  • Abstract
  • Introduction
  • Pre-requisites
  • Let's develop a simple ASP.NET WEB API
      Step: 1 Create ASP.NET WEB API Project
      Step: 2 Visiting Folder Structure
      Step: 3 Installing Fluent NHibernate Support
      Step: 4 Working on Models, Mappings and Repository Pattern
      • Adding Models and their Mappings
      • Adding Model Mappings
      • Adding Fluent NHibernate support to project
      Step: 5 Add WEB API Controller
      Step: 6 Set default result output type
  • Deploy our services to Azure
  • Working with AZURE MANAGEMENT

    • Create instance of API Management
    • Add an operation
    • Subscribe to our created API products
  • Discussing API MANAGEMENT Developer Portal
  • Testing APIs
  • Conclusion

Before start discussion, I would like to recommend following reading from my dear friend Sumit Jolly:
 
Abstract
This article explains the basics of Azure API Management to manage our Web API.
Introduction
This article explains all the basics of Azure Management to manage our Web API. Here we will not explain the Azure Management, how it works and how to create Virtual Machine, Create Cloud App and host Apps with Azure. Our focus is only on Managing Web APIs using Azure Management.
Here we will:
  • Create ASP.NET WEB API
  • Host/deploy our services to Azure
  • Manage our services using Azure API Management
Pre-requisites
To work with this article, we need:
  • Visual Studio 2013 or later (you can use the Community Edition).
  • SQL Server 2012 or later (you can use the Express Edition).
  • Basic knowledge of ORM (we will use FluentNHibernate in our demo app).
  • Basic knowledge of the ASP.NET WEB API.
  • Basic knowledge of ReSTful services.
  • A valid Windows Azure subscription (if you do not have one then you can get a one month free subscription).
Let's develop a simple ASP.NET WEB API
To work with this article we need WEB APIs, so, as a first step, let's develop a very simple web API using the following procedure.

Step 1: Create ASP.NET WEB API Project
To start we are using a simple ASP.Net project as in the following:
  • Start Visual Studio and select File -> New -> Project (or enter Ctrl + Shift + N).


  • From the available dialog choose Web Templates -> ASP.Net MVC 4 Web Application.
  • I named it "CRUDWithWebAPI"; you can choose your favorite one.
  • Select Empty Web API using Razor View Engine.



    (P.S.: Alternatively you can Select Create a unit test project, we are not discussing this topic here.)
Step 2: Visiting Folder Structure
After the preceding step, we will see that our project template is ready and the following is the default folder structure provided by the template:
  • App_Data
  • App_Start: contain config classes required to initiate the app (eg. route collection and so on.)
  • Controllers: controller of web API
  • Models: Contain model/classes
  • Scripts: all scripts and CSS
  • Views



    (P.S.: We are not going into more explanation of each and every folder, mentioned above, as it is beyond the scope of this article.)
Step 3: Installing FluentNHibernate Support
To install FluentNHibernate support to the project:
  • Open "Package Manager Console" using View -> Other Windows
  • Now type "Install-Package FluentNHibenrate" and hit Enter
Wait until FluentNHibernate has been installed.
Step 4: Working on Models, Mappings and Repository Pattern
In this step, we will create a Model and its mapping and will add a repository.
Adding Models and their Mappings
To add a model, right-click on the Models folder from the Solution Explorer and choose class and name it "ServerData".
  1. public class ServerData  
  2. {  
  3.     public virtual int Id { getset; }  
  4.     public virtual DateTime InitialDate { getset; }  
  5.     public virtual DateTime EndDate { getset; }  
  6.     public virtual int OrderNumber { getset; }  
  7.     public virtual bool IsDirty { getset; }  
  8.     public virtual string IP { getset; }  
  9.     public virtual int Type { getset; }  
  10.     public virtual int RecordIdentifier { getset; }  
  11. }  
Adding Model Mappings
Add its mapping class, right-click on the Models folder from Solution Explorer and choose class and name it "ServerDataMap".
  1. public class ServerDataMap : ClassMap<ServerData>  
  2. {  
  3.    public ServerDataMap()  
  4.    {  
  5.         Table("ServerData");  
  6.   
  7.         Id(x => x.Id, "Id").GeneratedBy.Identity().UnsavedValue(0);  
  8.   
  9.         Map(x => x.InitialDate);  
  10.         Map(x => x.EndDate);  
  11.         Map(x => x.OrderNumber);  
  12.         Map(x => x.IsDirty);  
  13.         Map(x => x.IP).Length(11);  
  14.         Map(x => x.Type).Length(1);  
  15.         Map(x => x.RecordIdentifier);  
  16.   
  17.    }  
  18. }  
Do not forget to add the following namespace:
  1. using FluentNHibernate.Mapping;  
Adding Fluent NHibernate support to project
  • Add a new folder and name it "Helper"
  • Add a new class beneath the "Helper" folder and name it "NHibernateHelper"
In this class we need to configure NHibernate and build all sessionfactory so, our application will interact with the database:
  1. private static void CreateSessionFactory()  
  2. {  
  3.    _sessionFactory = Fluently.Configure()  
  4.             .Database(MsSqlConfiguration.MsSql2008.ConnectionString(connectionString).ShowSql)  
  5.    .Mappings(m => m.FluentMappings.AddFromAssemblyOf<ServerData>())  
  6.            .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(falsefalse))  
  7.    .BuildSessionFactory();  
  8. }  
We will discuss all that stuff in details since they are beyond the scope of this article.
  • Create a new folder beneath "Models" and name it "Persistance"
  • Add one Interface "IServerDataRepository" under "Persistance"
    1. public interface IServerDataRepository    
    2. {    
    3.     ServerData Get(int id);    
    4.     IEnumerable<ServerData> GetAll();    
    5.     ServerData Add(ServerData serverData);    
    6.     void Delete(int id);    
    7.     bool Update(ServerData serverData);    
    8. }    
  • Add one class "ServerDataRepository" under "Persistance" and implement "IServerDataRepository"
    1. public class ServerDataRepository : IServerDataRepository  
    2. {  
    3.    //method implementation goes here   
    4. }  
Now, we are ready with our Repository to start playing.
P.S.: refer: msdn for more details on the Repository Pattern.

Step 5: Add WEB API Controller
In this step, we will add an API controller and will add all the necessary resources.
  • Right-click on the folder "Controllers" and add a new controller and name it "ServerDataController" (select an empty controller)
  • It would look like:
    1. public class ServerDataController : ApiController  
    2. {  
    3. }   
  • Add the following line of code (it will initiate our repository).
    1. static readonly IServerDataRepository serverDataRepository = new ServerDataRepository();  


    P.S.: Please note that in this article/demo we are not implementing any DI pattern or Inversion of Control (IOC) framework.
We all are set to go now:
  1. public IEnumerable<ServerData> GetServerData()  
  2. {  
  3.    return serverDataRepository.GetAll();  
  4. }  
In the preceding method, why we add a "Get" suffix, this is a good practice to add "Get" with your method name, by convention it maps to a GET request.
This method does not have any parameter, so, you can say this maps to a URI that does not contain an "id" parameter.
  • Add the following method to get ServerData by id. This is an optional parameter as defined in our route and the ASP.Net Web API framework automatically converts its type to an int.
  • It will throw a "HttpResponseExceptionexpception if it is not valid (in the following method we converted the exception to a 404 NOT Found exception).
    1. public ServerData GetServerDataById(int id)  
    2. {  
    3.     var serverData = serverDataRepository.Get(id);  
    4.     if (serverData == null)  
    5.         throw new HttpResponseException(HttpStatusCode.NotFound);    
    6.     return serverData;  
    7. }  
  • The following method gets ServerData by its type:
    1. public IEnumerable<ServerData> GetServerDataByType(int type)  
    2. {  
    3.    return serverDataRepository.GetAll().Where(d => d.Type == type);  
    4. }  
  • To invoke the preceding method we need to define new routes in "WebApiConfig.cs" as follows:
    1. config.Routes.MapHttpRoute(  
    2.    name: "ProductByType",  
    3.    routeTemplate: "api/{controller}/type/{type}"  
    4. );  
  • Similarly for:
    1. public IEnumerable<ServerData> GetServerDataByIP(string ip)  
    2. {  
    3.    return serverDataRepository.GetAll().Where(d => d.IP.ToLower() == ip.ToLower());  
    4. }  
    5. config.Routes.MapHttpRoute(  
    6.    name: "ProductByIP",  
    7.    routeTemplate: "api/{controller}/ip/{ip}"  
    8. );  
  • Here we will delete serverdata using this method:
    1. public void DeletServerData(int id)  
    2. {  
    3.    var serverData = serverDataRepository.Get(id);  
    4.    if (serverData == null)  
    5.    throw new HttpResponseException(HttpStatusCode.NotFound);  
    6.    serverDataRepository.Delete(id);  
    7. }  
  • Let's add a new method to our controller to add a new record of ServerData.
    1. public ServerData PostServerData(ServerData serverData)  
    2. {  
    3.    return serverDataRepository.Add(serverData);  
    4. }  
Will the preceding method work? Of course, it works but it's not an ideal solution or we can say it's not quite complete. Why is that?
  • In the preceding the suffix is "Post"; that sounds as if it sends a Http POST request.
  • Also its noticeable parameter is of type "ServerData".
  • Complex type parameters are deserialized from the requested body when we use the Web API; we can also say we expect serialized input from the client, like either in XML or JSON.
In the preceding method, we miss the following from the HTTP response:
  • Response code: by default it is 200 (Ok) but as per HTTP1.1 protocol, the server should reply 201 (created), whereas a POST request resuts in the creation of a resource
  • Location: the server should include the URI of the new resource in the location header of the response, whenever it creates a resource.
  • So, we can implement this as defined in the following methods:
    1. public HttpResponseMessage PostServerData(ServerData serverData)  
    2. {  
    3.    serverData = serverDataRepository.Add(serverData);  
    4.    var response = Request.CreateResponse<ServerData>(HttpStatusCode.Created, serverData);  
    5.    var uri = Url.Link("DefaultApi"new { id = serverData.Id });  
    6.    response.Headers.Location = new Uri(uri);  
    7.    return response;  
    8. }  
  • Finally, we need to add an update method, it's straightforward:
    1. public void PutServerData(int id, ServerData serverData)  
    2. {  
    3.    serverData.Id = id;  
    4.    if (!serverDataRepository.Update(serverData))  
    5.    throw new HttpResponseException(HttpStatusCode.NotFound);  
    6. }  
From the preceding, we can understand that the WEB API matches this method to a PUT request, the preceding method has two parameters, id and serverdata. So, it is taken from the URI path and the serverdata is deserialized from the request body.
P.S.: By default the Web API framework takes simple parameter types from the route and complex types from the request body.
Step 6: Set default result output type
We need a result in JSON by default, let's add the following line, either in the Global.asx.cs file or in the file where you are registering routes.
  1. //return JSON response by default  
  2. config.Formatters.JsonFormatter.SupportedMediaTypes.Add(new MediaTypeHeaderValue("text/html"));  
Deploy our services to Azure
Let's now deploy our preceding created services to our Azure server.
  • From Solution Explorer right-click and Publish.

  • We are deploying/publishing our ASP.NET WEB API as a Azure Website. So, we can get a robust endpoint; we will explain this in future sessions/articles.
  • And then click on Publish.


  • After a few minutes our WEB APIs will be available.
  • Check by browsing here



    Now, we have deployed our services, we need to set up the Azure API Management portal.
Working with AZURE MANAGEMENT
We are now ready with our WEB API to host/manage these with AZURE MANAGEMENT. If you do not have an Azure subscription then try a trial one from here.

Create instance of API Management
First, we need to create an API Management instance. Use the following procedure:
  • Log into your Azure Management portal from here: https://manage.windowsazure.com
  • If you do not have a subscription then get one from here: http://azure.microsoft.com/en-us/pricing/free-trial/
  • Click New, App Services, API Management, Create.


  • Now from NEW API MANAGEMENT SERVICE:


  • In the URL TextBox, specify a unique sub-domain name to use for the service URL.
  • Choose the desired Subscription and Region for your service instance. After making your selections, click the next button.


  • Enter an Organization name and E-mail id.


  • The API Management service instances that are available are Developer, Standard and Premium. By default, new API Management service instances are created using the Developer tier. To select the Standard or Premium tier, check the advanced settings checkbox and select the desired tier on the following screen.

    (P.S.: Premium is not available in promotional and free/trial accounts.)
  • Finally, click to create as in the following:


  • Here, we are on our API MANAGEMENT screen.


  • Click on MANAGE from the bottom of your dashboard.


  • To create our first API, click APIs from the API Management menu on the left and then click Add API.

In this screen, what did we do?
  • We provided a unique name for our API as "Demo" in the Web API Title TextBox. The Web API Title provides a unique and descriptive name for the API. It is displayed in the developer and management portals.
  • We provide an actual address where our WEB API is hosted, please refer to the preceding section, where we discussed the deployment of our WEB API to Azure. http://crudwithwebapi.azurewebsites.net/ into the Web service URL. Web service URL references the HTTP service implementing the API. The API management forwards requests to this address.
  • We provided a suffix as "demo" for our API. The Web API URL suffix is appended to the base URL for the API management service. Our APIs will share a common base URL and be distinguished by a unique suffix appended after the base.
  • The Web API URL scheme determines which protocol can be used to access the API. HTTPS is specified by default.
(P.S.: Here we selected both the HTTP and HTTPS protocols and I will explain this in future sections/series of articles.)
The API section has the following six tabs.
  • The Summary tab displays basic metrics and information about the API. 


  • The Settings tab is used to view and edit the configuration for an API, including authentication credentials for the back-end service. 


  • The Operations tab is used to manage the APIs.


  • The Security tab can be used to set Proxy Authentications using Basic and Mutual certificates or can be used to set OAuth 2.0; we will not discuss this in detail.


  • The Issues tab can be used to view issues reported by the developers using our APIs.


  • The Products can be used to create and manage products for our APIs; in this article we will be not be discussing this section.

Add an operation
  • Go to the Operation tab.
  • We did not create anything, so this tab will be empty.
  • Click on "Add Operation" to add a new API operation.
In our Web APIs we have the following resources:
  • Let's add our very first API resource as an operation in the API Management portal.

In the preceding screen, we specified:
  • HTTP verb as a GET, to retrieve the things.
  • URL template: our actual resource of Web API (as specified in the preceding table).
  • For this operation we did not have any Request parameters, so there is no need to define any.
  • Note that we can provide parameters as a query parameter or Body.
  • Under RESPONSES we select HTTP STATUS code 200 (that is "OK"); it means that everything went fine, it will return the specified application/json format.
We are done with our APIs work. We have hosted our Web API with Azure API Management. They are now ready to be used or consumed by developers.
Developers will use the Azure API Management developer portal to use/see all the APIs related documentations.

Unfortunately, we have not yet registered any user as a developer, let's use the following procedure to register our API products.

(P.S.: we will discuss this in a future session; that is, how to set up various products and mange users with the Azure API Management.)

Subscribe to our created API products
To create subscribers, we can do it by invitation and with the use of the Administrator Portal of API Management.


Here, we are using the Developer portal where we have already invited/shared our development portal links to our end-users or targeted audience for development.

Discussing API MANAGEMENT Developer Portal
This section briefly explains the Developer portal.


This will be the default Home page for every developer. Developers can go through the app APIs documentation, your API Blog (if created) and other applications (if you are providing any for any Product).
Since we are not going into details of the Developer Portal, let's sign up as a Subscriber.
  • Click on SIGN IN from the top-right.
  • From the Sign In page (since we have not registered yet) click on Sign up now.

  • Enter all the specified details and click on Sign up.

  • You need to verify your email.


  • After verification of your email, Log In to the developer portal then click on the API link.


  • Subscribe to a Product.

  • From the Administrator Portal click Users and approve the subscription for the user.


  • Click on the Demo API from Developer Portal.
  • Here you will get all the APIs listed under Demo.


  • Click on the first Get ServerData.

  • Here you can see that our Request URL requires a subscription-key that is nothing but our Primary/Secondary API key, provided by Azure API MANAGEMENT as per subscription.
Testing APIs
We can test our hosted APIs via an external Client or using the Console from within the API Developer Poartal.
  • Click on Open Console from the current Get ServerData API.
  • Here you should need an API key, select either Primary or Secondary.


  • After hitting HTTPGET (this is a GET Resource) you will get the related output.





    We are done with everything to manage the Web API with Azure API Management.
Conclusion
This article explained the creation of an ASP.NET Web API, hosting to Azure and management using the Azure API Management.
In future sessions/articles we will explain more about advanced topics/features of Azure API Management.
The complete source code is available at: Github.

1 comment:

  1. http://www.technicalblogs.sentientmindz.com/2017/04/16/manage-the-web-api-using-azure-api-management/

    ReplyDelete