90

I am creating a new MVC4 project, and research has lead me to believe that communicating from javascript to the server side is better achieved now through web API framework rather than controller actions. Is my understanding correct on this?

I am presuming that I can share all my attributes etc between web API and MVC controllers so on the face it, it does not seem a massive change for me.

When I am setting up applications, I like to split components out in to projects. My plan was to have a MVC project and a web API project. But I have ran in to issues. For example I have ended up with 2 apps as such, separate routing set up etc etc.

So my question is, in a MVC application should the web API framework sit within the same project, or should the web API be separated into a project of its own and work around the issues?

user229044
  • 232,980
  • 40
  • 330
  • 338
amateur
  • 43,371
  • 65
  • 192
  • 320

8 Answers8

112

Unfortunately you are wrong about that - I am presuming that I can share all my attributes etc between web api and mvc controllers so on the face it, it does not seem a massive change for me.

Many of the concepts used by Web API and MVC, even though similar at first glance, are actually not compatible. For example, Web API attributes are System.Web.Http.Filters.Filter and MVC attributes are System.Web.Mvc.Filter - and they are not interchangeable.

Same applies to many other concepts - model binding (completely different mechanisms), routes (Web API uses HTTPRoutes not Routes, even though they both operate on the same underlying RouteTable), dependency resolver (not compatible) and more - even though similar on the surface, are very different in practice. Moreover, Web API does not have a concept of areas.

Ultimately, if all you are trying to do achieve is to have a "new, trendy" way of serving up JSON content - think twice before going down that path. I certainly wouldn't recommend refactoring any existing code unless you are really looking into embracing HTTP and building your app in a RESTful way.

It all really depends on what you are building. If you are starting a new project, and all you need is to serve up some JSON to facilitate your web app - provided you willing to live with some potentially duplicate code (like the stuff I mentioned above), Web API could easily be hosted within the same project as ASP.NET MVC.

I would only separate Web API into a separate project if you are going to build a proper API for your online service - perhaps to be consumed by external customers, or by various devices - such as fueling your mobile apps.

Alexander
  • 4,153
  • 1
  • 24
  • 37
Filip W
  • 27,097
  • 6
  • 95
  • 82
  • 2
    +1 Excellent answer. I thought initially both the MVC and WebAPI may share some of the code especially in the case of filters, model binding etc. but they are totally different. – VJAI Oct 16 '12 at 12:14
  • Thanks for such a detailed response. I am creating a new web application using mvc controllers to serve content to my views. My plan is to use web api to handle communication from my client side js (site contains some rich features) to the server via web api. Some 3rd parties are building components for the site which will be integrated in the site and will use the web api to communicate with the server. So from what I read, would your suggestion be for such a setup have mvc and web api in the one project? Maybe have web api in a "api" folder. – amateur Oct 17 '12 at 22:53
  • 5
    Yeah in such scenario simply start a new MVC4 project in Visual Studio, and when prompted for a project template (second screen) simply select Web API. That will install Web API from Nuget and in the case you described should be perfectly fine. What you get is separate Web API config file plugged into Global.asax. Additionally you may want to separate the API Controllers into separate folder (by default they are together with MVC controllers). Finally, the default routes are obviously configured separately and do not interfere with each other – Filip W Oct 17 '12 at 23:49
  • 9
    I wish my lead would have read this post before he designed our current project. – Billdr Jan 03 '13 at 16:14
  • 2
    @FilipW Thanks for good explanations. I also have an MVC application and will use WebAPI2 for using service for Android applications. On the other hand, as David Peden says below, **security, maintenance and deployment** is also very important when deciding to create a new separate project for WebAPI. In that case, keeping in mind them, what would you suggest? To create a new separate project for WebAPI or use the current MVC project? Thanks in advance. – Jack May 19 '15 at 16:52
  • 1
    Very good "I would only separate Web API into a separate project if you are going to build a proper API for your online service - perhaps to be consumed by external customers, or by various devices - such as fueling your mobile apps." hit the nail on the head and makes it easy to determine which way to do it. – Andy Nov 07 '17 at 13:42
26

IMO, security and deployment should drive your decision. E.g., if your MVC app uses Forms authentication but you're interested in using Basic authentication (with SSL) for your API, separate projects are going to make your life easier. If you want to host yout site at www.example.com but host your API as api.example.com (vs. www.example.com/api), separate projects will make your life easier. If you separate your projects and subdomain them accordingly and you intend to leverage your own API from your MVC app, you will have to figure out how to deal with the Same Origin Policy issue for client-side calls to your API. Common solutions to this are to leverage jsonp or CORS (preferably if you can).

Update (3/26/2013): Official CORS support is coming: http://aspnetwebstack.codeplex.com/wikipage?title=CORS%20support%20for%20ASP.NET%20Web%20API

Community
  • 1
  • 1
