SPA with Angular, Web API (OWIN) as REST service with bearer token part 1

Mon Jul 13 2015

I'm working on a new project with a partner. He is the business guy, whilst I'm the tech guy. That means my partner has all the knowledge and knows what he wants, and I'm responsible to make it real.

This is a big opportunity to learn a lot of stuffs: I have experience in Web development, but mostly using server side rendering with ASP.Net Web forms and MVC. So, now I have the chance to learn and apply new techniques, especially with REST services and Single Page Applications (SPA).

By the way, I had worked with Angular, Web API and related tools before, but mostly on prototypes or for learning purposes. This will be my first real project using SPA, and I want to share a general review of what I have learned and applied during this months.

This article is for all the people who already knows the what, but they have doubts on the how. Web development is a huge world and there is a lot of tools on the space; this is a compendium of my prefered ones. Use it as a base, or feel free to comment on better alternatives.

Here is the source code of the article

The application

For the sake of simplicity, let's assume we need an application for doing CRUD on basic data. The application must contain the following features:

  • Full SPA. All is rendered on client side.
  • User authentication and sign up for new users.
  • Authorized users can create, modify or delete thoughts. A thought has a title, date and description.
  • An admin role which can modify data.

This simple application contains all what's required: an SPA application which communicates to a REST services, and manage role permissions.

Our solution will contain:

  • Angular: this Framework helps us to build SPA applications and contains all what's required: request injection for our authorization token, routing for different functionalities on client side, binding from models to user interfaces, http calls to server, and lot (a lot!) of other stuffs.

  • Web API 2: Web API is an excellent Framework to build HTTP services. It contains MVC-like routing (controller/action routes) and HTTP attribute routes, in case we want to declare our own API routing logic.

In our case, we will:

  1. Control whether the user is authenticated or not.
  2. When the user is authenticating, we call the REST service to log in. If log in is successful, the REST service returns a token. We save it.
  3. Apart from the token, the service returns the list of admitted roles for this user. We control user interface with those roles.
  4. Every call to REST service goes with the token, for authorization purposes.

Web API 2 has another very useful feature: it can be built without IIS dependencies by using OWIN. This means you can run your REST service as a self-hosted application (a console application, a Windows service, etc.). This allows us to have multi-tenancy services: if you want you can start different instances of the service, in case you have a lot of clients accessing it. The more clients, the more independent instances. Now you don't need to have different IIS servers hosting your REST service (which maybe implies to upload different Windows Servers). Consider this as a first step to upload your REST service to a cloud provider like Amazon or Windows Azure.

This is thanks to the Open Web Interface for .Net (OWIN), a standard interface between .Net Web servers and Web applications. The technical details are beyond this article, but in general you can consider OWIN an interface for developing Web applications by wrapping HTTP requests and responses; your REST service or Web application uses a standard object in which you traduce your actions to HTTP commands, and can use a common framework to get data (like with HTTP Requests).

Here is an excellent article from John Atten where he explains what is OWIN and the Middleware. Also, check the Rack project and their definition on Wikipedia. OWIN is based on almost all the ideas from Ruby Rack, so a little look at this project will give you a broad understanding of the Web Interface and the OWIN Hash.

Materials and tools

Hardware

Have you heard the phrase "The shoemaker's son goes barefoot"? This applies exactly in my case: I do not have a super powerful computer to code, whether I would like to have one.

In my case, I have a relatively old laptop (4-5 years old) with 4 Gb RAM and an AMD A6 APU CPU which runs four cores at 1.4 Ghz. The only upgrade made is the hard drive, from an 560 Gb/5330 rpm to an 250 Gb SSD.

With this arrangement I'm able to run all my tools without problems and, I must admit, It's really fast. The big plus in this case is the SSD hard drive. Before that, my laptop runs very slow. A 5300 rpm HDD is really a bottleneck in this case.

If you have some budget and you want to upgrade your computer, my recommendation is to consider an SSD hard drive, instead of buying a new one. The gaining is considerable.

Consider this configuration as a threshold: If you have something similar then all the required tools should run without problems.

Server side

Visual Studio 2013

For server side we're going to use Visual Studio 2013, which comes with .Net 4.5.1. The last .Net Framework is 4.5.2 (4.6 is Release Candidate at present), so I recommend you to download and install the latest framework version.

Apart from that we do not need additional tools, since everything else is covered by using NuGet.

Client side

