Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is that a best practice to host WebApi as a seperate project

I am working on an Single Page Application with Web Api and Angular JS. I want to grab all the best practices for a great spa applications.

I want to know that is that a best practice to host Web Api project as a seperate project or just include with in same project along with your spa.

Thanks

like image 482
Ravi Mittal Avatar asked May 21 '15 11:05

Ravi Mittal


People also ask

Where Can Web API be hosted?

Web API can be hosted under IIS, in the same way as a web application. You have learned to create a Web API in the previous section. As you have seen there, a Web API is created with ASP.NET MVC project by default.

How can I use my Web API project from other projects inside my solution?

In order to add a Web API Controller you will need to Right Click the Controllers folder in the Solution Explorer and click on Add and then Controller. Now from the Add Scaffold window, choose the Web API 2 Controller – Empty option as shown below. Then give it a suitable name and click OK.


2 Answers

Should one host SPA independently from API?

If you need to scale the front-end independently from the back-end then go with a Content Delivery Network (CDN) that lets you use own domain name, has configurable caching policies and all other modern attributes like 100% SLA, etc.

Your concerns might be

  • Desynchronised deployment of the two essential parts of a single solution.
  • Extra resources (human-hours) to maintain the distributed infrastructure (another point of failure);
  • Trade-offs for delivering essential parameters to the front-end. Either
    • you make the front-end bundle mutable between staging environments and include the parameters or
    • you keep it immutable and need extra time on the start-up to fetch them.

I'd dismiss concerns regarding additional OPTIONS requests for CORS as HTTP/2 brings latency down to 0.

Hosting SPA from WebAPI wouldn't have those concerns (but doesn't allow independent scaling).

How to host SPA from .NET WebAPI?

When it comes to hosting a SPA from a .NET API, there are three extension methods that do all the heavy lifting (starting from .NET Core 2.x and it's still the case in .NET 5):

  • UseSpa serves the default page (index.html) and redirects all requests there.
  • UseStaticFiles serves other than index.html static files under the web root folder (wwwroot, by default). Without this method Kestrel would return index.html in response on all requests for static content.
  • UseSpaStaticFiles does a similar thing but it requires ISpaStaticFileProvider to be registered to resolve location of the static files. You need it if the static files are NOT under the default web root folder wwwroot.

To host SPA from wwwroot you need just UseSpa and UseStaticFiles methods.

Don't forget 2 important things:

  • caching policies for static assets;
  • injecting environment variables on serving the front-end.

So your Configure method in the Startup.cs may have the following additions:

// Serves other than 'index.html' files from wwwroot folder with a cache policy
app.UseStaticFiles(new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        var headers = ctx.Context.Response.GetTypedHeaders();
        headers.CacheControl = new CacheControlHeaderValue { MaxAge = TimeSpan.FromDays(12*30) };
    }
});
// Serves 'index.html' with no-cache policy and passing variables in a cookie
app.UseSpa(c => c.Options.DefaultPageStaticFileOptions = new StaticFileOptions
{
    OnPrepareResponse = ctx =>
    {
        var response = ctx.Context.Response; 
        response.GetTypedHeaders().CacheControl = new CacheControlHeaderValue
        {
            NoCache = true,
            NoStore = true,
            MustRevalidate = true,
            MaxAge = TimeSpan.Zero
        };
        // Passing a variable to SPA in a short-lived cookie
        response.Cookies.Append("importantVariable", "Value", new CookieOptions { MaxAge = TimeSpan.FromSeconds(30) });
    }
})

See more in this blog post that also considers other options. No problems modifying the index.html & static files for injecting variables if you don't favour cookies.

Also check out this open source project at GitHub that does the trick with hosting SPA and passing parameters in cookies (direct link to Startup configuration and reading cookies in Angular).

like image 59
Alex Klaus Avatar answered Nov 09 '22 16:11

Alex Klaus


I believe your best bet is to have the SPA into a separate project and even better a different repository, since this is more flexible and supports many different development/deployment scenarios, especially as your project grows bigger.

I personally started with the mixed files approach and moved to the separate Repos approach just days after the project went beyond the size of the Todos examples.

Some of the pros of having separate projects/repos are:

  • better search context for search/replace or goto file/class.
  • fewer files per project/solution so visual studio is not crawling to its knees.
  • you can use different editors, more easily, for your spa project if you get better support for javascript/typescript there than in VS (eg. webstorm).
  • file structure is more readable in the small solution explorer window since there is less nesting
  • different people can work independently on the frontend/backend
  • your SPA can have its own versioning and you can mix and match FE/BE versions as required
  • simpler continuous integration since you do not mix frontend/backend build steps
  • you can decide at deployment time if they are going to be hosted on
    the same host, or different machines (after enabling CORS support)
  • Finally it makes your SPA a first class citizen and not just a subfolder of your web api.

On the opposite side I cannot think of any advantage of having the SPA as a subfolder to the WebApi except maybe for very small projects that you want to keep complexity to a minimum.

like image 34
masimplo Avatar answered Nov 09 '22 15:11

masimplo