David Peden
  • 17,596
  • 6
  • 52
  • 72
  • I'm trying to get my head around the issues around the decision to integrate Web API with my MVC application or have it as a separate project. I was able to successfully deploy a Web API HelloWorld app to a sub-domain on my web host. From this separate project, I will be likely using the Model from my MVC web application and calling code in that separate project. It seems like it might be easier to go down this route of a separate project, but what issues do you think I could run into with this approach? – Ciaran Gallagher Feb 14 '13 at 01:10
  • 2
    Personally, I would not use your view model as your DTO for your API. I would expect that that decision would cause you some serious pain down the road as your view models and API signatures diverge. SoC (http://en.wikipedia.org/wiki/Separation_of_concerns) is very important. – David Peden Feb 14 '13 at 17:02
  • @DavidPeden You suggest to create a new separate project for WebAPI. Is that true? On the other hand, I will create a new separate project for WebAPI (I currently have an UI Layer (MVC) and Data Layer (Class Library) in my application. So, I also use DI, but I am wondering if I can use the same Entities, Repositories, Interfaces and Abstract classes in the Data Layer for the newly created WebAPI project and the only thing I have to do is to create WebAPI Controllers? Or do I also create all of them (Entities, Repositories, Interfaces and Abstract classes) again for the WebAPI? Any help please? – Jack May 19 '15 at 16:47
  • 1
    @H.Johnson It's hard to give general advice that is meaningful but it sounds like you would benefit from having an application service layer that encapsulates your entities and repositories that can be leveraged by both of your UIs (MVC and API). – David Peden May 19 '15 at 20:51
10

After some degree of experience (creating API for apps and for mvc). I mostly do both.

I create a separate project for api calls that come from other clients or other devices (Android/IOS apps). One of the reasons is because the authentication is different, it is token based (to keep it stateless). I do not want to mix this within my MVC application.

For my javascript/jquery api calls to my mvc application, I like to keep things simple so I include a web api inside my MVC application. I do not intend to have token based authentication with my javascript api calls, because hey, it's in the same application. I can just use [authorize] attribute on a API endpoint, when a user is not logged in, he will not get the data.

Furthermore, when dealing with shopping carts and you want to store a users shopping cart in a session (while not logged in), you need to have this in your API as well if you add/delete products via your javascript code. This will make your API stateful for sure, but will also reduce the complexity in your MVC-API.

Dan Bechard
  • 5,104
  • 3
  • 34
  • 51
CularBytes
  • 9,924
  • 8
  • 76
  • 101
  • 4
    Well @Dimi, that's a useless edit to get some votes... How can I reject these? – CularBytes May 08 '16 at 11:54
  • Do what you want. I edit not by votes but for the best look it takes I assume. Go ahead. – NoWar May 08 '16 at 13:01
  • 3
    @CularBytes You can't reject edits, but you can edit it again and rollback the changes. This requires a peer review process under 2,000 rep, but you have enough rep to do it instantly. I agree that the edit added no value and have rolled it back for you. – Dan Bechard Jan 03 '17 at 13:59
6

Steven from SimpleInjector (IoC framework) advises two separate projects: What is the difference between DependencyResolver.SetResolver and HttpConfiguration.DependencyResolver in WebAPI

Community
  • 1
  • 1
Jeroen K
  • 10,258
  • 5
  • 41
  • 40
5

I have recently done almost the same thing: I started with a new MVC 4 web application project choosing the Web API template in VS2012.

This will create a Web API hosted in the same application as MVC.

I wanted to move the ApiControllers into a separate class library project. This was fairly easy but the solution was a bit hidden.

In AssemblyInfo.cs of the MVC 4 project add similar line of code

[assembly: PreApplicationStartMethod(typeof(LibraryRegistrator), "Register")]

Now you need the class LibraryRegistrator (feel free to name it whatever)

public class LibraryRegistrator
    {
        public static void Register()
        {
            BuildManager.AddReferencedAssembly(Assembly.LoadFrom(HostingEnvironment.MapPath("~/bin/yourown.dll")));
        }
    }

In the MVC 4 project also add reference to the Api library.

Now you can add Api controllers to your own separate class library (yourown.dll).

fanvabra
  • 140
  • 1
  • 8
2

Even if your project is so complex as to warrant two "front ends" then I would still only consider splitting out webapi into a separate project as a last resort. You will have deployment headaches and it would be difficult for a newbie to understand the structure of your solution. Not to mention routing issues.

I would aim to keep the system.web namespace isolated in the one "presentation layer". Despite the webapi not being presentational it is still part of the interface of your application. As long as you keep the logic in your domain and not your controllers you should not run into too many problems. Also, don't forget to make use of Areas.

Nick
  • 6,366
  • 5
  • 43
  • 62
  • 1
    My main reasoning for wanting separate projects is that the API isn't really front end. It's middle-tier. – lordcheeto Apr 15 '14 at 00:39
  • 6
    "It would be difficult for a newbie to understand" is not a great reason to choose one approach over the other. Keep it simple when possible, sure, but complex needs often require complex solutions. Rather than writing dumb code to cater to newbies, we should be training newbies to understand and write smart code. – Dan Bechard Jan 03 '17 at 14:02
0

In addition to setup the separate DLL for the Web.Api.

Just a Suggestion:

  1. Create the Project
  2. Nugget WebActivatorEx
  3. Create a a class Method to be called upon app_start

    [assembly: WebActivatorEx.PostApplicationStartMethod(typeof(API.AppWebActivator),"Start")]

    [assembly:WebActivatorEx.ApplicationShutdownMethod(typeof(API.AppWebActivator), "Shutdown")]

  4. Register a web.api routes inside the Start Method

    public static void Start() { GlobalConfiguration.Configure(WebApiConfig.Register); }

  5. Reference the Project to the Web Project. to activate the Start Method.

Hope this helps.

jayson.centeno
  • 835
  • 11
  • 15
0

I tried to split the API controllers into a new project. All I've done is to create a new library project, moved the controllers inside folder named API. Then added the reference of the library project to the MVC project.

The webAPI configuration is left in the MVC project itself. It works fine.