2017-02-01



alvinashcraft
shared this story
from Angular First.



Derived from photo by jeanbaptisteparis / flickr.com, CC BY-SA

Coming from an ASP.NET background, developers are familiar with the File, New Project… experience. This is the process to setup a new project in Visual Studio – typically from a template to help you get started effectively.

These starter projects include everything in the box. They have UI rendering, authentication, sample data APIs, and more. And while they are great for getting started, they may not be the best design for the application you are building.

When it comes to building an Angular application, how should it integrate with the server-side application if at all? What design options are available to you and how do you know which is the right one? This is an often-overlooked topic in Angular-focused material. One the other end, server-side articles tend to encourage using server-side features without considering that you are using a very powerful front-end framework already.

This article details several application responsibilities and groups them in terms of their integration with the host application. For the purposes of this article, the host application is the server-side application that sits beneath your Angular application and serves it to the browser/client. (Spoiler alert, there might be NO application sitting beneath your Angular application.) The Angular application consists of the TypeScript and/or JavaScript you write against the Angular framework.

Level 0 – No Server Application

This level includes features that are configurable to have no server-side dependency. This means that when the application runs, Angular handles these features without requiring the server to process any of the logic. This configuration may be desirable especially when static file hosting is the preferred deployment option.

Even though there is no run-time server dependency, you can still leverage the power of a build to optimize your application. These are some of the features you can configure with no server-side backend.

Routing

The Angular router is optionally configured to use the hash URL style. In this configuration, each route is represented in the URL following the hash symbol, like example.com/#/about or example.com/#/products/1. The main benefit is that when someone enters this URL into the browser, they are going to the same endpoint each time, example.com. When the application loads, the router kicks in and navigates to the correct view.

Internationalization (i18n)

Angular includes utilities to internationalize applications. There are several phases to this process which you can read about in the documentation. At the end, you are left with multiple versions of your application that are deployed to their own directory as static files. At this point, there are several options for routing the user to the correct version of the application. The choice can be left to the user in the UI or the application can read the language settings in the browser to automatically route to the correct locale.

View Rendering

One of the first highlights of the Angular framework was its rendering. Being able to bind a JavaScript object to a template and see the data and events wire themselves up was almost magic. Angular accomplishes this in the browser and while server frameworks have their own rendering engines, you can generally rely on client-side rendering for your views when using Angular.

Level 1 – Host Application Integration

This level consists of functionality where the host application and the Angular application work together to produce the runtime functionality. While the server may not know intimately about the Angular application, both the server and client must be configured in a complimentary manner and make assumptions about the other's behavior.

Routing

As opposed to the hash style URL discussed earlier, the more common HTML 5 pushState style URL depends on server support. These URLs lack the hash symbol, for example example.com/about or example.com/products/1. The issue here is that when someone navigates to your application the first time using one of these URLs, the Angular application doesn't have a chance to handle the route. Instead, the server receives the request first and then returns the Angular application to the client to then complete the routing process. You can see an example with ASP.NET Core here.

Authentication

Sometimes, there are reasons to lock down your Angular application to only authorized users. While the Angular application could handle this based off of Web API authentication, you also have the option to authorize with the host application. For instance, the first time someone navigates to your web application, the server can return the 'not authorized' messaging without returning any of the Angular code to the browser.

View Rendering

As mentioned previously, Angular's rendering is more than capable of generating your application's UI. Generally, this rendering occurs in the browser. However, applications optimized for SEO and time-to-load performance, benefit from server-side rendering.

This is where Angular Universal fits in. Instead of using the server framework's view engine, Angular Universal renders Angular templates server-side. The browser receives the HTML and CSS to display the page immediately without client-side rendering. Subsequent views are loaded via AJAX and rendered on the client to reduce subsequent payload sizes. The framework supports both Node.js and ASP.NET Core backends.

Using Angular Universal does increase complexity and imposes certain restrictions in how you write your Angular application. Be sure that if you need this extra performance boost that you understand the trade-offs. Read more about it on GitHub.

Internationalization

Internationalization is an area where the host application may not have a direct role but may need to assist integrated routing, authentication, and/or rendering to provide the desired experience.

Logging

Logging also doesn't necessarily represent a tight integration between the host application and the Angular application. However, consider that as you increase the server's role with routing, authentication, and/or rendering, you should consider logging any errors resulting from this increased responsibility.

Level 2 – Web APIs

These dependencies are server-side dependencies. However, they do not have to live within the same web application hosting the Angular application. By keeping these dependencies in their own code base, there are many advantages. Builds and deployments are performed only for the applications that have changed. The APIs are built with whichever technology the team and/or company decide so long as it works over a common protocol – typically HTTPS. If you are familiar with the concepts of Web APIs and/or Microservices, this group encompasses those concepts.

Web APIs

Some examples of web API responsibilities that an application requires include data access, logging, and usage analytics. Interestingly, none of these concerns require any knowledge of the Angular application. In fact, they could serve many different front-end applications.

Authentication

Authentication at this level is typically handled directly between the Angular application client and the Web API server. There are many ways to do this but today's solutions generally use some form of JSON web tokens to maintain the user's identity.

Internationalization

At this level, any assets requiring i18n would be handled by the web API using server-side techniques. Again, this has no coupling to the Angular application beyond the API contract.

A Case for Bundling

Sometimes, applications are small and the API that they access is small. In this case, you may decide to keep this functionality together in the same application. They share the same build and the same deployment. Sometimes the effort to split these functions isn't greater than the payoff.

In this case, consider your development and design carefully as to avoid creating unnecessary coupling between the concerns. The web API may one day 'grow up' to need its own project so develop accordingly.

Final Thoughts

Every application is different. Hopefully by reading about how application concerns create dependencies between the server and the Angular application, you can apply these considerations to your own architecture.

One thing you might have noticed, there's no discussion of development tools that integrate with the server. This is a topic for a future post so stay tuned.

Ultimately, there is no one way to design an application. However, by knowing your options, you're better equipped to make lasting design decisions for your project.

What do you think? Is there functionality you prefer to run on the server? The client? Please share in the comments.

Show more