Your API

Build a RESTful API & share it with the world. Part 2


In Part 1, I discussed a business case and implementation analysis when moving forward with developing an API for your organization.

This second part will cover the technical side of your Restful API. This technical discussion will revolve around an open source RESTful API Starter Kit called WebApiSoup. Let me take a moment to touch on some of the technologies used to support this Starter Kit:

Download the Source via from GitHub or just the Zip

  • ASP.NET MVC 4 WebAPI with Help Pages
  • Entity Framework 5, Code First
  • The WebMatrix SimpleMembership Implementation
  • MD5 hashing for Authentication
  • Custom Auth Message Delegate Handler
  • API Metering Management


Along with the default features you get with visual studio’s ASP.NET MVC4 WebApi template, this project has the following additional features:

  • Membership Provider: WebMatrix membership is already coded and running along side the WebAPI’s custom user profile
  • User & Application Support: Entity Framework 5 (Code First) is used to define and persist User profiles and “API Applications” those users have registered with your RESTful API.
  • Token Based Security: No need to worry about building your own RESTful API request authentication. WebApiSoup employs MD5 encryption using a Application Identifier along with a Application Secret.
  • Application Request Limiter: Need to keep track of your user’s RESTful API request count. Out of the box this solution will support custom daily request limits, monthly request limits or no limit at all.
  • Taste Test The Soup: No project is complete with out code samples of how a client would use this API. This test project demonstrates how to generate a token, assemble the request authorization headers and communicate to your HTTP endpoint

Membership, Roles and API Applications

This application accomplishes two objectives: To add user security (Membership) and to support multiple API’s access instances per account. One common feature developers need is different API accounts and keys for different environments or applications. This is why WebAPISoup has implemented such a feature. It support a user account to have multiple API Application accounts with their own API Identifiers and private keys.

Below are examples from the initial configuration data seeding in the Starter Kit. Snippets from Configuration.cs

Create a user

WebSecurity.CreateUserAndAccount("", "admin1");

Add User to Role

Roles.AddUsersToRoles(new[] { "" }, new[]    { Constants.ROLES_ADMINISTRATOR });

Add an Application to User

