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 = "https://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: https://localhost

URI: https://localhost/api/Users

HTTP method: GET

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

HTTP method: GET

Parameter: id - FromUri

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

HTTP method: GET

Parameter: id - FromUri

URI: https://localhost/api/Values

HTTP method: GET

URI: https://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.