In this series, I’m exploring a variety of ways to build back-end data storage and services for Windows 8 apps (many of which, BTW, can also be used for other mobile and web apps as well). Here are the posts so far:
Overview – High-level view of some of the available platform technologies, and a discussion of the game leaderboard scenario I’m using to demonstrate them, as well as the games I’m using for my demos.
## Overview
In this post, I’m going to show you how I can implement the same leaderboard service using a relatively new member of the ASP.NET stack, Web API. Web API is designed specifically for building services that are accessed via HTTP, and is a lightweight, yet highly customizable way of building RESTful services, and even supports OData as well. I’ll also show you how easy it is to host services built using ASP.NET Web API using the new Windows Azure Web Sites feature.
For the sake of simplicity, I’m going to leverage the same database schema that I created in part 1 of the WCF Data Services-based solution, and will also leverage Entity Framework for modeling the data. If you have not already, you should <a href="https://devhammer.net/blog/building-back-end-data-and-services-for-windows-8-apps-odata---part-1" target="_blank">read through the sections entitled “Creating the Database” and “Creating the Schema” in that post</a>, before moving on. I’ll wait.
## Preparing a Home for our Web API
Since the last project showed how I was able to host a WCF Data Services-based OData service using a Windows Azure cloud service, this time I’m going to do things a little differently and host my Web API using <a href="http://www.windowsazure.com/en-us/home/scenarios/web-sites/" target="_blank">Windows Azure Web Sites</a>, a new offering (still in preview as of the time of this writing). As with cloud services, you will need a Windows Azure account to follow along. If you don’t have one, <a href="http://bit.ly/Azure90" target="_blank">you can get a 90-day free trial account</a>.
Creating a Web Site in Windows Azure is simple. I just log into the management portal, and click on the Web Sites tab. Since I don’t have any web sites yet, this is what I’ll see:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="AzureWebSites_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="AzureWebSites_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/AzureWebSites_2_thumb.png?resize=660%2C335" width="660" height="335" />][1]
Next, I’ll click the link to create a web site, which prompts me with some options for how I’d like to create my web site:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="AzureWebSiteOptions_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="AzureWebSiteOptions_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/AzureWebSiteOptions_2_thumb.png?resize=660%2C285" width="660" height="285" />][2]
Note the reminder that the service is (as of this writing) in preview, and the options for quick create, creating with a database, and creating from the gallery (a great option for when you want to stand up a site based on one of the many web apps available from the <a href="http://www.microsoft.com/web/gallery/categories.aspx" target="_blank">Windows Web App Gallery</a>, such as DotNetNuke, Umbraco CMS, <a href="http://orchardproject.net/" target="_blank">Orchard CMS</a>, or WordPress). I’m going to choose Create with Database. This prompts me with the following dialog, which I’ve filled out with my desired web site URL (note that I’m using the free version of the service, which uses the naming pattern [mysitename].azurewebsites.net. (NOTE: You can configure your web site to use a custom domain name, but this requires switching the site to Shared or Reserved mode, which may have cost implications) Additionally, I’m specifying that I want to create the site in the East US region, and create a new database. I’ve left the connection string name as the default:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="CreateWebSite_1_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="CreateWebSite_1_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/CreateWebSite_1_2_thumb.png?resize=660%2C437" width="660" height="437" />][3]
When I click the arrow for “next,” I see page 2 of the Create Web Site wizard, where I provide the database settings for the new database (I’m using the same database server as for my previous project, so my login information remains the same):
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="CreateWebSite_2_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="CreateWebSite_2_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/CreateWebSite_2_2_thumb.png?resize=660%2C437" width="660" height="437" />][4]
Next, I’ll click the checkmark, and let Windows Azure spin up my new website. It takes just a few minutes, and then I’m all set.
## Creating a Web API Project
I’ll start off similarly to the WCF Data Services project, using Visual Studio 2012, but this time, I’ll start with an ASP.NET MVC4 Web Application using Visual C#. I’m calling the project GameLeaderWebAPI (_note that I’ve specified .NET Framework 4.5 as the version for my project_):
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="NewProjectWebAPI_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="NewProjectWebAPI_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/NewProjectWebAPI_2_thumb.png?resize=660%2C456" width="660" height="456" />][5]
Once I click OK, I’m greeted with a dialog that prompts me to select the specific [ASP.NET MVC][6] 4 template I want to work with. If I wanted to create a full MVC site with a Web API service, I’d select the Web API template, but for my current purposes, that template has a number of things I don’t need (like views, for example), so I’m going to start with the Empty template, as shown below:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="NewProjectWebAPI_2_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="NewProjectWebAPI_2_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/NewProjectWebAPI_2_2_thumb.png?resize=660%2C598" width="660" height="598" />][7]
Since I’m not planning on having any views, it doesn’t really matter which view engine I choose, so I’ve left the default. When I click OK, Visual Studio creates the project for me, with folders appropriate for MVC, along with all the necessary configuration for my Web API, but without all of the default controllers and views I’d get with the Web API template. Here’s what the project looks like in Solution Explorer at this point:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="EmptyProjectSolutionExplorer_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="EmptyProjectSolutionExplorer_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/EmptyProjectSolutionExplorer_2_thumb.png?resize=223%2C352" width="223" height="352" />][8]
Before I start adding any models or API controllers, I want to make sure I’m ready to support OData in my Web API, which is currently accomplished through a nuget package. To get the package, I’ll open up the Nuget Library Package Manager using Tools > Library Package Manager > Manager Nuget Packages for Solution… (note that at the time of this writing, the Web API OData package is in alpha release, so you’ll need to choose “Include Prerelease” in the leftmost drop-down, as shown below, to see the package) and search for “Web API OData”. Once I find the package, I simply click the Install button and click through the prompts to finish the install:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="NugetWebAPIOData_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="NugetWebAPIOData_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/NugetWebAPIOData_2_thumb.png?resize=660%2C440" width="660" height="440" />][9]
Now, it’s important to note that you don’t need to do this to create a RESTful service with Web API. But since my previous example leveraged OData for its rich URL query functionality, I’d like to maintain that in my Web API version.
## Adding the Model
Now that the project is set up, I want to add a model, and connect it to my back-end database. As noted earlier, I’m planning to use the same schema as in the <a href="https://devhammer.net/blog/building-back-end-data-and-services-for-windows-8-apps-odata---part-1" target="_blank">previous post on WCF Data Services</a>, so before adding the model, I created a table named GameScores in the database I created earlier, and added columns for Id, Game, Player, Score, Wins, Losses, and Ties. Note that in my WCF Data Services version, I had named the table Scores, which didn’t play nicely with Entity Framework, due to the fact that the table had a column name that was the singular version of the table name, which caused EF to rename the column to Score1, which was a little confusing when querying, to say the least. With the schema in place, I can simply add a new ADO.NET Entity Model to the Models folder, and point it at my database (again, see the <a href="https://devhammer.net/blog/building-back-end-data-and-services-for-windows-8-apps-odata---part-1" target="_blank">previous post for details on this</a>) and my model is ready to go:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="GameScoresModel_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="GameScoresModel_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/GameScoresModel_2_thumb.png?resize=148%2C228" width="148" height="228" />][10]
I’ve seeded the GameScores table with some data to make the remaining tasks easier. I did so manually, but if you want to automate the process (for example if you want to use Entity Framework Migrations), Entity Framework supports seeding your tables automatically when you update them (<a href="http://msdn.microsoft.com/en-US/data/ef" target="_blank">read more about Entity Framework here</a>).
## Defining the API
Now that my model is in place, it’s time to create the API, which is done by simply adding an API Controller, which is a specialized type of MVC controller specifically for Web API. It’s how we create the endpoints and logic to handle all of the HTTP requests for our API. Visual Studio 2012 provides great scaffolding support for automating the process of creating an API Controller, but I need to build the project in order for the scaffolding to find my model class. Once the project is built, I’ll just right-click the Controllers folder, and select Add > Controller… and specify the Model class and Data context class, as well as the name for my controller:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="AddController_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="AddController_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/AddController_2_thumb.png?resize=604%2C393" width="604" height="393" />][11]
Note that if you see an error message indicating that no Model classes are available, you need to build the project and try adding the controller again.
When I click Add, Visual Studio scaffolds the API Controller for me, including creating the underlying data context and creating functions for the basic CRUD operations, and my service is ready to test. But if I click the start button in the toolbar to open the site in Internet Explorer, here’s what I see:
[<img data-recalc-dims="1" loading="lazy" decoding="async" title="404_2" style="border-top: 0px; border-right: 0px; background-image: none; border-bottom: 0px; padding-top: 0px; padding-left: 0px; border-left: 0px; display: inline; padding-right: 0px" border="0" alt="404_2" src="https://dhcontent.blob.core.windows.net/images/2015/06/404_2_thumb.png?resize=660%2C430" width="660" height="430" />][12]
Oops! Turns out, there’s a good reason for this. Remember how I started this project using the Empty template? Well, there aren’t any views associated with the project, so there’s nothing for me to see at the root URL. Thankfully, the API Controller that I scaffolded helpfully includes comments with the correct path to append to get to a given API member, as you can see below for the GetGameScores function:
<div class="csharpcode">
<pre class="alt"><span class="lnum"> 1: </span><span class="rem">// GET api/Scores</span></pre>
2: public IEnumerable<GameScore> GetGameScores()
3: {
4: return db.GameScores.AsEnumerable();
5: }
If I append api/Scores to the URL shown above, I’ll be prompted to open or download a file named Scores.json, which contains the response from GetGameScores (which defaults to JSON format, though Web API supports content negotiation as a means of supporting additional formats).
We’re not quite done with the API, however…recall that I wanted to add some basic OData support as well.
Adding OData Support
You might think, given how simple the function GetGameScores is, that we have to do a lot of tweaking to make our API support OData query syntax. In truth, the basic level of support is super-easy to add. All I have to do is modify the GetGameScores function as follows:
1: // GET api/Scores
2: [Queryable]
3: public IEnumerable<GameScore> GetGameScores()
4: {
5: return db.GameScores.AsEnumerable();
6: }
If you blinked, you might have missed the change. All I needed to do was add the [Queryable] attribute (which is provided by the Nuget package I installed earlier), and now my API supports OData URL queries like $filter, $orderby and more. So a query like this:
http://localhost:55830/api/Scores?$orderby=Score
returns all scores ordered by score (ascending by default…just tack on a space and “desc” to get descending results…note that if you’re doing this in the browser, you should use %20 for the space). And this query:
And with that, my Web API service is good to go…on to deployment.
Publishing a Site to Windows Azure
As with the example I build on WCF Data Services, I could start integrating my service with the games running the service locally, but I’m going to go ahead and publish the site first, so that I can use the Windows Azure version of the URL for the service.
To publish, all I need to do is right-click the project in Solution Explorer, and select Publish…, which will open the following dialog:
I’m going to import my publishing profile, which comes in the form of a .PublishSettings file, but first I need to download this from the Windows Azure management portal page for my website, by clicking the link highlighted below in the “quick glance” section of the Web Sites page for my Azure web site:
Once I’ve saved the file to my PC, I can go back to the Publish Web wizard and import it by clicking the Import button, selecting the file, and clicking the Open button. This will import the settings for my web site. I can click Next to view additional settings, including information on my database, and click Publish to publish my website to Windows Azure.
Using the API
Once published, I can simply make HTTP requests to the URL for my website, using the following URLs and HTTP verbs:
Getting all Scores
http://[myAzureWebsiteUrl].azurewebsites.net/api/scores – HTTP GET request
where “myAzureWebsiteUrl” is the unique portion of the URL for the published site.
Note that we can also use OData queries to return a single unique score, assuming we have the game and player name we’re looking for, and the game only stores one unique score per player.
Getting a Single Score
http://[myAzureWebsiteUrl].azurewebsites.net/api/scores/5 – HTTP GET request
where 5 is the ID of the score record to return.
Updating a Score
http://[myAzureWebsiteUrl].azurewebsites.net/api/scores/5 – HTTP PUT request
Note that the URL is the same as getting a single score, with the last portion being the ID of the score to update, we simply change to using a PUT request, and provide the score object in the body of the request (by default, the API accepts JSON, but you can update it to support additional formats).
Inserting a Score
http://[myAzureWebsiteUrl].azurewebsites.net/api/scores – HTTP POST request
The URL is the same as for getting all scores, but uses the POST verb instead of GET. Again, we need to pass the score object in the body of the request as JSON.
Deleting a Score
I won’t make use of this API in the game clients, but here’s how to delete a score entry:
Because everything in the API uses standard HTTP verbs, our API has great usability and fidelity to the way the web works.
Wiring up the Leaderboard Clients
Since I’ve already walked through once the process of wiring up the leaderboard service to the games, I’m going to make this a quicker version, and refer you back to part 2 of the WCF Data Services version for additional details.
To wire the games up to the Web API version of my leaderboard service, it made sense to start with the JavaScript file I created for the WCF Data Services version, and modify it as needed to work with the new service. The updates required very few changes to the code, and allowed me to maintain a completely compatible interface between the leaderboard JavaScript library and the games. As a reminder, here’s what the leaderboard JavaScript library exposes to the game client(s):
1: WinJS.Namespace.define("Leaderboard", {
2: setPlayerName: setPlayerName,
3: init: init,
4: addWin: incrementWins,
5: addLoss: incrementLosses,
6: addTie: incrementTies,
7: updateScore: updateHighScore,
8: getTopTenScores: getTopTenScores,
9: getTopTenWins: getTopTenWinLossTie,
10: leaderboardList: leaderboardList
11: });
By using the namespace support in WinJS, I can hide the internals of my service behind a consistent set of functions, which makes it easy for me to switch from one back-end service to another.
Here’s the full listing for the new leaderboard service library, which I’ve called leaderboardWebAPI.js (I’ve highlighted the changes, and will walk through them one by one below the listing):
240: leaderboardList = new WinJS.Binding.List(scores);
241: completed(leaderboardList);
242: }
243: },
244: function (e) {
245: showMessage(e);
246: }
247: );
248: }
249: );
250: }
251:
252: function showMessage(msg) {
253: diag = new Windows.UI.Popups.MessageDialog(msg);
254: diag.showAsync();
255: }
256:
257: })();
Here are the changes I made from the WCF Data Services version:
Line 44, in the init function (which initializes the leaderboard data for a given game), modified the baseUri property of the leaderboardClient object to reflect the updated URL for the service
Line 58, updated the syntax by which I test for a valid return value from the xhr call, owing to differences in how WCF Data Services and Web API return the results
Line 61, updated the name of the Score property of the gameScore object. In the previous version, this was Score1 due to the aforementioned conflict between my database table name and how EF deals with pluralizing/singularizing objects and their properties
Lines 100 and 105, in the function getCurrentPlayerScore (which returns the first score for the given player and game), updated the syntax by which I test for and assign the value returned from the xhr call, again due to differences in how Web API returns the results.
Lines 123, 127, 128, and 132, in function setPlayerName (only used by Space Cadet, to update the player name if required by the game), updated the way that I add the data to the xhr request, to include the entire object (the WCF Data Services version used a custom HTTP verb, MERGE, which allowed the service to update the score record with just the new playerName as the data). Also changed the HTTP verb to PUT, as required by Web API for updates, and modified the URL for the xhr request to match that of the Web API (i.e. – /api/scores/id). Also added code to update the query property of the leaderboardClient object to include the updated playerName, fixing a bug in the previous version of the library
Lines 171 and 172, in function updateHighScore (which gets the current score record for the player/game, and calls another function to update the leaderboard), updated the property name from Score1 to Score, again, to match updates to my EF model
Lines 184 and 185, in function updateScoreRecord (called by updateHighScore, and which sends the updated score to the service), changed the HTTP verb to PUT (removing the header that specified the custom MERGE verb), and modified the URL to reflect the syntax required by Web API
Lines 200, 207, and 212, in function getTopTenScores, updated the naming of Score1 to Score, and the syntax by which the object returned from the xhr call is tested and passed to the constructor for WinJS.Binding.List
Lines 235 and 240, in function getTopTenWinLossTie, same as above.
As you can see, the list of needed changes was quite short.
One other change that I needed to make was in the HTML file for the leaderboard in Space Cadet, which uses databinding to display the score on the leaderboard, like so:
Notice, on line 6, that the textContent property of the second span is being bound to the value “Score”. In the WCF Data Services version, this was “Score1”.
With the leaderboard library for Web API complete, now all I need to do is update the HTML pages for the game client and leaderboard pages to use the new version of the library, like so:
Now I can run the game (in this case, Space Cadet), and here’s what I’ll see if I beat my previous high score:
which tells me that my service is working properly. But just to be sure, I’ll check the leaderboard as well:
The data (minimal though it may be) reflects what’s in the database, so it’s looking good!
Wrap-up
In this post, you’ve seen how I created a Web Site in Windows Azure, created a new ASP.NET Web API project, used Entity Framework to create a model of the data I showed in the previous version of the leaderboard service, and created a new API Controller, leveraging Visual Studio’s powerful scaffolding to automatically generate an API on top of my data model. I also showed how I could quickly download a Nuget package to add basic OData query support on top of Web API with the addition of a single metadata attribute. You’ve also seen how with a few simple updates, I created a new version of my leaderboard JavaScript library that works with the Web API version of the leaderboard service.
You also saw how I was able to use the new Web Sites feature of Windows Azure to quickly provide a spot in the cloud for my service, with simple Web Deploy-based publishing from Visual Studio to streamline the process of deploying my service to the cloud. While I didn’t have time to cover it in detail in this post, Windows Azure Web Sites also provides robust monitoring, error logging, configuration options, etc. all from the management portal, simplifying the management of my Web Site.
Here are the advantages and disadvantages, in my view, of using ASP.NET Web API for this kind of service:
Advantages
Mature platform – While Web API is relatively new, SQL Server and Entity Frameworkhave each been around for numerous versions, and have had time to improve and grow over that time. Maturity also means greater familiarity for .NET developers.
Data format options – can return data in XML (ATOM) or JSON format, or other formats for which type formatters are configured. Content negotiation makes it pretty easy support multiple types for both input and output. See the ASP.NET Web API site for more information, videos, and tutorials.
Customizable – ASP.NET Web API is a fully customizable solution, with powerful routing, content negotiation, and other features that you can leverage.
Query flexibility – While the implementation I showed only supports a subset of query types, OData’s powerful query syntax makes it easy to work with the service through JavaScript, simply by building the appropriate URL and making the appropriate HTTP requests.
Disadvantages
Complexity – While arguably a little simpler and easier to understand than the WCF Data Services version of the leaderboard service, this version still has a fair number of technologies used. The scenario I’ve shown is deliberately simple, so as to illustrate the end-to-end solution, so expect a little more work when it comes to more complex schemas, adding robust data validation, etc.
No client library for JavaScript apps – as with the WCF Data Services version, when working with this service from JavaScript, you have to construct your own library for interacting with the service (well, you could just write the code to call the APIs directly in your client code, but who’d do that?).
New platform – ASP.NET Web API is a newcomer to the ASP.NET stack. While it’s been through a good bit of testing in preview versions, it’s still new enough to unfamiliar to many devs. As I showed, it’s pretty easy to implement, though. And some parts of the stack I used (such as the Nuget package that adds OData support to Web API) are preview releases, which may argue against using them in a production situation.
As with the previous discussion of a WCF Data Services-based leaderboard service, whether ASP.NET Web API is the right solution for your back-end depends on a number of factors, not limited to your familiarity with ASP.NET and related technologies, and your willingness to use relatively new platform technologies. This was my first major foray into Web API, and I was pleasantly surprised by how easy it was to get the basic service up and running. I’m looking forward to digging deeper into Web API, and in fact, it’s one of the technologies that’s under consideration as the basis for the next version of my Community Megaphone site.
While you’re waiting, why not sign up for Generation App? There are lots of great resources available for building Windows 8 apps (and now for Windows Phone 8 as well), including new information on a variety of app frameworks from partners that make it fast and easy to build apps and games for Windows 8. It’s free, and you control how often updates are sent, so there’s no good reason to pass it up. Sign up now!
Comments
Comment by Mike Cattle on 2012-12-07 12:12:00 +0000
Comment by Jason Dean on 2012-12-07 13:02:00 +0000
Funnily enough. I hit a problem today with hosting a WCF OData application. Everything worked fine in the Local hosting scenario. But as soon as I published to the cloud (Azure Extra Small/Small compute) I got errors due to not having enough memory. I’m now re-trying this with the exact same Web API package you mentioned.
Comment by devhammer on 2012-12-07 16:31:00 +0000
Apologies, Mike. I should have been clearer. Yes, there are third-party JS libraries for OData. I was referring to official libraries from Microsoft. You could probably use DataJS or JayData, but I haven’t put those through their paces, so didn’t want to complicate things. Thanks for pointing out the libraries!
Comment by devhammer on 2012-12-07 16:32:00 +0000
Strange. I haven’t seen that…are you loading a lot of entites?
Comment by Jason Dean on 2012-12-07 20:03:00 +0000
No. It basically had a single table with two rows that it was accessing via entity framework 5 code first. I’m going to try it again this weekend.
Comment by devhammer on 2012-12-07 23:41:00 +0000
Well, let me know if you still have trouble with it. I’d be happy to put you in touch with one of my peers who spends more time in that world.
Comment by Jason Dean on 2012-12-10 09:18:00 +0000
I deleted everything and started again. This time it seemed to start up ok. Not sure why I was getting the not enough free memory to launch service. I’m beginning to wonder if that was a red herring and there was another issue at the bottom of what was going wrong. I’m glad it’s working as I can now go back to using this instead which makes things easier
Comment by devhammer on 2012-12-10 12:27:00 +0000
Good to hear! Hope it continues working smoothly for you.
Comment by ScottJ on 2012-12-20 00:01:00 +0000
Great article/example! For a real-world application is this workable or would you want to create domain entities using EF code-first, then a business layer, then data transfer objects? We are currently working through an architecture like this but once you put in a proper business layer and data transfer objects it seems like you lose a lot of productivity but gain SoC. E.g. the cowboy in me wants to just call EF from controllers, project into anonymous types if necessary, etc. Is there a great model project out there that use EF, business layer, data transfer objects, etc.?
Comment by Jalpesh Vadgama on 2012-12-20 03:01:00 +0000
Nice work Great Article!!
Comment by devhammer on 2012-12-21 00:09:00 +0000
Thank you. Glad you liked it.
Comment by devhammer on 2012-12-21 00:16:00 +0000
I’m not in the trenches building systems, so take my advice with a grain of salt. But the advantage I see of using ASP.NET Web API is that it can be the basis for just about any client tier. And it’s really up to you how complex you want to make the business layer and/or DTOs.
I’m a fan of the quote from Albert Einstein: “Make everything as simple as possible, but not simpler.” IOW, I tend to look for the simplest solution I can find to a given problem, until it becomes clear that more complexity is needed, rather than the other way ’round.
One thing that you may lose in separating concerns through Web API is the ability to easily propagate validation via metadata attributes, but there are folks who find that somewhat icky to begin with. I’m not a purist, so I think there’s a place for both approaches, depending on what’s most important for a given solution.
Comment by Aamir HasAN on 2013-01-16 00:07:00 +0000
Excellent, I like you article
Comment by devhammer on 2013-01-16 00:57:00 +0000
Thank you. Good to hear.
Comment by Dean B on 2013-03-28 13:09:00 +0000
Absolutely brilliant article, look forward to trying this. Question – not looking for any detail just maybe a couple of keywords I could Google if it’s possible – is there anything built in on the authentication side of things?
Comment by devhammer on 2013-03-28 15:19:00 +0000
Thanks! Glad you liked it. In terms of authentication, you can use many of the techniques you’d use in an ASP.NET MVC app. Basically think of it as securing an HTTP endpoint…can be as simple or complex as your needs dictate.
For an easier authentication route, Windows Azure Mobile Services provides built-in support for authenticating against Twitter, Facebook, Microsoft accounts, and Google accounts, so a lot of the hassles associated with authentication (in particular, getting users to register new credentials for your app) go away.