$30 off During Our Annual Pro Sale. View Details »

Isomorphic templating with Spring Boot, Nashorn and React

Isomorphic templating with Spring Boot, Nashorn and React

After an introduction presenting the upcoming Spring Framework 4.2 Script Templating support, this talk will show, with code samples, how to develop an application performing the same templates rendering on client AND server based on Spring Boot, Nashorn and Javascript based template engines like React (the latest game changer Javascript library released by Facebook).

The rendering of Javascript templates is performed initially on server-side thanks to a Spring MVC + Nashorn integration, then enriched on client side with a push mechanism (Websocket or Server-Sent Events).

This kind of isomorphic templating + the disruptive innovation brought by React with his virtual DOM mechanism make it possible to build a new kind of applications : responsive, with a great UX while being accessible.

Sébastien Deleuze

September 16, 2015
Tweet

More Decks by Sébastien Deleuze

Other Decks in Programming

Transcript

  1. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    SPRINGONE2GX
    WASHINGTON, DC
    Isomorphic templating with

    Spring Boot, Nashorn and React
    Sébastien Deleuze
    @sdeleuze

    View Slide

  2. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Agenda
    • Isomorphic?
    • Script based templating support in Spring
    • Handlebars support
    • What is React?
    • Isomorphic application with Spring and React
    • Demo
    • What’s next?
    2

    View Slide

  3. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Isomorphic?
    3

    View Slide

  4. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Isomorphic
    4
    Shared code that runs on both the client & server

    View Slide

  5. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Use cases
    • Templating - User interface
    • I18n
    • Application logic
    • Routing
    • Model validation
    5

    View Slide

  6. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Why?
    1. Performance
    • Initial pageload speed
    • Huge impact on mobile
    2. Maintainability
    • Share more code between client
    and server
    • A single technology to learn
    3. SEO - Accessibility
    • Make your site more crawlable and
    accessible
    6

    View Slide

  7. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Principle
    7
    Server Client
    Ȑ
    Content + UI
    Content + UI +

    DOM event listeners

    View Slide

  8. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Your website is …
    8
    Application

    centric
    Content

    centric

    View Slide

  9. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    GitHub as an example
    9

    View Slide

  10. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Script based templating

    support in Spring
    10

    View Slide

  11. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Support JSR 223 script engines
    11
    https://jira.spring.io/browse/SPR-12266: Support JavaScript Templating

    View Slide

  12. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Nashorn
    • Bundled with JRE 8+
    • Evolve fast
    • Min. requirement: Java 8u66
    12

    View Slide

  13. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Nashorn code sample
    13
    ScriptEngineManager manager = new ScriptEngineManager();

    ScriptEngine engine = manager.getEngineByName("nashorn");

    Invocable invocable = (Invocable)engine;


    String result = (String)invocable.invokeFunction("hello", "Brian");
    function hello(name) {

    return "Hello " + name;

    }

    View Slide

  14. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Available in Spring Framework 4.2
    14
    And in the upcoming Spring Boot 1.3 GA

    View Slide

  15. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Javascript based template engines
    15
    Mustache

    View Slide

  16. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Handlebars templates
    16


    {{title}}




    {{#each comments}}

    {{author}} {{content}}

    {{/each}}




    View Slide

  17. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Spring MVC controller
    17
    @Controller

    public class HandlebarsController {


    @RequestMapping(path = "/home", method = RequestMethod.GET)

    String home(Model model) {

    model.addAttribute("title", "Title example");

    List comments = Arrays.asList(

    new Comment("author1", "content1"),

    new Comment("author2", "content2"),

    new Comment("author3", "content3"));

    model.addAttribute("comments", comments);

    return "home";

    }

    }

    View Slide

  18. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Spring MVC controller revisited
    18
    @Controller

    public class HandlebarsController {


    @RequestMapping(path = "/home", method = RequestMethod.GET)

    Map home() {

    return hash(title -> "Title example",

    comments -> asList(

    new Comment("author1", "content1"),

    new Comment("author2", "content2"),

    new Comment("author3", "content3"))

    );

    }

    }
    View name guessed from the URL

    thanks to RequestToViewNameTranslator
    Hash literal using
    java 8u60 with
    -parameters and
    lambda type references

    View Slide

  19. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Spring MVC controller re-revisited
    19
    @Controller

    public class HandlebarsController {


    @Get("/home")

    Map home() {

    return hash(title -> "Title example",

    comments -> asList(

    new Comment("author1", "content1"),

    new Comment("author2", "content2"),

    new Comment("author3", "content3"))

    );

    }

    }
    spring-composed
    annotation based
    on @AliasFor
    https://github.com/sbrannen/spring-composed

    View Slide

  20. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Dependency Management
    20

    org.webjars

    handlebars

    3.0.0-1


    View Slide

  21. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Script based templating configuration
    21
    @Bean

    ViewResolver viewResolver() {

    ScriptTemplateViewResolver viewResolver = new ScriptTemplateViewResolver();

    viewResolver.setPrefix("/static/templates/");

    viewResolver.setSuffix(".html");

    return viewResolver;

    }
    View resolver

    View Slide

  22. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Script based templating configuration
    22
    @Bean

    ScriptTemplateConfigurer configurer() {

    ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();

    configurer.setEngineName("nashorn");

    configurer.setScripts("/static/polyfill.js",

    "/META-INF/resources/webjars/handlebars/3.0.0-1/handlebars.js",

    "/static/render.js");

    configurer.setRenderFunction("render");

    configurer.setSharedEngine(false);

    return configurer;

    }
    Configurer

    View Slide

  23. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Concurrency with Nashorn
    23
    • In web browsers, no simultaneous execution of your code
    • Nashorn itself is NOT thread-safe by design
    • The behavior depends of your Javascript code
    • Worth to read Nashorn Multithreading and MT-safety

    View Slide

  24. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    The sharedEngine property
    24
    • When sharedEngine is set to false, Spring uses
    ThreadLocal
    • Handlebars and React need sharedEngine=false
    • Mustache works perfectly with a single ScriptEngine (defaults)
    • Be careful on memory consumption

    View Slide

  25. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    polyfill.js
    25
    var window = {};

    View Slide

  26. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    render.js
    26
    /** String template: the template content
    Map model: the view model
    String url: the template url (since 4.2.2) **/
    function render(template, model, url) {

    // ...

    }


    // Since url is optional, you can also declare:
    function render(template, model) {

    // ...

    }

    View Slide

  27. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Handlebars render() implementation
    27
    var templates = {};


    function render(template, model, url) {

    var compiledTemplate;

    if (templates[url] === undefined) {

    compiledTemplate = Handlebars.compile(template);

    templates[url] = compiledTemplate;

    }

    else {

    compiledTemplate = templates[url];

    }

    return compiledTemplate(toJsonObject(model));

    }


    // Create a real JSON object from the model Map

    function toJsonObject(model) { … }

    View Slide

  28. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Model to JSON Object conversion
    28
    // Create a real JSON object from the model Map

    function toJsonObject(model) {

    var o = {};

    for (var k in model) {

    // Convert Iterable like List to real JSON array

    if (model[k] instanceof Java.type("java.lang.Iterable"))
    {

    o[k] = Java.from(model[k]);

    }

    else {

    o[k] = model[k];


    }

    }

    return o;

    }

    View Slide

  29. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Is it fast?
    29

    View Slide

  30. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Yes :-)
    30
    6000 page/s on my laptop

    View Slide

  31. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Spring MVC + Handlebars production ready ?
    31
    • Nice to use
    • handlebars-layouts
    • Easy to customize
    • Quite fast
    • Young stack
    • Latest Java 8 needed
    • Load partials from
    classpath
    nashorn.eval(new InputStreamReader(getClass().getResourceAsStream("file.js")));

    View Slide

  32. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Experiment, contribute!
    32
    https://github.com/sdeleuze/spring-boot-sample-web-handlebars

    View Slide

  33. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    What is React?
    33

    View Slide

  34. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    34
    • A Javascript library for building user interfaces
    • Component oriented
    • Not a full-stack framework
    • Virtual DOM diffing/updating
    • Server side rendering

    View Slide

  35. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    DOM diffing
    35
    http://techblog.constantcontact.com/software-development/reactive-component-based-uis/

    View Slide

  36. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    It’s Like Source Control for the DOM
    36

    View Slide

  37. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Before showing you JSX code …
    37

    View Slide

  38. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    React component: comment.js
    38
    var Comment = React.createClass({

    handleClick: function(event) {

    alert(this.props.content);

    },

    render: function () {

    return (


    { this.props.author }

    { this.props.content } 

    onClick={ this.handleClick }>View details »



    )

    }

    });

    View Slide

  39. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    JSX transformer
    39

    { this.props.author }

    { this.props.content } 

    onClick={ this.handleClick }>View details »


    React.createElement("div", {className: "col-md-4"}, 

    React.createElement("h2", null, this.props.author), 

    React.createElement("p", null, this.props.content, " "), 

    React.createElement("p", null,
    React.createElement("a", {className: "btn btn-default",
    href: "#", role: "button",
    onClick: this.handleClick}, "View details")
    )

    )

    View Slide

  40. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    The most interesting man in the world about JSX …
    40

    View Slide

  41. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    React component: comment-list.js
    41
    var CommentList = React.createClass({

    getInitialState: function () {

    return this.props;

    },

    render: function () {

    var commentNodes = this.state.comments.map(function (comment) {

    return content={ comment.content }

    key={ comment.id } />

    });

    return (


    { commentNodes }


    )}});


    React.render(,

    document.getElementById("comments"));

    View Slide

  42. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Isomorphic application

    with Spring and React
    42

    View Slide

  43. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Gradle configuration
    43
    apply plugin: 'java'

    apply plugin: 'spring-boot'

    plugins {

    id 'net.eikehirsch.react' version '0.3.1'

    }


    sourceCompatibility = 1.8

    targetCompatibility = 1.8


    dependencies {

    compile('org.springframework.boot:spring-boot-starter-web')

    compile('org.webjars:react:0.13.1')

    testCompile('org.springframework.boot:spring-boot-starter-test')

    }


    jsx {

    sourcesDir = 'src/main/resources/static/jsx'

    destDir = 'src/main/resources/static/output'

    }
    processResources.dependsOn('jsx')

    View Slide

  44. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Page composition
    44

    View Slide

  45. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Controller
    45
    @Controller

    public class CommentController {


    private CommentRepository commentRepository;


    @Autowired

    CommentController(CommentRepository commentRepository) {

    this.commentRepository = commentRepository;

    }


    @RequestMapping("/")

    String render(Model model) {

    model.addAttribute("title", "Layout example");

    model.addAttribute("comments", this.commentRepository.findAll());

    return "index";

    }

    }

    View Slide

  46. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    index.ejs
    46







    <%= React.renderToString(React.createElement(CommentForm)) %>






    <%= React.renderToString(React.createElement(CommentList, { comments: comments} )) %>







    <



    View Slide

  47. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Server side rendering
    47

    <%= React.renderToString(React.createElement(CommentForm)) %>









    Post comment



    View Slide

  48. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    client.js (client side rendering)
    48
    React.render(
    $.post('/', comment, null, ‘json'); }}/>,
    document.getElementById("navbar"));


    $.getJSON('/', function( data ) {

    React.render(,
    document.getElementById("comments"));

    });

    View Slide

  49. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Server and client side = same output
    49
    React re-render everything BUT:
    - No flickering thanks to Virtual DOM diff
    - React just attach the DOM listeners

    View Slide

  50. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    polyfill.js
    50
    var global = this;

    var console = {};

    console.debug = print;

    console.warn = print;

    console.log = print;

    View Slide

  51. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    render.js
    51
    function render(template, model) {

    var data = toJsonObject(model);

    return new EJS({text: template}).render(data);

    }

    View Slide

  52. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Issue: script duplication
    52







    configurer.setScripts("static/polyfill.js",

    "static/lib/js/ejs.min.js",

    "/META-INF/resources/webjars/react/0.13.1/react.js",

    "static/render.js",

    "static/output/comment.js",

    "static/output/comment-form.js",

    "static/output/comment-list.js");

    View Slide

  53. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    53
    Develop a Javascript module loader server extension

    that loads resources from the classpath
    nashorn.eval(new InputStreamReader(getClass().getResourceAsStream("file.js")));

    View Slide

  54. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    SSE (server)
    54
    @Controller

    public class CommentController {

    private final List sseEmitters = new ArrayList<>();


    @RequestMapping(path = "/", method = RequestMethod.POST, produces = "application/json")

    @ResponseBody

    Comment jsonCreate(Comment comment) throws IOException {

    Comment newComment = this.commentRepository.save(comment);

    for (SseEmitter sseEmitter : this.sseEmitters) {

    sseEmitter.send(newComment, MediaType.APPLICATION_JSON);

    }

    return comment;

    }


    @RequestMapping("/sse/updates")

    SseEmitter subscribeUpdates() {

    SseEmitter sseEmitter = new SseEmitter();

    this.sseEmitters.add(sseEmitter);

    sseEmitter.onCompletion(() -> {

    this.sseEmitters.remove(sseEmitter);

    });

    return sseEmitter;

    }

    }

    View Slide

  55. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    SSE (client)
    55
    var CommentList = React.createClass({

    componentDidMount: function() {

    var eventSource = new EventSource("/sse/updates");

    var self = this;

    eventSource.onmessage = function(e) {

    var comment = JSON.parse(e.data);

    var comments = self.state.comments;

    var newComments = comments.concat([comment]);

    self.setState({comments: newComments});

    };

    },

    // ...

    });

    View Slide

  56. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Demo
    56

    View Slide

  57. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    What’s next?
    57

    View Slide

  58. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    58
    EcmaScript 6

    View Slide

  59. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    59
    TypeScript
    TypeScript = EcmaScript 6

    + types + decorators (annotations) + …

    View Slide

  60. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    60
    Ember 2

    View Slide

  61. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    61
    Angular 2

    View Slide

  62. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    62
    Angular 2
    @Component({selector: 'my-app'})

    @View({template: 'Hi {{ name }}'})

    // Component controller

    class MyAppComponent {

    constructor() {

    this.name = 'Ali';

    }

    }

    View Slide

  63. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    63
    Routing
    Need to build a bridge between server side
    and client side routing …

    View Slide

  64. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    64
    Spring 5 draft roadmap for serverside JS
    • Builtin Java to JSON object conversion
    • JS logging on server side
    • Facilities to load content from filesystem/classpath
    • Script loader extension (classpath instead of Ajax request)
    • Ember2/Angular2/React support?
    • Spring beans accessible from Javascript?

    View Slide

  65. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    65
    Experiments and contributions welcomed!

    View Slide

  66. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    66
    Conclusion
    • Javascript evolves: ES6 - TypeScript
    • Javascript frameworks are becoming more mature: React -
    EmberJS 2 - Angular 2
    • Isomorphic applications provide a nice balance between server
    side rendering and Javascript based RIA
    • Develop your front-end skills and try by yourself!
    • The choice of the client side technology/software design is key
    differentiator for your project/product!

    View Slide

  67. Unless otherwise indicated, these slides are © 2013-2015 Pivotal Software, Inc. and licensed under a

    Creative Commons Attribution-NonCommercial license: http://creativecommons.org/licenses/by-nc/3.0/
    Thanks!
    67
    https://github.com/sdeleuze/spring-boot-sample-web-handlebars
    https://github.com/sdeleuze/spring-react-isomorphic
    @sdeleuze

    View Slide