On client side we have a lot of options. So much, that overwhelms new developers. In this case my recommendations are:

Node Js

Node is a platform built on the Chrome javascript engine. This means that you can create applications in javascript, using all the power of this runtime engine. In this case, we're going to use node in order to install other tools for client side management.

First, go to https://nodejs.org/download/ and install the runtime.

Bower package manager

If NuGet is the package manager for .Net libraries, Bower does the same for Web. With this, is super easy to share a project, specifying the Web dependencies on a simple file. Thanks to that, you don't need anymore to share your project along with all the required libraries or CSS files. Just configure your dependencies in the bower.json file, and execute the install prior to use the application.

To install Bower, open a DOS-like console and execute:


  npm install -g bower
  

npm is the Node Package Manager, a little tool from Node (installed in the previous section) which helps us to install different tools that runs on the Node runtime.

Later we're going to use Bower for our project.

Sublime Text 3

Sublime Text 3 is one of the best text editors out there. It's super fast and easy to use. I do not hesitate in recommend this excellent editor.

Perhaps a new developer does not see at first what's the benefit of using this editor instead of others (or Visual Studio for instance), but once you start to use it and get accustomed, when coding HTML and javascript it starts to shine.

Here is the download page for Sublime.

Emmet for Sublime

Emmet is a plugin which improves HTML and CSS development. Once you start to use it you can accelerate the coding. For example, if you need to code a table like this:


    <table>
      <thead>
        <tr>
          <th></th>
          <th></th>
        </tr>
      </thead>
      <tbody>
        <tr>
          <td></td>
          <td></td>
        </tr>
        <tr>
          <td></td>
          <td></td>
        </tr>
        <tr>
          <td></td>
          <td></td>
        </tr>
      </tbody>
    </table>
  

Emmet can make all this with one single line command:


  table>(thead>tr>th*2)(tbody>(tr>td*2)*3)
  (then press [tab] key)

This command tells Emmet to:

  • Create a table.
  • Inside the table, create a thead with an tr and two th.
  • After thead, create a tbody with three tr, each one having two td.

Emmet is super fast and easy to use. Before that, I had to copy and paste every required tr. Now I just need to understand what elements do I need and code them with the Emmet syntax.

CSS class on HTML? Properties on elements, or text? Sure:


  ul.myUlClass.secondUlClass>(li.liClass>a[href="http://myurl"]{My text})*3
  (then press [tab] key)
The result:

  <ul class="myUlClass secondUlClass">
    <li class="liClass"><a href="http://myurl">My text</a></li>
    <li class="liClass"><a href="http://myurl">My text</a></li>
    <li class="liClass"><a href="http://myurl">My text</a></li>
  </ul>

Here is the documentation for Emmet.

To install Emmet on Sublime Text 3, you first need to install Package Control. The steps are:

  1. Go to Package Control and copy the text under Sublime Text 3 Tab.
  2. Under Sublime, go to View -> Show Console. A little console window opens on Sublime.
  3. Paste the text from point 1 on the console. Press Enter.
  4. After the installation, restart Sublime.

Once installed, now we need to install Emmet. The instructions are here:

  1. Open Command Palette in Sublime (press Control + Shift + P).
  2. Select "Install Package" option: the Command Palette has a type ahead search, so write "Install" up until appears the option.
  3. Wait a few seconds. The Palette will appear again. Write and install Emmet.

That's it. Once installed, all your html files are covered by this tool.

JSHint

As Javascript is a scripting language, it cannot be analyzed on compile time, like C#, Java, C or others. It's a big problem if you make a mistake, which cannot be found until you test it on the javascript runtime (on node or your preferred browser). JSHint prevents this issue by analyzing potential problems in your Javascript code.

