SPA Questions | John Papa

John Papa

Evangelist on the loose

SPA Questions

...

I’m taking my own advice here and responding to some frequently asked questions I receive on SPA on my blog. I get some of these a lot and it just makes sense that I aggregate them and share for discussion. The questions are all good and they cover a variety of experiences. Hopefully by sharing them, they will be of benefit to others.

I encourage you to also chime in with your comments if you have more to add or have other questions.

Q1: Is SPA the future web trend?

SPA has been around for years, but recently it has gained a lot of momentum. It is an emerging area, for sure. However, the reasons businesses are attracted to it usually come down to its 3 core aspects:

  • Reach
  • Reduced Round Tripping
  • Rich User Experience

I think the web trend is more accurately depicted by achieving these 3 R’s.

Q2: How do you secure a Web APIs for a SPA?

Web API can certainly be secured and the good news is that some of the ASP.NET MVC / SPA templates demonstrate this. Specifically, check out the SPA template that comes with VS 2012.2 Update mentioned here. There are a variety of ways to implement security, this is one. You can also implement security at the method level.

    [Authorize]
    [ValidateHttpAntiForgeryToken]
    public class TodoController : ApiController
    {
        // Controller methods go here
    }

The anti forgery attributes are also worth considering, if that suits you. Check out the SPA template and the Breeze SPA template for more concrete details.

Q3: Can anyone query for any server-side data?

Only if you allow them to. If you have data that should not be queryable, don’t make it queryable. Lock down sensitive data like you would in any app. Most samples and demos will show what you can do but making Web API methods IQueryable. There are huge benefits to making the data flexible like this, but when specific data should be locked down, absolutely do that. One way to limit data is to remove IQueryable and construct the exact query on the server. You can also use a specific RPC like action in your Web API. Yet another way is to use IQueryable on a method, but have it return a projection of the data (return all fields and rows except the sensitive ones). The bottom line is that security is still important and is still placed on the developer’s shoulders to follow the requirements.

Q4: Does SPA work only with a .NET back-end?

SPA works on the client, so it works with any web server technology. It works great with a .NET back end, and my preference is an ASP.NET back end. However you can absolutely use PHP, Java, Azure cloud service, or a node.js server (just a few examples). The key concept here is reach: SPA allows for a multitude of devices and client browsers regardless of the back end. You can hook to any of them and call web services through AJAX.

Q5: Which core libraries should I choose for SPA?

Durandal with Knockout, Angular, Ember, and Backbone are just a few solid choices.The key is in picking one that suits you. I prefer Durandal with Knockout because I believe it is easy to follow, scales well, is easy to build on, doesn’t try to do too much, and has a great data binding core (which I prefer). Angular is another library I like as it has similar qualities. If you have time, it is certainly worth looking into these and choosing your favorite. They all have pros and cons and very different styles. There are other choices too, like Batman or CanJS.

The key is not to get hampered by choosing, but to choose one that fits for you, your project, your team, and allows you to build on it. You can always choose another one later for your next project :)

Q6: Which core libraries do you recommend?

I prefer the combination of Durandal and Knockout along with some others like Breeze and toastr. If you install HotTowel you will get my core list of preferences.

Q7: Does Hot Towel work with ASP.NET (no MVC) ?

Yes, but you will want the NuGet package named HotTowelette. Hot Towel is designed for ASP.NET MVC while Hot Towelette is designed for ASP.NET without MVC. The libraries and App JavaScript are the same in both. The only differences are in using MVC routing vs a startup HTML page. In fact, both use ASP.NET razor, web optimization, and Web API too.

Q8: How much data should be pushed to the client in a SPA?

These are the determining factors in how much data to send to the client in an initial page:

  • Data that will be displayed for that first page
  • Lookup list data for any drop downs on that page
  • Data that is required for and presentation rules

