ASP.NET Web API vs. ASP.NET MVC “APIs”
Web API By Dave Ward. Updated June 30, 2012I’ve been receiving lots of emails asking my opinion about ASP.NET Web API lately. One of the most recent messages boiled them all down pretty well in its subject line:
ASP.NET Web API – Why is it so cool?
That’s a great question.
Too many of the answers to that question come down to subjective, personal preference. Worse, you’ll often hear that it’s what you should use simply because it’s the new thing Microsoft is pushing (you know, like WCF once was). If you’re already making good use of ASP.NET MVC’s controller actions as a makeshift API, just hearing that Web API is “better” might not be all that compelling.
However, I think Web API objectively wins out over MVC controller APIs in a few key areas. In this post, I’ll cover why these three aspects of ASP.NET Web API make it a clear choice for my ASP.NET-based APIs going forward:
- Content negotiation
- Flexibility
- Separation of concerns
Content negotiation
Content negotiation is one of those features that can seem overwrought at first glance. The technical demos we’ve seen most often, returning content like images and vcards based on the Accept header, are neat, but not something you’re likely to need on a daily basis.
However, content negotiation is still a nice feature even if you only expect to return a single type of serialization. Why? Because it decouples your API code’s intent from the mechanics of serialization.
For example, which would you rather write and maintain?
ASP.NET MVC
public class TweetsController : Controller { // GET: /Tweets/ [HttpGet] public ActionResult Index() { return Json(Twitter.GetTweets(), JsonRequestBehavior.AllowGet); } }
ASP.NET Web API
public class TweetsController : ApiController { // GET: /Api/Tweets/ public List<Tweet> Get() { return Twitter.GetTweets(); } }
The choice between those two options is an easy one for me. Not only is the return value of List<Tweet> more expressive (especially when you revisit this code in a year or two), but letting Web API handle the serialization means you don’t need to clutter the action up with the Json() code.
Of course, you never know when it might be helpful someday for that same endpoint to support returning its data as XML, CSV, MessagePack, or some future serialization format. Content negotiation makes adding that across an entire API relatively simple with Web API, but it would be cumbersome to update a plethora of MVC controller actions.
Flexibility
It’s clear that flexibility was a central goal in Web API (without resorting to the configuration tedium that burdened WCF). Content negotiation is a great example of that, but that’s only the beginning. Web API starts with sensible defaults, but then provides a GlobalConfiguration object that you can use to tweak a wide range of options.
A couple more concrete examples:
Down with XML!
One initially disconcerting thing about Web API is that hitting an endpoint in your browser will result in an XML response. That’s correct behavior because regular requests in browsers usually send an Accept header preferring text/html and application/xml, but not JSON.
If you want to bring Web API’s behavior more in line with the output of MVC’s Json() helper, you can remove XML support from your API entirely. Just add this to the Application_Start event and you’ll never see XML again:
// Normally, you'd probably be doing this in a setup method that // accepts the configuration as a parameter and this line wouldn't // be necessary, but you can do it right in Application_Start too. var config = GlobalConfiguration.Configuration; config.Formatters.Remove(config.Formatters.XmlFormatter);
Now, even if a client’s Accept header prefers XML over JSON, Web API won’t respond with XML. Personally, I’d prefer to see Web API prefer JSON over XML by default, but it’s great that Web API is flexible enough to allow these global changes with a minimum of configuration ceremony.
Tweaking your API’s JSON format
You’re generally stuck with the JSON that JavaScriptSerializer wants to generate when you use MVC’s Json() helper. Luckily, JSS does a pretty good job of creating sane JSON, but it also opts you into some unusual conventions like “MSAjax” date encoding instead of the more common ISO format.
Web API and Json.NET allow you to tweak the JSON that your API produces very easily. For example, Json.NET defaults to using ISO dates, but you can switch that to the Microsoft format for backwards compatibility across your entire API with a simple configuration setting:
// Separate statements for purposes of fitting within my tiny // 492px code blocks. You could do this on one line if you wanted. var js = GlobalConfiguration.Configuration.Formatters.JsonFormatter; var dfh = js.SerializerSettings.DateFormatHandling; dfh = Newtonsoft.Json.DateFormatHandling.MicrosoftDateFormat;
There’s a wide range of options you can set this way, from “pretty printing” the JSON to support for automatic translation between camelCase and PascalCase. For more examples, see this article on the ASP.NET site.
Separation of concerns
All of the preceding examples highlight one of my favorite overall advantages of using Web API. It’s possible to quickly drop these high-impact changes in across an entire API largely because Web API helps separate your API from the part of your project that returns HTML.
MVC controller actions are optimized for building up an HTML document through the use of things like views, partial views, and HTML helpers. That whole pipeline doesn’t really make sense in the context of an API that returns entities, DTOs, or ViewModels, and I think it’s valuable to keep them separate.
So separate, it’s not tied to a website at all
In fact, you may eventually want to isolate API from your website to the point that it doesn’t even make sense to host the API within the same project. With Web API, you can self-host the same API code in a Windows Service or even a console app.
You could do that with an ASP.NET MVC “API” by creating a separate project for the API, but then you’re still paying the performance penalty for your API requests to filter through MVC’s rendering pipeline. In simple load testing on my local machine, I’ve found that Web API endpoints hosted in console apps are nearly 50% faster than both ASP.NET controller actions and Web API endpoints hosted within MVC projects.
It’s great to have that low-cost, high-performance option as usage of your API grows. Starting with Web API means you’re not tied to ASP.NET MVC (or any web framework) in the future. It’s quick and easy to migrate an MVC-hosted Web API to a centralized project of its own as your needs organically grow.
Conclusion
These are the three main reasons why I’m using Web API controllers for client-side callbacks in my ASP.NET MVC projects going forward. Even though many of those “APIs” will never grow into more than endpoints for AJAX callbacks, using Web API for those endpoints is still easier and more flexible than other built-in alternatives.
What do you think? Are you using Web API yet? Do you plan to migrate from MVC controller actions to Web API in the future? Did I miss an aspect of the MVC-centric approach that makes it work better than Web API for you (I can think of one, but I haven’t seen many projects actually doing this in the real-world anymore)?
Similar posts
What do you think?
I appreciate all of your comments, but please try to stay on topic. If you have a question unrelated to this post, I recommend posting on the ASP.NET forums or Stack Overflow instead.
If you're replying to another comment, use the threading feature by clicking "Reply to this comment" before submitting your own.
2 Mentions Elsewhere
- The Morning Brew - Chris Alcock » The Morning Brew #1131
- Aprendiendo ASP.NET Web API… gratis y en video!! | Jersson on the block!



I really like web API, however, I am finding it quite limiting that you cannot have a non CRUD operation within a controller. So i have to have an actions mvc style api as well. This means i end up with more controllers and miscellaneous action methods inside my mvc API.
sorry for the brevity, am on my WP
You can have RPC Style Actions in Web API. You just need to set a route up for it to be api/{controller}/{action}/{id}.
Rick Strahl mentions it in this article in Code Magazine http://www.code-magazine.com/Article.aspx?quickid=1206081
I totally agree re: REST vs. RPC. I think REST is preferable when it fits, but sometimes an RPC-style API makes a lot more sense.
Fortunately, as Al mentioned, Web API does support RPC-style endpoints, and it even turns out to be very easy. It’s just not very well documented (yet). I wrote a post about how to use RPC-style routing with Web API that you might be interested in.
Sorry Dave, forgot you wrote that. I just recently was revisiting Rick’s article, so it was fresh in my brain. Either way, same outcome. Keep the good info coming.
Al
No worries. The more resources we all have the better, and Rick’s content is always fantastic.
Interesting although all the features/advantages you mention here have been available in ServiceStack for years – that has been shipping .NET’s fastest JSON Serializer for years (and still does). The JSON serializer is very resilient and can withstand extreme versioning without error.
It also requires less code to setup and configure as seen in this ServiceStack vs WebAPI port of Rest files.
If you’re talking about separation of concerns and flexibility/versatility, then again ServiceStack lets you do more where you’re able to re-use your existing web services in an MQ Host where it also runs on .NET 3.5 and Mono (in ASP.NET or HttpListener hosts). You can even call the same web service with SOAP, which is strange compatibility (that WebApi notably lacks) since the tech-lead of WebApi was working for years on WCF/SOAP before starting WebApi.
It also supports MonoTouch/Silverlight clients and is still the only web service framework that offers the most succinct, typed, end-to-end API without any code-gen.
All C#/.NET ServiceClients share the same interfaces which make them highly testable and swappable to the point where you can have the same unit test also serve as an XML, JSON, JSV, SOAP Integration Test – none of which WebApi lets you do.
It still maintains many other features that WebApi lacks as briefly described in this ServiceStack vs WebApi StackOverflow question and has been shipping on production systems for 4+ years which has amassed over 70 contributors.
Why do you think most .NET devs keep waiting for Microsoft to release yet-another-replacement-framework before most .NET devs move off the last one?
I don’t know if I’m understanding your point here. Isn’t the WebAPI built on top of ASP.NET? It uses Routing, Controllers, has actions – is this not the case?
In terms of “Controllers actions are optimized to return HTML” – I don’t think that’s an accurate statement. They don’t have anything to do with HTML at all – when they’re invoked they hand data and context off to a ViewEngine. If you’re saying “well it takes extra code to write JSON” – sure I’ll give you that. But that’s not the ActionResult’s fault, nor is it inherently it’s nature. A quick set of helpers/extension methods and you’ve fixed that.
The main thing I’m curious about, however, is the supposition that maintaining two projects is somehow better than just one. Yes, the WebAPI has better content-negotiation as it’s basically invisible… however that syntax sweetness is an Extension Method away.
It could very well be that I’m missing something – apologies if that’s the case :). Overall I agree with you: the WebAPI makes a nice choice if you’re doing heavy client work. I’m not sure that I agree with the “separation of concerns’ angle, nor do I agree with the idea of having two projects.
You can host the same Web API code outside of ASP.NET and even outside of IIS. I’m definitely not suggesting that everyone should start with a separate, self-hosted project for their API, but it’s nice to be able to port your API code directly to a self-hosted project if it grows to need that extra efficiency. Personally, I’d never bother with a separate project for the typical “API” that just exists for AJAX callbacks, but I’d consider it if I were setting up a public or widely-shared-private API that I was expecting to handle heavy usage.
Nothing factually incorrect, but I choose to see it like so:-
http://hadihariri.com/2012/04/06/with-http-your-application-is-your-api/
One thing you didnt mention which WebAPI has vs doing it in MVC is OOTB support for OData filteing/projection etc.
One thing Hadi’s post may not call out explicitly enough is that having 2 copies of everything means 2 sets of authorization, routing etc. code and/or testing.
It’s my understanding that oData support is going away for RTM (but probably coming back as an addon of some sort later, with support for more of oData’s features).
Ah, interesting. Definitely makes sense to separate that functionality as it’s useful in lots of contexts.
Luckily that doesnt matter as Linq2Rest takes care of the requirement anyway.
@Dave,
I think much of what you mention here as advantages actually exist in ASP.NET MVC too. Action Filters and other extensibility points have been there pretty much from day one. Conneg is a few lines of code (if we exclude actual serialization code) and can be injected as a global filter. SoC is available in both systems based on the patterns they follow, so I don’t really think it’s a Web API advantage as such.
On the other hand, and excluding the contrib project, MVC does have the advantage of shipping with view engine support, something Web API does not.
To be clear, I’m only talking about APIs here; like how you commonly see an “API” controller right beside regular page-generating controllers in so many MVC projects. In other words, I’m saying if you need a view engine then use MVC and if you need a serializer then use Web API, not that you should use one or the other exclusively.
Which I believe is the wrong approach to begin with (“API Controller” next to regular controller).
For me right now the only substantial benefit of Web API over MVC is self-hosting.
Ultimately however, I’d stick with one or the other and not have a somewhat artificial divide.
So what’s your optimal setup, using ASP.NET MVC exclusively? Separate projects? Areas?
The reality I’ve seen in my consulting is that most of my clients have been mixing their “API” with their website, putting all of the controllers side-by-side (sometimes even actions in the same controller). I’m optimistic about Web API helping bring some separation there. I don’t see how that divide is artificial at all.
Use one exclusively. And right now I feel that MVC offers more advantages than Web API if we’re talking about tre ability to serve not only an API but also our UI. This doesn’t mean however that I have two controllers or different methods for one and the other. This is about leveraging a single point of entry for both. A UI is nothing more than another Consumer of the API.
I wrote about this sometime ago here
http://hadihariri.com/2012/04/06/with-http-your-application-is-your-api/
Just so I understand your post, you’re advocating a single endpoint that responds with both HTML and JSON, JSONP, XML, or whatever else the non-human requests need to be fed?
An endpoint isnt/shouldnt be a thing. The central ‘thing’ for me is a Resource, and it _is_ one thing.
The RE in REST is REpresentation. You negotiate a representation of the resource.
I realize that is not going to be a popular opinion but I think having:
public List Get() {
is a really bad practice for a Web API controller. IMHO the purpose of controllers is to provide an interface between the HTTP world and your .NET application. Returning strongly typed objects is just an illusion that you can transfer objects over the wire and obscures all the richness of the HTTP application protocol.
If the controller doesn’t deal in terms of HTTP and it doesn’t contain business logic, exactly what role is it playing? If you are simply converting domain objects to DTOs then I agree with Demis, use ServiceStack.
Web API is about embracing HTTP as a first class application protocol. That means working with HTTP concepts all the time, not just looking under the covers for the exception cases.
I agree with Ruben Bartelink.. Basically use the right tool for the right job..
Simple.Web has content negotiation /and/ view engine support. Thus, I win… ;)
Link: http://blog.markrendle.net/2012/06/01/simple-web/
As a matter of interest, to you have a story for Linq2Rest style OData-based querying on your resources like WebAPI was going to have?
(I’m happy if it’s just it ‘shouldnt be hard to integrate Linq2Rest’)
I’m planning on supporting OData the way WCF Web API did, but with a Simple twist… watch this space.
I’m Simply waiting with intrigue for the unveiling :)
ASP.NET Web API is no surprise for me, in early of ASP.NET 2.0 webforms, i already implement a “API” and response Json string for other winforms application.
another way, web service still in use and work with jQuery of my current projects.
Totally Agreed. Thanks Dave.
I’m on the fence about whether the benefits of Web API outweigh the cost of having a separate (but similar technology) to ASP.Net MVC.
Content negotiation has been added, in my opinion, successfully to ASP.Net MVC with an SDK developed by Microsoft and released on codeplex (for more details see http://blog.maartenballiauw.be/post/2009/08/19/REST-for-ASPNET-MVC-SDK.aspx)
The benefit of the above SDK was that you were able to serve xml, json, AND html. Yes there are pros and cons for having the same action serve both html and a DTO, but on the whole I found this a useful option.
One particular benefit I found with being able to serve html along with the other formats, is that it enabled me to *easily* create a html document page for the service endpoint. When combined with ASP.Net MVC templated helpers, your dto output by the endpoint could be output in a usable html form with as little as Html.EditorForModel().
With a fairly unobtrusive change to ASP.Net MVC, the SDK added RPC and/or REST style endpoints without developers on the team having to learn another (albeit similar) technology.
At the moment my opinion is: when a project is predominantly server side html rendering, with a little bit of web service thrown in, the SDK adds just enough REST/RPC without forcing developers to learn another technology in an already bulging stack.
Christian
I told myself I’d stay out of this, but well I couldn’t resist. Yes the stacks are different and there are several reasons for this. Using conneg as the poster child is the wrong angle, yes conneg is a nice feature but the new stack brings much more than that.
Disclaimer: I am not on the team anymore, though I was.
At a high level I would say that the reason for the two sets of abstractions is to
1. Evolve the platform
2. Support a richer set of needs that were identified around Web API development.
3. Not break existing customers who are building with MVC.
4. Keep familiar abstractions in order to reduce the concept count / reuse existing knowledge.
Here’s my detailed brain dump, which some might consider a rant.
1. Self-host. ASP.NET MVC is deeply tied to IIS. Yes, you can use Cassini, but not in an production sense. Folks that build APIs often don’t want a full blown web server. For example in WCF, self-host was extremely popular. One of the others places this popped it’s head was in deploying to Worker Role where IIS is not running. Another place was with OWIN. With Web API you can use the OWIN bridge to run Web API on top of Kayak, Firefly etc. There was no way to achieve this without breaking the cord to ASP.NET.
2. HTTP programming model. ASP.NET Web API builds top to bottom off of the new HTTP programming model which appears in .NET 4.5. It is purely async top to bottom, and offers a much richer programming model working with HTTP. Add to that new extensibility points for handling things like ETags, caching, etc in a very HTTP friendly way. Additionally because it is inherently async it offers great scale. Introducing this programming model to ASP.NET MVC would be a massive breaking change.
3. Enhancements to existing concepts. ASP.NET MVC has controllers, Web API has controllers. However web API controllers have different semantics like routing by HTTP method, utilizing formatters for the body and yes, exposing the new HTTP programming model.
ASP.NET has Filters, Web API has filters. However Web API filters take continuations for chaining also Web API filters expose the new HTTP abstractions. This was to support common patterns that we saw prevalent in Web API systems where it is very common to modify the request in a pipeline sort of model.
4. Introduce more IoC friendliness. ASP.NET uses a lot of globals and statics. Web API abstractions however do not rely on global state with exception of one place which is the global configuration object which is only used in Web host scenarios.
5. Conneg. Yes it’s awesome and yes you can do that today in ASP.NET MVC with some existing code. However Web API conneg relies on the newer, better, more scalable HTTP programming model with all of it’s awesomeness.
Most of the aforementioned items were NOT achievable without making major breaking changes. Could the functionality have been provided on the existing abstractions, yes. However would that really be helping the platform move forward?
To answer your last question with another question, why not?
In an effort to maintain “backwards compatibility” which has been broken actually quite a few times in the past just with MVC, you’ve (I mean MS, not you) have introduced a somewhat uncertainty for developers and segregation, much of which is demonstrated not only in the comments of this post, but the actual need for this post.
How does this help move the platform forward? This will be another technology until at some point, someone realizes something was actually done wrong and it would be too difficult to change without breaking backwards compatibility and introduce yet another framework.
How does that help move the platform forward? I guess it depends on what we consider the platform to be.
Hadi
We can debate all day long and probably will not see eye to eye, though I do respect your opinion. With frameworks in general, there is the continual tension between creating something new or retrofitting onto something that is existing. In this particular case there many different constraints which weighed into the decision and it was not black and white.
As far as the statement that there will be another technology until someone realizes something went wrong, I don’t think this is about right and wrong. We’re learning continually and as we learn we reevaluate some of our past decisions based on the new knowledge. The product of that new knowledge usually results in a chance in the way we do things going forward.
Glenn,
When I say wrong I’m speaking figuratively. We all learn and find better ways of doing things.
And while often it makes sense to cut off and start again, I feel in this case, it probably wasn’t called for. True that it takes much more effort to try and evolve a framework as opposed to start from scratch, but it also shows a certain level of commitment to your users, and that’s something they will appreciate.
That’s all well argued and stuff, but the reality is that the OOTB stuff forces a false split between API and web.
That’s going to result in:
a) time poured down the drain following a bad design approach and confused devs
b) security issues and bugs due to lack of syncing between an api side and a non-api side
I strongly recommend you and others read and understand
http://hadihariri.com/2012/04/06/with-http-your-application-is-your-api/
Web Api has some fine concepts, but it’s all about how it fits into a real system. That’s something worth putting time into doing properly.
Ruben, I hear you saying a lot “sky is falling” and “this is the end of development as we know it” type comments. I can see the arguments for having one HTTP stack that handles websites and web apis. On the other hand the way that traditonal websites have been designed vs how we are building web apis today is very differnet and the needs of the frameworks is differnet. I am throughly NOT convinced that the negative result that you are claiming will happen will happen. Time will tell however.
For every sky is falling barb, there is an equal and opposite Architecture Astronaut one. Good luck to you and the “we” who are building your sites in your undefined “new” way. Its always fun building a revolutionary solution to a big problem in a nice green field because you’ve seen the future.
My key point is very concrete: If I have an ASP.NET MVC site and I want to emit JSON, XML and generally offer API style interfaces. Web API at one point sounded like something that would fit in with what I’m already doing. You see examples saying ‘take this controller; this is how much cleaner it gets in Web Api`. You see they both derive from a Controller class.
Then you have a deeper look and you see that you’re forced to effectively create an Api side and an App side with separately maintained authorization, routing etc.
Its very similar to the way that the REST stuff bolted onto WCF in 3.5 didnt solve any problem I have in a way that I wanted to solve it. I’m sure the designers of that believed in their solution too.
My frustration is that I need to offer APIs, OData endpoints but my site also has HTML to render. And I want the thing to be grokkable without having an API team and a site team and Api testers and site testers and meetings for them to coordinate things. Web Api just muddies the waters for that problem space.
I am very satisfied that Web Api is excellent and appropriate if programmatic APIs was all I wanted to emit.
I dont have much need for the MVC view stack (using client side stuff like backbone talking to my APIs instead). Problem is that OOTB Web Api doesnt give me any useful integration – it just leaves me in “now you have 2 problems” land.
I know you can give concrete advice and don’t normally stray into this type of namecalling. I know you’ve learned a lot from your Node work about what a modern web framework can and should offer. I wouldnt mind a paragraph or two from you that explains what you mean about `the way we build APIs today`.
Am I correct in inferring that the way things are going is to have an API area which is for programmatic use and let the site/app be rev’d/designed/maintained separately or at a different pace?
What’s the big thing I’m just not getting about how having 2 stacks makes life simpler?
Ruben
I don’t think I called anyone any names did I? If I offended you I apologize.
When I said we, I mean’t the industry, not Microsoft :-) I was being inclusive not excluse though it sounds like you thought I was being the latter.
I am not at all saying that having two stacks is the only possibile solution. OpenRasta for example proves that is not the case.
I do believe that all things being equal, the benefits of bringing self-host, pure async and a more targetting HTTP experience as well as not breaking existing customers outweighs the cons of introducing the second set of abstractions.
As for using one stack to do both. I think you will see web api continually fleshing itself out for handling sites as well. This is currently happening via the community, but I expect you’ll see more of that in the box in the future.
I was reacting to the “sky is falling” bit as being a thinly veiled Chicken Licken you’re not working with the facts mate barb. Which is an overreaction. I fully understand it’s just hyperbole. But there was a grain of truth in that I wasnt giving examples of or backing up my “it’ll all make a mess” innuendo.
I’m taking your we as referring to the people who are trying to solve larger problems and come up with general solutions that move things forward. I understand that having everything work with everything will implode due to complexity.
However when wizards for ASP.NET are going to start spitting out API controllers in the app, we get problems.
When the Web Api stack is feasible as a full app stack, it’ll be great and I look forward to when that’s happened.
But it’s not and right now that’s being presented as “well that doesnt matter anyway because APIs are different to your full app anyway”.
I am not quibbling with any of your justifications for not being able to achieve a full win by mutilating MVC.
Right now we have two overlapping solutions and confusing messaging and justifications for this situation. Your average dev infers a lot from the wizard output. It’s not a good default architecture message to be sending even if it will garner good adoption for Web Api and will superficially make it easier for people to add some form of APIs to their ASP.NET sites.
I know there are plenty cases where having 2 right tools for the job used side by side is the correct thing to do. But that’s far from an 80% case. And I don’t think it’s very Chicken Licken to say so.
“However when wizards for ASP.NET are going to start spitting out API controllers in the app, we get problems.”
Which problems?
>>“However when wizards for ASP.NET are going to start spitting out API controllers in the app, we get problems.”
>Which problems?
Needing to implement and test two sets of auth
Having two sets of DI config
Having two sets of routing config
Having to document/make discoverable what the linkage/relationship is between your app controllers and your ‘api’ controllers / routes /resources / url structure.
Most importantly: People thinking it is an 80% case that one would need a normal controller and a special _API_ controller for the APIs without even suggesting conneg exists and/or might be appropriate. People going too far before discovering the “two of everything” problem.
Having a hydra which does it all is fine for a cool blog post or for an interesting sample. The fact that so many people are confronted with this arrangement without appropriate contextual guidance is not a good idea IMO.
Its a really bad default as the ideal next step of throwing away your learning code and considering the best approach to your overall app doesnt happen in practice.
Let’s not forget that by tightly coupling the HTTP verbs in ASP.NET Web API with the API operations, on the surface, the controller must be tightly coupled to its model. Consider for example,
public List Get() { .. }
In C#, there can only be one Get() method in a class, and in this case that method returns a list of Foo. Therefore, on the surface (using default design), the controller must be named FooController. And, unlike ASP.NET MVC, this might mean that it could be difficult to offer up a diverse number of model types in a single controller by merely varying the actions, because to get instances of these models there is only one action, and that is GET.
On the other hand, as mentioned earlier, one can set up routes make this work. I am still new to ASP.NET Web Api so I haven’t experimented with this yet, but where routes are managed in a completely isolated configuration class the possibilities of introducing multiple model types support are introduced.
This makes me wonder what the benefits are, then, of starting with an HTTP verb convention in the first place other than merely a “git ya started” feature, and whether routing wildcarding might facilitate strongly typed routes using automatic conventions such as MVC routing already enjoys.
Jon
You are not tightly coupled to HTTP methods in the name. You can use attributes to specify whatever name you like. The method is just a convention.
Also the conventions are smart as they support using HTTP methods as prefixes. Thus you “can” have GetCustomer and GetCustomers in the same controller where one returns a single and the other a collection. As for returning diverse models from the same controller, you could do it, but I don’t’ recommend you do nor is Web API designed to help you there. It takes a resource centric approach with the idea that your controllers are HTTP resources. This is consistent with the way HTTP works as a resource corresponds to a URI and is exposed over HTTP methods.
Glenn, thanks. What I read from this response is confirmation that by intended design there is a one-to-one mapping of controller to model. A resource by HTTP design typically correlates to a model IMO, handled by a controller that ties the model to the resource identifier. And that is not quite how MVC ran, where anything went. I’m not saying this is *bad*, I’m saying it’s a major design detail with significant design considerations if one was to follow this paradigm. Perhaps it’s actually good. It sort of makes sense, my only concern is having a detailed Web API implementation and tens or hundreds of controllers that conform to this design. Clearly, whether this works well or not really probably just depends on project scope, etc.
Jon Davis
Not necessarily a model as you can just receive HttpRequestMessage and return HttpResponseMessage. But yes there is definitely an idea that IF you go a model driven route that your controllers will handle a single model.
What is your concern specifically?
^^ see “my only concern” above ;) Also, said concern is in the context of continuance of that convention. It’s not a real-world concern, though, not one I presently face, just one I can imagine limiting the technology to applications and web sites with very basic functions (like Twitter) and not feature-heavy sites or large B2B or internal enterprise solutions without deviating from this specific convention.
Jon,
I have an API for LOB solution that has many hundreds of controllers. The HTTP method to controller action mechanism has worked very well for me.
Darrel,
I’m so very sorry to hear this. I’m sure you’re proud, but if I were to inherit such a project and it is implemented as it sounds I would probably not be able to maintain it without sitting still. For example, if there is a “standard pattern” in your controller->model declarations and how you expose your models then I would at least create a generic API controller (MyController:ApiController) and use single-line class declarations either in the model file or else all together in a single file to create then uniquely, overriding methods in their own partial class files only where needed. But if you’re hand-rolling a new controller class with its own file for every model and the list goes into the hundreds, particularly when the models are probably already doing this so as well, in my mind this becomes a major redundant maintenance exercise. If you aren’t introducing shortcuts like that I would be intimidated to know what your codebase looks like.
^^ “(MyController:ApiController)” this comments implementation could use some love since all of us are using generics samples here, let’s see what pre does:
(
.. and we can’t edit nor delete .. ;alsdkjf3f3afd
Yes, the classic programmer’s tack of, hey, I can take these 10 simple classes and make one uber generic class because that will make maintenance easier. Having supported the LOB apps I have written for the last 18 years I can assure you there are many cases when that definitely does not make it easier.
My controller classes implement functions from accounting, inventory management, purchasing, preventative maintenance, sales, and many other domains. I almost never get a request for a change from a customer that affects more than a few controllers. That’s because my classes map to business concepts, not to common implementation patterns for the sake of saving lines of code.
I had a developer come and work for me that saw the repeating patterns of logic between controllers and attempted to abstract away the logic. The end result were controller classes that were meaningless to read, sat on top of a mess of inheritance, generic types and interfaces and strategy patterns. It was an absolute nightmare to change anything.
You make a valid point but .. 10 simple classes? You said hundreds. I would be far less likely to do that for 10 simple classes. My concern is the manageability of hundreds of redundant copy-and-paste classes; consider if one change needed to be applied to all controllers. Perhaps your developer didn’t do a very good job at refactoring. Inheritance for eliminating redundancy is something I strongly believe in but I’ve been guilty in the past myself of introducing unreadability. These are mistakes in themselves and a separate discussion.
That said, I think this discussion is relevant and demonstrates the potential controversy of ASP.NET Web API’s current intended-design strategy.
I’m glad I didn’t tell you how many controllers I actually have :-) My scenario is a bit different in that my API covers many more domains than most and I do use inheritance sparingly to remove duplication. I just have been burnt so badly by excessive blind adherence to the DRY principal that I tend to shy the other way.
However, my original point was just to say that whether wise or not, Web API won’t get in the way if you decide to create a large number of controllers.
IMO mapping to C# or controller methods is a terrible idea to be promoting for remote services – which is something all MS web service frameworks continue to do generation after generation. There’s plenty of good reasons why mapping to models remains the superior alternative, which I explain in detail in:
https://github.com/ServiceStack/ServiceStack/wiki/Advantages-of-message-based-web-services
The default mapping in Web API is to map actions based on HTTP methods and the media type which are both centered around the message not the uri. Routing maps the controller based on the URI. So essentailly the client has no visibility / coupling to the server implementation.
Sorry I meant the mappings are both centered around the message not the controller / action.
I really think that Web API is the future of ASP.NET, but I’m not sure about what framework use at client side. I think it must be a jQuery based or similar FrameWork, but I doubt between Kendo UI, Google Closure Library, Backbone.js, etc…
I don’t blame Microsoft for trying to break away from the existing ASP.NET framework as the existing ASP.NET providers are dated (i.e. built before IOCs), xml-config encumbered, overly complex, and the degrading locking in ASP.NET sessions is defected by design, esp. for Ajax/Internet websites. It’s why we’ve replaced them with clean, fast, dep-free impls contained in MVC PowerPack:
– New Authentication Provider Model – includes Twitter, Facebook, Credentials, Basic and DigestAuth built-in.
– Clean caching providers – with InMemory, Redis, Memcached & Azure CacheClient providers built-in.
– New (typed/POCO-based) Session providers that work with all the above Caching providers.
@Moises
Why do you think WebApi is the future of ASP.NET? will it replace it?
Is it because it comes bundled with ASP.NET MVC? Or just because its the latest framework prescribed by Microsoft? Tried any of the others before this? How is it better than all the rest – i.e. does it promote a better design? Does this deprecate all Microsofts previous web service fx attempts? (e.g. .asmx, CSF, WCF, WCF/REST, WSE, WCF DataServices, RIA, MVC) – do you think it will be their last?
For client side frameworks if you want to stay within the preferred Microsoft guidance – use Knockout.js. If you want to use what everyone else is using – use Backbone.js. Ember.js/AngularJS/Batman.js/Spine.js are also good contenders – AngularJS is now sponsored by Google and their demo at BackboneConf was impressive, i.e. shortest amount of code to implement a TODO app.
I wouldn’t recommend using Closure Library now, as it looks to be replaced with Google’s new Modern Web Dev language and platform initiative – Dart: http://www.dartlang.org/
More linkbait
http://www.paulstovell.com/one-more-aspnet