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
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.
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.
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
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):
index.html
) and redirects all requests there.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.wwwroot
.To host SPA from wwwroot
you need just UseSpa
and UseStaticFiles
methods.
Don't forget 2 important things:
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).
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:
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With