On a view that would show a list of recipes, I would get the recipes and some key factors to display (like recipe name, the dish, and other key info) that can be displayed in a list. Enough for the user to make a determination on what to pick. Then when the user dives into a recipe, then go get that 1 recipe’s details.

The general rule is get what you user will almost certainly need up front. Then get other data as they request it.

Q9: Why doesn’t Hot Towel include more examples?

It’s the difference in my mind of a template and a sample. Hot Towel is a template to build on. A sample would include more example code (that would be ripped out later by you).

When I built the Hot Towel template I had a focus on providing enough to get folks going with the right tools, and just enough starter code to guide the way. I did not want anyone ripping out code. I’m not a fan of templates that start you down a path and make you remove tons of files and code and change direction. Those are samples.

Samples are good. In fact, samples can be excellent (like the other templates, which I feel are more like samples). Those serve another purpose: to show how you can do things.

Back to the Hot Towel template …if I include code that uses Breeze, I would be tempted to add a datacontext.js and a model.js on the client. They would contain data access code and code to extend the models on the client. Then I would be tempted to add a controller, some server-side models, an ORM and a database. Once there, I’d want to use the data in multiple screens, which leads me to more Knockout and caching with Breeze. Then I might be tempted to add editing, which would lead to change tracking. Soon I have a full-blown app. Or more conservatively, I have a sample again. While these approaches would provide more guidance on how to put these together, they would not help you “get started” with a template where you can just start building and adding your own code. If I stop short of some of these features, it’s still walking down a road that requires you to change how I did it.

As it stands today, Hot Towel is pretty darn close to a template in the truest sense. You create a new project and you are off and adding your own code.

You could argue (and you may be) that Breeze shouldn’t be in there since I don’t use it in the template. Nor do I use moment.js, BTW. However, I argue that they are both excellent libraries that I would not want to build a CRUD based SPA without them.

