24

Let's say we have 2 separate applications, a Web Api application and a MVC application both written in .NET 4.5. If you were to host the MVC application in IIS under the host header "https://www.mymvcapp.com/" would it be possible to host the Web Api application separately in IIS under the host header "https://www.mymvcapp.com/api/"?

The processes running the 2 applications in IIS need to be separate. I know of the separate methods of hosting, self hosting and hosting using IIS. I would like to use IIS if at all possible.

Also, how would I host two applications (an API and a web application) if each were on a separate server so that I could serve the api from http://www.mymvcapp.com/api?

George Stocker
  • 57,289
  • 29
  • 176
  • 237
boosts
  • 605
  • 1
  • 7
  • 15

1 Answers1

32

There are at least 4 ways of doing what you want to do. The first two methods are for if you have 1 web server, and both applications are served from that one web server running IIS. This method also works if you have multiple web servers running behind a load-balancer, so long as the API and the Web site are running on the same server.

The second two methods are using what's called a "Reverse Proxy", essentially a way to route traffic from one server (the proxy server) to multiple internal servers depending on what type of traffic you're receiving. This is for when you run your web servers on a set of servers and run your API on a different set of servers. You can use any reverse proxy software you want, I mention nginx and HAProxy because I've used both in the past.

Single Web Server running IIS

There are two ways to do it in IIS:

If your physical folder structure is as follows:

c:\sites\mymvcapp
c:\sites\mymvcapp\api

You can do the following:

Create a Child Application

Creating a child application will allow your "API" site to be reachable from www.mymvcapp.com/api, without any routing changes needed.

To do that:

  • Open IIS Manager
  • Click on the appropriate site in the "Sites" folder tree on the left side
  • Right Click on the API folder
  • click "Convert to Application"

The downside is that all Child Applications inherit the web config of their parent, and if you have conflicting settings in there, you'll see some runtime weirdness (if it works at all).

Create a directory Junction

The second way is a way to do it so that the applications maintain their separateness; and again you don't have to do any routing.

Assuming two folder structures:

c:\sites\api
c:\sites\mvcapp

You can set up Junctions in Windows. From the command line*:

cd c:\sites
mklink /D /J mymvcapp c:\sites\mvcapp
cd mymvcapp
mklink /D /J api c:\sites\api

Then go into IIS Manager, and convert both to applications. This way, the API will be available in \api\, but not actually share its web.config settings with the parent.

Multiple Servers

If you use nginx or haproxy as a reverse proxy, you can set it up to route calls to each app depending.

nginx Reverse Proxy settings

In your nginx.conf (best practice is to create a sites-enabled conf that's a symlink to sites-available, and you can destroy that symlink whenever deploying) do the following:

location / {
    proxy_pass http://mymvcapp.com:80
}
location /api {
    proxy_pass http://mymvcapp.com:81
}

and then you'd set the correct IIS settings to have each site listen on ports 80 (mymvcapp) and ports 81 (api).

HAProxy

acl acl_WEB hdr_beg(host) -i mymvcapp.com
acl acl_API path_beg -i /api

use_backend API if acl_API
use_backend WEB if acl_WEB

backend API
server web mymvcapp.com:81

backend WEB
server web mymvcapp.com:80

*I'm issuing the Junction command from memory; I did this a few months ago, but not recently, so let me know if there are issues with the command

NB: the config files are not meant to be complete config files -- only to show the settings necessary for reverse proxying. Depending on your environment there may be other settings you need to set.

Community
  • 1
  • 1
George Stocker
  • 57,289
  • 29
  • 176
  • 237
  • 1
    Would it be possible to host the applications on separate servers using any of the methods you mentioned? – boosts Jun 12 '14 at 17:41
  • @bosts Yes. In that case you'd need to provide the IP/Hostname of the server you're proxying to. For instance, `proxy_pass http://anotherlocalserver.com:81` or `proxy_pass http://172.168.0.2:81`, which would be the IP address of that separate server. – George Stocker Sep 06 '19 at 17:39
  • You may face errors with child / sub / nested application because IIS tend to inherit web.config settings from parent to child folders / apps. You can fix that by wrapping parent config into location tag with inheritInChildApplications="false" attribute as mention in the link https://articles.runtings.co.uk/2010/04/solved-breaking-parent-webconfig.html. – Jackson Mar 08 '22 at 15:05