NOTE: This also displays how to define the application rate limits.

    //Get the User Profile
            int userId = WebSecurity.GetUserId("");
            Repository.UserProfile profile = context.UserProfiles
                                            .Where(w => w.UserId == userId)
            //Add a new Applicaiton to the user
            profile.Applications.Add(new Application()
                ApiAccessMetricLimit = Common.Constants.API_ACCESS_METRIC_NO_LIMIT,
                SubscriptionType = Common.Constants.API_SUBSCRIPTION_TYPE_NO_LIMIT,
                CreateDtm = DateTime.UtcNow,
                LastDtmAccessed = DateTime.UtcNow,
                AppGeneratedSecret = Security.HashSecurity.GenerateAppSecret(),
                AppGivenName = "First App"

Token Based Security

This starter kit employs authentication on each request. This is done with an MD5 hash of your API ID, API secret and the UNIX Time stamp and added to the AppToken Header Key while the AppId Header should contain the API ID.

This authentication method is the same used by Mashery’s Authentication. There is also a test application in the repository called TestTasteTheSoup that demonstrates how to create an auth token to be passed to the server. If your organization needs to provide a resource based authentication/authorization you will need to use something like OAuth instead.

Implementation on the Client, snippet from WebApiSoupTest.cs:

    HttpClient client = new HttpClient();
    HttpRequestMessage msg = new HttpRequestMessage(HttpMethod.Get, 
                                                     new Uri("http://localhost:58720/api/SoupRecipes/PerformHandshake"));
    // Add an Accept header for JSON format.
    client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
    msg.Headers.Add("AppId", firstAppId);
    msg.Headers.Add("AppToken", CreateToken(firstAppId, firstAppSecret));

    HttpResponseMessage response = client.SendAsync(msg).Result;
    string responseAsString = response.Content.ReadAsStringAsync().Result;
    if(response.StatusCode != System.Net.HttpStatusCode.OK)
         //There was a problem
         Assert.Fail(String.Format("Failed with code: {0}", response.StatusCode));

    private string CreateToken(string applicationId, string secret)

        string retVal = string.Empty;
        string tm = ((int)(DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalSeconds).ToString();
        string toEncrypt = string.Format("{0}{1}{2}", applicationId, secret, tm);
            return md5hex(toEncrypt);
        catch (Exception ex)
            throw ex;

    private string md5hex(string str)
        MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
        byte[] data = Encoding.Default.GetBytes(str);
        byte[] hash = md5.ComputeHash(data);
        string hex = "";
        foreach (byte b in hash)
            hex += String.Format("{0:x2}", b);
        return hex;

On the server side, you will notice in the AuthMessageHandler it will inspect the HTTP message for the appropriate authentication artifacts. It will either return a 200 (OK), 427 (Too many requests), 401 (Unauthorized) or 403 (Forbidden).

        if (DoesHaveAppId && DoesHaveAppToken)
            if (Guid.TryParse(appIdValues.FirstOrDefault(), out AppIdGuid))
                principal = ValidateAuthentication(AppIdGuid, appTokenValues.FirstOrDefault());
                if (principal != null) //Valid User
                    System.Threading.Thread.CurrentPrincipal = principal;
                    if (IsAppOverLimit(AppIdGuid))
                        responseCode = (HttpStatusCode)429;
                else//User failed to authenticate
                    responseCode = HttpStatusCode.Unauthorized;
        else//User didn't supply Key/Token
            responseCode = HttpStatusCode.Forbidden;

Application Request Limiter

Another common feature you will find when consuming an API is your usage allowance. This allowance provides a mechanism to limit your users to X number of calls over a given period. If you provide your service for free, you will want to police the usage to ensure some users don’t degregate the service for the rest of your users.

I have implemented a such a feature by counting requests made in a given time period. These counts are recorded against the App Id submitted during authenticating. If the App is over the limit for the defined time period then a HTTP Response code of 429 is returned (Too Many Requests).

Below is the method found in the AuthMessageHandler that handles checking the subscription type, if it is over the limit and increments the request count if it is below the limit:

    private bool IsAppOverLimit(Guid AppId)
        using (var context = new Repository.RepoContext())
            Repository.Application app = context.Applications.Where(w => w.ApplicationId == AppId).FirstOrDefault();
            if (app != null)

                switch (app.SubscriptionType)
                    case Common.Constants.API_SUBSCRIPTION_TYPE_NO_LIMIT:
                    case Common.Constants.API_SUBSCRIPTION_TYPE_DAILY_RESET:
                        if (app.LastDtmAccessed.DayOfYear < DateTime.UtcNow.DayOfYear)
                            app.ApiAccessMetricCurrent = 1;
                        if (app.ApiAccessMetricCurrent >= app.ApiAccessMetricLimit)
                            return true;
                    case Common.Constants.API_SUBSCRIPTION_TYPE_MONTHLY_RESET:
                        if (app.LastDtmAccessed.Month < DateTime.UtcNow.Month)
                            app.ApiAccessMetricCurrent = 1;

                        if (app.ApiAccessMetricCurrent >= app.ApiAccessMetricLimit)
                            return true;

                app.LastDtmAccessed = DateTime.UtcNow;
        return false;

Pipeline.AuthMessageHandler – Use to decorate API methods that require Token Authentication also records API requests. Snippet from WebApiSoup / WebApiSoup / App_Start / WebApiConfig.cs

            name: "DefaultApi",
            routeTemplate: "api/{controller}/{action}/{id}",
            defaults: new { id = RouteParameter.Optional },
            constraints: null,
            handler: HttpClientFactory.CreatePipeline(
                      new HttpControllerDispatcher(config),
                      new DelegatingHandler[] { new Pipeline.AuthMessageHandler() })


Download the Source via from GitHub or just the Zip

Posted in API, SOA and tagged , , , , , , , .