tags: faq SPA
  • Patrick

    Good info. I think some of the confusion can be derived from comparing the Hot Towel template to the SPA with HTML5, KnockOut, etc… on PluralSight. Hopefully the next course this month will clear some of that confusion up.

    In my opinion, it really takes going through the previous course all the way to the end, making notes along the way of modules to go back and watch, and then building onto the Hot Towel template from that point as opposed to trying to build an app while you watch the course. I made this mistake, so hopefully someone can learn from me : )

    • John

      Patrick – That’s good feedback. Ideally, Hot Towel and my new course would have been released the same day. Hot Towel was inspired by my new course, but as this is my moonlighting job I didn’t have time to get it all ready in time.

      Yes, I agree that my end to end courses are best watched, then re-watched to build. This is my learning style. I like to watch first, then go re-watch and do it with the instructor. The new course should allow you to write all the code with me

  • Pingback: SPA Questions | WebDevStuff | Scoop.it

  • Mohamed Omar

    Thanks John for sharing all of these questions but for enriching the discussion, Do you think that SPA is suitable for many business scenarios, especially LOB apps, some apps which contains back-end for generating changing front-end content etc…

    • John

      Mohamed – Certainly can use SPA for that. It’s just another option along with WPF, strict ASP.NET MVC, PHP, etc. The caveat is always “if done properly”, which basically means use it for what its good and don;t fit it into a bad spot (like if you need heavy device interaction, then WPF is awesome … just 1 example.)

  • Marco

    Thank you for the clarification!

    I’ll do my CBT (My end of course work in computer science, as we speak here in Brazil), and your courses are my base to develop my final project.

    And surely I’ll be using the Hot Towel template in my next projects.

    Thanks again,

    Muito obrigado.

    • Marco

      Just correcting, I meant TCC(Trabalho de conclusão de curso) and not CTB;)

  • James

    I’m trying to add a simple SignalR Hub in the Hot Towel template, without success. Can you help? I’ve done it before lots of time, but the dynamic proxy just seems impossible to be referenced in this case.

    • John

      James – sounds like a route might be interfering. Take a look a the routes on the server and see if that is the issue.

  • http://blog.developers.ba Radenko

    Hi John. Nice post.

    I wanted to ask you how to handle security (antiforgerytoken) without ASP.NET MVC/ WEB API in my SPA so I can use it inside PhoneGap as well ?

    If I use some server side functionality from ASP.NET MVC I cannot deploy SPA into PhoneGap easily ?

    • Ward Bell

      Can you explain how CSRF is a threat in a PhoneGap app? My impression was that the attack required two different web sites in the same browser. Didn’t think that was possible in a PhoneGap app. A link to this threat to PhoneGap apps would help us all understand better.

  • http://www.calabonga.com Calabonga

    thanks! some answers were helpful!

  • http://oscarmeszar.com Oscar

    Hi John, as always good stuff.

    You are addressing in Q9 the question that I see asked by people as I travel the web. I, myself, also thought it would have been nice to have a working sample.

    However, I agree with your statement that Hot Towel is a template. People shouldn’t have to rip anything out as they use the template in their application.

    I decided to create a small tutorial that shows how to integrate the Breeze database access with your template. The tutorial is basically a marriage of the Breeze Web Api NuGet sample with the Hot Towel NuGet template.

    People can find the tutorial here http://oscarmeszar.com/hottowel-with-breeze-example/

    Of course, my small tutorial doesn’t compare to what we have coming in your Pluralsight course. I can’t wait to watch it.

  • Bart Calixto

    Can I suggest you to add comments to the Template on where to put code, and which codes?

    something like: // here you app logic, // here your bindings, // here your functions (save, delete) etc..

    I think it isn’t quite evident ‘where’ to put code using breeze, where to place extra js like datacontext, where to manage the manager. If not using breeze, where to map the viewmodel from controller into knockout on first load, what one should expect on the activate method.
    Comments could be very helpful to see the bigger picture.

    Having breeze included, which currently support EF and Web Api, I guess should be good to also consider adding comments guiding users to create an ApiController, DbContext and breeze client datacontext js with some best practices.

    The template is GREAT, and I know you are doing a tutorial right now which will fulfill the need for the ‘example’ missing, but I think will be difficult for someone to start if you just did MVC before and you want to learn how to spa, Durandal, Breeze, AMD, requirejs, Knockout, Q, Web Api it’s a lot of literature. I can’t even imagine how to get the team involved… any guide in how to motivate a team that did little javascript but lot of c# code is appreciated :D

  • Sławek

    I wonder how should I address page access restrictions. In MVC I can just decorate my action controller with Authorize attribute. Another question how to manage with resources/localization.

  • Walt Daniels

    John, I’ve been following the whole SPA progression since it was included as a project template with vs2012 beta. I really like what I’ve seen, and the work you’ve done is amazing. However, I do have some reservations that maybe you could help with. The items are basically validation and Html Helpers. I know that sounds vague, let me clarify. There are a lot of features baked into MVC that I would like to take advantage of, especially the Html helper classes. We use the Html.EditorFor and the Html.ValidationMessageFor to render the appropriate HTML controls to input data and display validation messages. This all occurs “automatically” and is directly tied to the MVC view’s model (through DataAnnotations, etc). These are (to me) important benefits to enterprise application developers. However, when implementing Ajax-based CRUD operations, where data is serialized to JSON, you tend to loose these capabilities … I feel like all of the Client-Side validation and validation messaging that is provided by MVC is lost to SPA and Ajax. Am I missing something? Is there some magical component that I’m just not aware of that ties all of this together? Or, am I forced to hand-write the validation code for the client?

    • John

      Walt – the validation you do with MVC in Razor is server side. Some of it can help generate client side validation, too. I always recommend to put validation on the server, and then add it to the client, for user experience reasons. You aren’t losing Razor with SPA, but you are handling the presentation differently. This means the validation needs to be refactored for SPA too. There is no magical component that makes Razor validate SPA clients … though that is a great idea for the ASP.NET team :)

  • Dat

    Hi John,

    You did a great job. I really enjoyed your course. However, I’m a bit confused about role of data context on client side. As you said in the course, it acts as repository in the client. However, looking into the code, I think that the actual repository for the client is the EntitySet. The data service somewhat likes the DbSet on the server and data context on the client is the DbContext. Although I know they are not the same concepts, please help me to clarify. And, do you think we should apply same server architecture to client (such as Repository, Unit of work pattern, etc)?

    Thanks,
    Dat

    • John

      Dat – I find it easier to think of the data context as a place to abstract all data manipulation. I dont worry too much if I have a repo or UoW exactly like the server. Yes or no, it doesnt change that the pattern works well. I do believe that you can use those on the client with the datacontext and breeze if you like, but again, its up to you and your app.

  • Dat

    Thanks for quick reply John.

    Another question that I’m concerning is about RepositoryFactories and RepositoryProvider classes. I’m not very clear with role of each class, why should we create a IRepositoryProvider and inject it using IoC instead of injecting RepositoryFactories directly? And further, why shouldn’t we inject repositories themselves instead of injecting IRepositoryProvider (in CodeCamperUow)?

    Also, in the base EFRepository class we have:

    public EFRepository(DbContext dbContext)
    {
    if (dbContext == null)
    throw new ArgumentNullException(“dbContext”);
    DbContext = dbContext;
    DbSet = DbContext.Set();
    }
    I just wonder, should I pass in DbSet to the constructor instead of DbContext because calling DbContext.Set() is a little tight coupling and it will be hard to unit test the repository.

    Thanks,
    Dat

  • Nick

    Hello John,

    I am following your courses on pluralsight. I am wanting to use your hot towel template for building a SPA. However the server and the client need to run seperately from each other. Besides the server (Web API) needs to be consumed by other applications as well. Is it possible and recommended to go to the server directly from with a single page application?

    What would be your approach? Others may react as well please.

    • http://www.breezejs.com Ward Bell

      Yes you can serve the client app assets from one location and get data from a different location … but only if your server is setup to cooperate.

      The fundamental obstacle is that browsers adhere to the “Same Origin Policy” (http://en.wikipedia.org/wiki/Same_origin_policy) which prohibits cross origin AJAX requests.

      You can circumvent this restriction with JSONP or CORS. A discussion of these technologies is out-of-scope for a comment. I can say that(a) CORS is my preferred approach and (b) the BreezeJS samples demonstrate a simple CORS technique. Please not that said demo is an illustration of the potential, not a prescription for you.

      Expect the Breeze folks to elaborate over the coming months. For the here and now I hope it is sufficient to take heart that it is possible … if not right our of the box.

      • Nick

        Hello Ward,

        Many thanks for your reaction. I have found out about CORS and JSONP however it seems that CORS is not supported in every browser (for example IE8). My other problem is authentication is it possible to use authentication when using a breeze controller in combination with CORS.

        My other option is to build a WEB API on the server and make a WEB API in the client application that gets the servers information using a HttpClient, what do you think of this approach, it feels like repeating myself but it also feels safer than a Cross Origin Request.

        Maybe I should not use a single page application at all as it may not be the best choice in my architecture, but I would love to learn and make one myself.

        Thanks, In advance!

        Greetings, Nick

  • Alex

    Hi John!

    Do you have a recommended approach for managing client-side session state when a user clicks browser’s refresh button?

    I am planning to use localstore to store key session info with very short expiration from window.onunload, and then rebuild the session in window.onload. However, I am wondering if there is a better/simpler solution.

    • John

      Alex – If you want to protect the user from a browser failure, closing, or forced page refresh yu can use local storage. I think that is a fine choice. Cloud based storage is also an option. Depends on what you have available and what you need to protect your users from.

  • Dat

    Hi John,

    In RequireJS website, they recommend us not to define a name for a module:

    “You can explicitly name modules yourself, but it makes the modules less portable — if you move the file to another directory you will need to change the name.”

    So I just want to understand the reason why would you choose to explicitly define name for module in Code Camper?

    Thanks,
    Dat

    • John

      Dat – I did this in the first code camper because I wanted to bundle and minify on my own and not use require for that. I was also trying to use require for all dependency resolution. In my new course I dont name them nor do I use require for 3rd party modules, which frankly makes it a ton easier and more portable overall. It’s still good to know both ways, but for most apps, I recommend using unnamed modules and loading as I do in the SPA JumpStart

  • Sarah

    Hi!
    I’m loving working wth the hot towelette template. I’m sorry if this isn’t the proper forum for this question, but here goes: the only issue I’m having that I can’t seem to find or come up with a solution to is using javaScript in a details view. Specifically, I’m using the twitter bootstrap carousel in my home.html file, and inserting the javaScript like this into my home.js file:

    define(['services/logger'], function (logger) {
        var vm = {
            activate: activate,
            title: 'Home View'
        }; 
        return vm; 
        function activate() {
            logger.log('Home View Activated', null, 'home', false);
            return true;
    
    
        };
        $(window).load(function () {
            $('#myCarousel').carousel({
                interval: 2500
            }); 
        }); 
    });
    

    I’ve tried rearranging the javaScript several different ways- without anything extra, just the

    $('#myCarousel').carousel({
                interval: 2500
            }); 
    

    The issue I’m having is the carousel doesn’t play. If I click the next button, it activates the carousel. Is there a simple solution I’m missing, here?

    S

    • John

      Sarah – Thanks, i am glad you enjoy it!

      Check out Durandal’s DOM interaction section in their documentation. You can either hook up your jquery/$ code in the viewAttached event or you can create a knockout binding handler (preferred way). The issue is that you need the viewmodel to wait for the DOM to be ready before you can run your bootstrap/jquery code.

      http://durandaljs.com/documentation/Interacting-with-the-DOM/

  • Dat

    Hi John,

    I find it is completely suitable for implementing small web application (about ~10 views) using SPA. However, with larger and more complicated application (may be 100 views or more), initially loading all views isn’t very reasonable. So, is there any best practice to implement large application using SPA?

    Thanks,
    Dat

  • Mike

    Hi John,

    Any thoughts on how I could make a SPA application multi tenant? Is it even possible?

    Thanks

    • Rob Hudson

      I have this same question

  • Eliran Kononowicz

    Hi John,

    Is it possible to use HotTowel with a PHP backend? I’ve seen your pluralsight course and was wondering how I could implement the data retrieval with PHP MVC instead of .NET. Does breeze work with PHP?

    • Ward Bell

      Yes a BreezeJS client could work with PHP. There are examples today of Breeze working with Node/Mongo and with Ruby. PHP is just another target. Unfortunately we don’t have a PHP example. If you want to take on the challenge, I’d look at the Ruby sample first and borrow ideas. The folks at Breeze may be able to help when/if you get stuck.

  • David McClelland

    In ASP.NET MVC web apps, I have been accustomed to “centralizing” formatting concerns using DataAnnotations – so for example if I have an object Foo with a property Amount that has the DataAnnotation [DisplayFormat(DataFormatString = “{0:c}”)], then I know that all pages which use Html.DisplayFor(foo => foo.Amount) will render the same formatting for this field. How could I accomplish this same type of centralized formatting in a single page application?

    • johnpapa7

      David – I dont normally put formatting in the model as I feel that th formatting is a presentation concern and there are times when the same data field should be presented differently in the UI. That said, I can see why folks do it and I have no issue with it either. In a SPA I dont see as straight-forward of a way to do that. You could use the Angular filter in the HTML, of course http://docs.angularjs.org/api/ng.filter:currency

  • sam jack

    Do you have example with java as backend to review? I need to use this with java as backend.

%d bloggers like this: