ASP.NET Web API <#= Proxy to T4 #>

Sunday, March 10, 2013

One of the coolest new features of ASP.NET is Web API, which allows you to build powerful RESTful services exposed over HTTP. HTTP is not just for serving up web pages, but it provides a platform for building APIs that expose services and data. It is simple, flexible, and ubiquitous.

ASP.NET Web API is all about REST HTTP Services. Unlike Web Services, it does not expose an end-point for meta-data exchange. When consuming a HTTP Service, you will have to create your own client-side code that must serve as a proxy for interfacing with the API.

Like any other WCF junkie out there, I've been working with Windows Communication Foundation for quite some time now implementing Web Services. Not only is it flexible and extensible, but it offers inter-operability, multiple message patterns, transactions and  meta-data exchange etc.

The nice thing about WCF is meta-data exchange, which allows you to generate the client-side proxy-code, contracts and classes used for talking to the service. On the other hand, ASP.NET Web API is more light-weight, operates only via HTTP and is used more for serving CRUD-based operations. The latter, however, does not have functionality (yet) for exposing service meta-data. Until now...


Update: Use WebApiProxy with your ASP.NET Web API 2 service for a metadata provider and generate JavaScript & C# proxy clients. More here...

T4 to the rescue

As an API developer, I want to be able to use ASP.NET Web API for it's light-weight footprint as well as exposing some kind of meta-data exchange mechanism, which is not currently supported out of the box. This is where T4 templates come into play.

While playing around with the Text Template Transformation Toolkit (T4, hence the four T's), I realized that I can actually build generic T4 templates (that is delivered via a mechanism like Nuget) and then generate the API's proxy code (C# and JavaScript) based on certain settings.

The settings file contains a list of end-point URLs that the T4 template should crawl and download the meta-data for.

The API

For the concept, I built an API that feeds basic people information. It needs to be called from any REST-based client and must be able to provide meta-data (like web services) to the consumers.

To have my API feed this type information, I've created the following classes:
  • ExposeProxyAttribute - used to mark the endpoints for metadata generation.
  • TypeRetriever - responsible for extracting all the types used in the API marked with the ExposeProxyAttribute.
  • ContractInfo - the model that houses the metadata which describes information like classes and methods.

MexApiController

This is the base class for the MEX (Metadata Exchange) enabled API Controller. Every class (controller) that inherits from this, will receive an extra GET endpoint with a ?metadata identifier, i.e. /api/people?metadata


PeopleController

Here is a normal Controller called PeopleController. It inherits the MexApiController which will enable the metadata endpoint for /api/people. 

So now we have the following endpoints:

  • GET /api/people - Gets a list of People
  • GET /api/people/2 - Gets one Person with Id 2
  • POST /api/people - Creates a new Person
  • PUT /api/people/2 - Updates Person with Id 2
  • DELETE /api/people/2 - Deletes Person with Id 2
  • GET /api/people?metadata - Retrieves the metadata for the People API as a ContractInfo model response.
Testing the API gives me the following result:

GET /api/people


Notice that only the end-points decorated with ExposeProxy are included in the meta-data response:

GET /api/people?metadata

The client side

Now that I have MEX end-points that give me all the meta-data for a API, I tell my T4 template to make sense of it all using the settings and generate the appropriate C# and/or JavaScript code to use the service.

Here are the files I've used:

The WebApi.CSharpProxy.tt and WebApi.JavaScriptProxy.tt generates C# and JavaScript based on the configuration given in the WebApi.Proxy.config file. The WebApi.Proxy.Core.tt contains infrastructure code specifically for the T4 template.

Examining the WebApi.Proxy.config:

As you see, the settings allow for multiple proxies. In each proxy you can specify the metadata identifier and the resource suffix. A list of applicable resource end-points are defined to tell the generator to only generate the code for specific resources.

This makes consuming my REST-based API a breeze with cool intellisense:




Also generating JavaScript? This got me thinking...

Most of my API calls will originate from HTML apps. So instead of having the JavaScript guys generate their own proxies, why not do it for them?

So, I ended up adding another endpoint to my API called ProxyController that merely just relays the generated JavaScript file from the T4 template to the client, as a JavaScript file.





Now, from the client HTML-based app, adding a reference to my JavaScript proxy end-point will get the latest JavaScript code to use my API.

Reference in the HTML file:
<script type="text/javascript" src="http://myapiservice.net/api/proxy"></script>

This will expose the proxy code to the rest of the client-side scripts. This allows us to use it like:


Done and Done

After all this, I seriously felt like an API ninja. I wouldn't be surprised if the ASP.NET team brings out a similar feature in the near future. Although this is just a proof of concept, my aim is to round-it off a bit more and deploy it to Nuget. Also be on the lookout for the source-code soon to be on GitHub.

Thats all folks! Please follow me on Twitter @FanieReynders and feel free to ask any questions regarding this.

17 comments

  1. This is great stuff. I've only done some consuming of SOAP but I found the generation of client classes really nice. Now, starting to working against RESTful service it feels like going back years in (developer) time and doing plumbing work from scratch again.

    ReplyDelete
  2. This is awesome when is this going to be available for dl?

    ReplyDelete
    Replies
    1. Hi MJ, you can find more information on this here. It has been released and is open source :) http://www.faniereynders.com/2014/01/introducing-webapiproxy-providing.html

      Delete
  3. Work in progress... Subscribe to my feed if you want to be notified once it's published

    ReplyDelete
  4. Is there any reason why you can't use the Bundling API to hand out the javascript file rather than having to create the proxy controller?

    ReplyDelete
  5. Not at all. The proxy controller is just a transfer mechanism to get the generated JavaScript to the client. I just chose this method to standardize any ASP.NET Web API with the same route to the proxy without you actually having to do it yourself.

    ReplyDelete
  6. ASP.NET Web API Help page, which is released in recent 'ASP.NET and Web Tools 2012.2 Update' provides API documentation.

    http://nuget.org/packages/Microsoft.AspNet.WebApi.HelpPage/

    Can't envisage your solution adds any value.

    http://weblogs.asp.net/sukumarraju/default.aspx

    ReplyDelete
  7. The main aim of this solution is to allow automatic proxy generation for ASP.NET Web API in C# and JavaScript. It is not for document generation. I am aware of the link provided for the documentation generation :).

    Thanks for the input however.

    ReplyDelete
  8. Hello! Great Job! What is the estimated date of beta/release version?

    Regards

    ReplyDelete
  9. Hello! Great Job! What is the estimated date of beta/release version?

    Regards

    ReplyDelete
    Replies
    1. Hi Eduardo, its finally here! Check out the introductory blog post over at http://www.faniereynders.com/2014/01/introducing-webapiproxy-providing.html and its also available on Nuget - https://www.nuget.org/packages/WebApiProxy and https://www.nuget.org/packages/WebApiProxy.CSharp/

      Any suggestions welcome.

      Delete
  10. Nice information you shared regarding .NET technologies and I think everyone should remember.
    hire a PHP developer | hire a ASP.NET developer

    ReplyDelete
  11. This comment has been removed by the author.

    ReplyDelete
  12. For those that are interested, I've pushed the initial release to source control. Feel free to send me a pull request - https://github.com/faniereynders/WebAPIProxy

    ReplyDelete

Community

Popular Posts

Archives

About Me

My Photo

I'm a Microsoft Certified Professional from South Africa. Being a web technology evangelist in my own right, I've been developing on the Microsoft stack for over 9 years and writing about technical lingo for the past 2 years. Follow me on Twitter @FanieReynders