ASP.NET Web API: Introducing IApiExplorer/ApiExplorer


IApiExplorer is an abstraction layer that allows you to obtain a description of the structure of your Web APIs. This information can be used to produce documentation, machine-readable metadata, or a test client.

ApiExplorer is the default implementation of IApiExplorer that inspects the routes and other Web API constructs to produce the description.

This feature is currently available as part of our ASP.NET Web API project on CodePlex.

Getting started

Since ApiExplorer is implemented as one of the built-in services, you can access it from the Services property in HttpConfiguration.

   1: var config = new HttpConfiguration();
   2: IApiExplorer apiExplorer = config.Services.GetApiExplorer();

Once you get back the ApiExplorer instance you can iterate through the ApiDescriptions and read the information you’re interested in. In the snipped below, I’m printing out the URI path, the HTTP method and the parameters of an API.

   1: foreach (ApiDescription api in apiExplorer.ApiDescriptions)
   2: {
   3:     Console.WriteLine("Uri path: {0}", api.RelativePath);
   4:     Console.WriteLine("HTTP method: {0}", api.HttpMethod);
   5:     foreach (ApiParameterDescription parameter in api.ParameterDescriptions)
   6:     {
   7:         Console.WriteLine("Parameter: {0} - {1}", parameter.Name, parameter.Source);
   8:     }
   9:     Console.WriteLine();
  10: }

Sample

In the sample below, we have a service setup with a default route “api/{controller}/{id}” and two controllers: Users and Values. Using the ApiExplorer, we’re going to print out the APIs for this service.

   1: using System;
   2: using System.Web.Http;
   3: using System.Web.Http.Description;
   4: using System.Web.Http.SelfHost;
   5:  
   6: namespace SelfHost
   7: {
   8:     class Program
   9:     {
  10:         static void Main(string[] args)
  11:         {
  12:             string baseAddress = "http://localhost";
  13:             HttpSelfHostConfiguration config = new HttpSelfHostConfiguration(baseAddress);
  14:             config.Routes.MapHttpRoute("Default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
  15:  
  16:             HttpSelfHostServer server = new HttpSelfHostServer(config);
  17:             server.OpenAsync().Wait();
  18:             Console.WriteLine("Server listening at: {0}", baseAddress);
  19:             Console.WriteLine();
  20:  
  21:             IApiExplorer apiExplorer = config.Services.GetApiExplorer();
  22:             foreach (ApiDescription api in apiExplorer.ApiDescriptions)
  23:             {
  24:                 Console.WriteLine("URI: {0}/{1}", baseAddress, api.RelativePath);
  25:                 Console.WriteLine("HTTP method: {0}", api.HttpMethod);
  26:                 foreach (ApiParameterDescription parameter in api.ParameterDescriptions)
  27:                 {
  28:                     Console.WriteLine("Parameter: {0} - {1}", parameter.Name, parameter.Source);
  29:                 }
  30:                 Console.WriteLine();
  31:             }
  32:  
  33:             Console.Read();
  34:         }
  35:     }
  36:  
  37:     public class UsersController : ApiController
  38:     {
  39:         public void Get() { }
  40:         public void Get(int id) { }
  41:     }
  42:  
  43:     public class ValuesController : ApiController
  44:     {
  45:         public string Get(int id) { return "value"; }
  46:         public string[] Get() { return new[] { "value1", "value2" }; }
  47:         public void Post(Value value) { }
  48:     }
  49:  
  50:     public class Value
  51:     {
  52:         public int Id { get; set; }
  53:         public string Text { get; set; }
  54:     }
  55: }

After running the sample, you should see the following API information printed to the console:

Server listening at: http://localhost

URI: http://localhost/api/Users

HTTP method: GET

URI: http://localhost/api/Users/{id}

HTTP method: GET

Parameter: id – FromUri

URI: http://localhost/api/Values/{id}

HTTP method: GET

Parameter: id – FromUri

URI: http://localhost/api/Values

HTTP method: GET

URI: http://localhost/api/Values

HTTP method: POST

Parameter: value – FromBody

Well folks, that’s it for today. On the next blog post, I’ll dive deeper into ApiExplorer and show you how to implement a simple help page.


Comments (6)

  1. James Hancock says:

    Is this new, or is it in the beta bits? I can't seem to get to GlobalConfiguration.Configuration.Services…

    Thanks!

  2. Yao - MSFT says:

    Hi James,

    Yes, this is new and not available in beta. But you can try it out using our CodePlex bits. See aspnetwebstack.codeplex.com/…/353867

    Henrik has a nice post on how to consume the package: blogs.msdn.com/…/using-nightly-nuget-packages-with-asp-net-web-stack.aspx

  3. Kavita Aggrawal says:

    HI i cant get configuration.services…. how i can get this dll???

  4. Yao - MSFT says:

    @Kavita

    This should be available in the RC release. Please find the download link here: http://www.asp.net/…/downloads

    If you have an existing project that's using the Beta release, please make sure you update the NuGet packages.

  5. jstaelens says:

    It would be nice if GetApiExplorer() would return duplicate records if the controller name is the same but namespace is different.  I have multiple controllers with the same name but a separated by their namespace so that we can have different versions of the same api in one assembly.  However the help page does not work with this.

    Or even better t would be nice if GetApiExplorer() accepted a namespace as a parameter.

  6. troy says:

    Note in the newer version, you need to get configuration thus:

    HttpConfiguration config = GlobalConfiguration.Configuration;