For example, this code:


  if(true) {
     console.log(Hello, World!);

Here we have two problems:

  1. We forgot to close the if branch.
  2. We forgot to use quotes on the string.

JSHint helps us to identify this problems:

JSHint

If you move the cursor to each one of the errors, the tool explains the problem:

JSHint JSHint

It's extremely necessary to analyze our codes, specially if we're going to code a lot on client side.

To install JSHint for Sublime Text, we first need to install the JSHint tool. Open a DOS-like console and execute:

npm install -g jshint

Then, we need to install the SublimeLinter-jshint plugin for Sublime Text 3:

  1. Open Command Palette in Sublime (press Control + Shift + P).
  2. Select "Install Package" option: the Command Palette has a type ahead search, so write "Install" up until appears the option.
  3. Wait a few seconds. The Palette will appear again. Type jshint, search for SublimeLinter-jshint and install it.

Once installed, you need to configure the linter. In this configuration you define how strict JSHint has to be.

Here in this gist file you can check my JSHint configuration. Just download that file and save it on your home account with the name jshint.conf. On Windows 8.1 it will be C:\Users\YourAccount\jshint.conf.

Source code versioning

Source code versioning is a must today. I know people who are still saving their codes on zip files, one for each release. The big problem with that is how to determine the changes, get the differences between them and revert or apply corrections.

In this case, my recommendation is to install and use git.

Git and versioning is a whole complete concept, between branch, commit, pull, pulls, etc. Unfortunately It's beyond this article, but please, consider to use it for your source code versioning.

Step 1: create folder and initialize git repository

Ok, now we are ready to start. First, we need to create the base structure for our project. Open a DOS-like console and execute:


  cd c:\your\prefered\folder
  mkdir Thoughts
  cd Thoughts
  git init
  mkdir src
  mkdir dist

This first step helps us to create a folder for the project, and to initialize an empty Git repository. It's recommended to do this before anything, because once we create the project, Visual Studio is capable to detect the git repository, adding all the required ignores to avoid committing binary or unnecessary files.

The src and dist folders will contain the source code and published projects, respectively.

Step 2: Visual Studio project

Open Visual Studio and create a new Blank solution:

File -> New -> Project...

Visual Studio Blank solution

Close Visual Studio and go to C:\Your\Project\src. You can see that Visual Studio created a new Folder called Thoughts.

  • Move the Thoughts.sln (located in src\Thoughts\) to src (one folder up).
  • Then delete the Thoughts folder.

One of the things that I don't like is that Visual Studio always creates a folder, even for blank projects.

After that, you have a single .sln file under src folder:

Solution

Double click on the .sln file. Now we are again on Visual Studio.

Create a new project for the REST API:

File -> Add -> New Project...

Select the .Net Framework 4.5.2 and under Web select ASP.Net Web Application (select C# as languaje). Call it Thoughts.API.

Solution

In the next section, select Empty project and check on Web API. This option will creates a very basic Web API template.

Solution

Now, create another project for the Web application:

File -> Add -> New Project...

Select the .Net Framework 4.5.2 and under Web select ASP.Net Web Application. Call the project Thoughts.Web.

In the next section, select an Empty template. Do not select Web API nor other option on the Add folders and core references for.

Solution

Now, we will update all the references for the project. This is one of the benefits of .Net and the NuGet package manager.

Under Visual Studio, go to Tools -> Library Package Manager -> Package Manager Console and write


  Update-Package

This command searches for new versions of the library, updating them if applies.

Apart from that, we're going to install other libraries, required for our project. Under NuGet Package Manager Console write for the Thoughts.API project:


  Install-Package Microsoft.Owin.Cors [Enter]
  Install-Package Microsoft.Owin.Host.SystemWeb [Enter]
  Install-Package Microsoft.Owin.Security.OAuth [Enter]
  Install-Package Microsoft.AspNet.Identity.EntityFramework [Enter]
  Install-Package Microsoft.AspNet.Identity.Owin [Enter]
  Install-Package Microsoft.AspNet.WebApi.Owin [Enter]
  • Microsoft.Owin.Cors: Enable CORS (Cross Origin Resource Sharing). This allows our Javascript applications to access external services, like our API. Before CORS we had to use JSONP, which isn't a very clever solution.
  • Microsoft.Owin.Host.SystemWeb: Enable hosting of our application on IIS.
  • Microsoft.Owin.Security.OAuth : Middleware that enables an application to support any standard OAuth 2.0 authentication workflow.
  • Microsoft.AspNet.Identity.EntityFramework: ASP.NET Identity providers that use Entity Framework.
  • Microsoft.AspNet.Identity.Owin: Owin implementation for ASP.NET Identity.
  • Microsoft.AspNet.WebApi.Owin: Host ASP.NET Web API within an OWIN server.

Step 3: Create the basic Web structure

Now we need to start our Web project. First, we need to initialize Bower in our project to manage our required Javascript and CSS libraries. Open a DOS-like console and go to your project folder:


  cd c:\your\prefered\folder\Thoughts\src\Thoughts.Web
  bower init

After some time, bower would ask you some questions. Just press [Enter] to select default options, except in "would you like to mark this package as private...". Select y.

After that, you should have a bower.json file on your folder with your configured project. Now we need to install our libraries:


  bower install --save angular
  bower install --save angular-route
  bower install --save angular-local-storage
  bower install --save bootstrap
  • angular: the SPA framework.
  • angular-route: routing to link controllers and views on client side.
  • angular-local-storage: we use it to save data on LocalStorage (HTML5), specifically for our authentication token.
  • bootstrap: CSS framework for user interface.

Now, you can see we have a new folder: bower_components. This folder contains the new dowloaded files through Bower package manager.

For our Web project, the structure will be (create these folders, together with the files):


  index.html
  app\app.js
  app\controllers\
  app\controllers\homeController.js
  app\controllers\indexController.js
  app\directives\
  app\services\
  app\services\authService.js
  app\views\
  app\views\home.html
  content\site.css

For now, we will write basic files to simulate authentication. index.html is the entry point for our SPA application, whilst app.js has the initial configuration for our application. Both files are important as they define how we start to use it, especially app.js which defines services and routing, in our case.

Here you should decide which user interface fits for your requirements, or the graphical structure for the application. In this case, I get some structure from HTML5 Boilerplate project, a simple template with some basic structure which helps to start your project ASAP.

index.html


<!DOCTYPE html>
<html lang="en" ng-app="thoughtsApp">
<head>
    <meta charset="utf-8">
    <meta name="keywords" content="" />
    <meta name="description" content="" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>Thoughts</title>
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
    <link rel="stylesheet" type="text/css" href="/bower_components/bootstrap/dist/css/bootstrap.min.css">
    <link rel="stylesheet" type="text/css" href="/content/site.css">
</head>
<body>
  <nav class="navbar navbar-default" ng-controller="indexController">
    <div class="container-fluid">
      <div class="navbar-header">
        <button type="button" data-toggle="collapse" data-target="#navGeneral" class="navbar-toggle collapsed">
          <span class="sr-only">Navigation</span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
          <span class="icon-bar"></span>
        </button>
        <h1>Thougths</h1>
      </div>
      <div id="navGeneral" class="collapse navbar-collapse navbar-right" ng-if="authService.isAuthenticated">
        <ul class="nav navbar-nav">
          <li>
            <a href="#/thoughts"><i class="glyphicon glyphicon-check"></i> Thoughts</a>
          </li>
          <li>
            <a href="" ng-click="logOut()"><i class="glyphicon glyphicon-log-out"></i> Logout</a>
          </li>
        </ul>
      </div>
    </div>
  </nav>
  <div class="container">
    <div id="content">
      <div ng-view></div>
    </div>
  </div>
  <script src="/bower_components/jquery/dist/jquery.min.js"></script>
  <script src="/bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
  <script src="/bower_components/angular/angular.js"></script>
  <script src="/bower_components/angular-route/angular-route.js"></script>
  <script src="/app/app.js"></script>
  <script src="/app/services/authService.js"></script>
  <script src="/app/controllers/homeController.js"></script>
  <script src="/app/controllers/indexController.js"></script>
</body>
</html>

Here we have a lot of information. Let's see:


  <html lang="en" ng-app="thoughtsApp">

Here we define our HTML as an Angular application, named thoughtsApp.


  <nav class="navbar navbar-default" ng-controller="indexController">

This section is associated in thoughtsApp with the indexController controller. We use it to control menu and links, whether the user is or not authenticated. Check all the structure and you will see HTML elements, rendered if certain conditions are met:


  <div id="navGeneral" class="collapse navbar-collapse navbar-right" ng-if="authService.isAuthenticated">

Or course, authService.isAuthenticated must be an object inside indexController.


    <div class="container">
    <div id="content">
      <div ng-view></div>
    </div>
  </div>

This part is the core of our application: ng-view is used by angular-route to render in this HTML element all the content from the views.


  <script src="/bower_components/jquery/dist/jquery.min.js"></script>
  ...
  <script src="/app/controllers/indexController.js"></script>

Here we add the javascript dependencies (our app, controllers, libraries, etc.).

app\app.js


var app = angular.module('thoughtsApp', ['ngRoute']);
app.config(function ($routeProvider) {
    $routeProvider
    .when('/home', {
        controller: 'homeController',
        templateUrl: '/app/views/home.html'
    })
    .otherwise({ redirectTo: '/home' });
});

As you can see, this file declares the application name (thoughtsApp), together with the routing information. We declared a watcher for the /home url, related with the homeController controller and the home.html view.

app\controllers\homeController.js


app.controller('homeController', [function () {
}]);

This is the simplest way to declare an Angular controller in our application. This controller does nothing at the time.

app\controllers\indexController.js


app.controller('indexController', ['$scope', 'authService', function ($scope, authService) {
  $scope.authService = authService;
  $scope.logOut = function() {
    authService.logOut();
  };
}]);

The indexController is very different. Here we declare functions and dependencies.

At first, we declare the controller as in the homeController. Apart from that, it declares some dependencies:


  ['$scope', 'authService', function ($scope, authService)

Angular has a dependency system very simmilar to require.js, in which you declare your dependencies, and then they are 'injected' as parameters in the function. In this case we have two dependencies:

  • $scope: we use it to declare variables and functions which can be seen in the view.
  • authService: it's our service, located on services\authService.js. We use it to get some authentication information.

As you can see, we have a variable ($scope.authService) and a function (logOut). Both elements are used in the view to control user access:


  <div id="navGeneral" class="collapse navbar-collapse navbar-right" ng-if="authService.isAuthenticated">
  ...
  <a href="" ng-click="logOut()"><i class="glyphicon glyphicon-log-out"></i> Logout</a>

That way we can communicate our views with the model.

app\services\authService.js


  app.factory('authService', [function () {
    var authService = {
        isAuthenticated: true,
    };

    authService.logOut = function() {
      this.isAuthenticated = false;
    };

    return authService;
}]);

Here we declare a factory named authService, which controls the user authentication. This file declares isAuthenticated as true, which means we're faking an authenticated user once we start our app.

app\views\home.html


  Home.html page

A simple HTML page.

Now, we can run our page and see the result. If you do not have an HTTP server to host your page, just open a DOS-like console and execute:


  npm install -g http-server

Once installed, go to your\project\src\Thought.Web\ and execute:


  http-server .

Now, with your preferred browser we will see our new application (if you're using http-server you have to go to http://localhost:8080)

App

If the client clicks on "Logout" the application simulates the logout procedure

App

Step 4: Commit your changes

This is the final step for this article. Now we will commit our project on Git.

First, edit the .gitignore file, located in c:\your\prefered\folder\Thoughts. This file was created automatically by Visual Studio, and define which files and folders should be ignored.

Add the following ignores at the end of the file:


  bower_components/
  packages/
  • bower_components/: used by the Bower package manager.
  • packages/: used by NuGet package manager.

As we ignored the packages/ folder, we need to add the src\packages\repositories.config file. Open a DOS-like console, go to your project folder and write:


  git add src\packages\repositories.config -f  

Now, under the project folder press right button and select Git Commit -> "master".... Select all the files and add a comment for your commit.

Git

Source code

You can get a copy of the codes on https://github.com/jparaya/spa-angular-web-api/. I will update this repository, adding releases per article. In case you don't know how to use this, I'm going to explain step by step, from cloning until you have the application working.

Download using git

Git is the preferred way. For this, open a DOS-like console and execute:


  git clone https://github.com/jparaya/spa-angular-web-api.git
  cd spa-angular-web-api
  git checkout part1

The first line clone the existing repository, whilst the third changes to the part1 tag. This tag contains all the codes explained in this article. Keep in mind that later I will commit more codes for the next part of the article, so don't lose with additional codes and use this tag.

Download the release

If you do not want to use Git, just download a copy of the release and unzip it on your preferred folder.

Downloading dependencies

Now, open the project by double click on src\Thoughts.sln. Visual Studio will open.

This project only has the packages\repositories.config and Thoughts.Web\bower.json files, so we first need to download dependencies.

  • For Visual Studio: Compile the solution (Control + Shift + B). Visual Studio will download the required dependencies for you, magically.
  • For Web: in your console, go to src\Thoughts.Web\ and write: bower install. Bower will check the bower.json file, downloading required dependencies.

Now you're ready to start. As easy as it is to share your projects with this tools.

Final words

This is an extremely extensive article, from step to step. The next parts will go more faster than this, because we already have the base and we know (I hope, please practice) what's our structure.

I hope you enjoy this article, as much as I do writing it. I have a friends who know what's Angular and Web API, but unfortunately they don't know how to start. I hope this article will guide them up until they feel comfortable coding on this new tools and platforms.

I hope the second part of the article will be ready in one or two more weeks.

Greetings!

comments powered by Disqus