isomorphic templating with spring boot, nashorn and react

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/ SPRINGONE2GX WASHINGTON, DC Isomorphic templating with Spring Boot, Nashorn and React Sébastien Deleuze @sdeleuze

Upload: spring-by-pivotal

Post on 13-Apr-2017

4.073 views

Category:

Technology


1 download

TRANSCRIPT

Page 1: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

SPRINGONE2GXWASHINGTON, DC

Isomorphic templating withSpring Boot, Nashorn and React

Sébastien Deleuze

@sdeleuze

Page 2: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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

Page 3: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Isomorphic?

3

Page 4: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Isomorphic

4

Shared code that runs on both the client & server

Page 5: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Use cases

• Templating - User interface

• I18n

• Application logic

• Routing

• Model validation

5

Page 6: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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

Page 7: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Principle

7

Server Client

! "#

Content + UIContent + UI +

DOM event listeners

$ $

Page 8: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Your website is …

8

Applicationcentric

Contentcentric

%&

Page 9: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

GitHub as an example

9

Page 10: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Script based templatingsupport in Spring

10

Page 11: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Support JSR 223 script engines

11

https://jira.spring.io/browse/SPR-12266: Support JavaScript Templating

Page 12: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Nashorn

• Bundled with JRE 8+

• Evolve fast

• Min. requirement: Java 8u60

• Wait Java 8u66 if using React

12

Page 13: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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; }

Page 14: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Available in Spring Framework 4.2

14

And in the upcoming Spring Boot 1.3 GA

Page 15: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Javascript based template engines

15

Mustache

Page 16: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Handlebars templates

16

<html> <head> <title>{{title}}</title> </head> <body> <ul> {{#each comments}} <li>{{author}} {{content}}</li> {{/each}} </ul> </body></html>

Page 17: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring MVC controller

17

@Controllerpublic 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"; }}

Page 18: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring MVC controller revisited

18

@Controllerpublic class HandlebarsController { @RequestMapping(path = "/home", method = RequestMethod.GET) Map<String, ?> 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 URLthanks to RequestToViewNameTranslator

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

Page 19: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Spring MVC controller re-revisited

19

@Controllerpublic class HandlebarsController { @Get("/home") Map<String, ?> 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

Page 20: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Dependency Management

20

<dependency> <groupId>org.webjars</groupId> <artifactId>handlebars</artifactId> <version>3.0.0-1</version></dependency>

Page 21: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Script based templating configuration

21

@BeanViewResolver viewResolver() { ScriptTemplateViewResolver viewResolver = new ScriptTemplateViewResolver(); viewResolver.setPrefix("/static/templates/"); viewResolver.setSuffix(".html"); return viewResolver;}

View resolver

Page 22: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Script based templating configuration

22

@BeanScriptTemplateConfigurer 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

Page 23: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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

Page 24: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

The sharedEngine property

24

• When sharedEngine is set to false, Spring uses ThreadLocal<ScriptEngine>

• Handlebars and React need sharedEngine=false

• Mustache works perfectly a single ScriptEngine (defaults)

• Be careful on memory consumption

Page 25: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

polyfill.js

25

var window = {};

Page 26: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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) { // ...}

Page 27: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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) { … }

Page 28: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Model to JSON Object conversion

28

// Create a real JSON object from the model Mapfunction 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;}

Page 29: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Is it fast?

29

Page 30: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Yes :-)

30

6000 page/s on my laptop

Page 31: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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")));

Page 32: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Experiment, contribute!

32

https://github.com/sdeleuze/spring-boot-sample-web-handlebars'

Page 33: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

What is React?

33

Page 34: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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

Page 35: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

DOM diffing

35

http://techblog.constantcontact.com/software-development/reactive-component-based-uis/

Page 36: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

It’s Like Source Control for the DOM

36

Page 37: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Before showing you JSX code …

37

Page 38: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

React component: comment.js

38

var Comment = React.createClass({ handleClick: function(event) { alert(this.props.content); }, render: function () { return ( <div className="col-md-4"> <h2>{ this.props.author }</h2> <p>{ this.props.content } </p> <p><a className="btn btn-default » href="#" role=« button" onClick={ this.handleClick }>View details &raquo; </a> </p> </div> ) }});

Page 39: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

JSX transformer

39

<div className="col-md-4"> <h2>{ this.props.author }</h2> <p>{ this.props.content } </p> <p><a className="btn btn-default" href="#" role=« button" onClick={ this.handleClick }>View details &raquo;</a></p></div>

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") ) )

Page 40: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

The most interesting man in the world about JSX …

40

Page 41: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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 <Comment author={ comment.author } content={ comment.content } key={ comment.id } /> }); return ( <div className="comment-list"> { commentNodes } </div>)}});React.render(<CommentList comments={ data }/>, document.getElementById("comments"));

Page 42: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Isomorphic applicationwith Spring and React

42

Page 43: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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')

Page 44: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Page composition

44

Page 45: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Controller

45

@Controllerpublic 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"; }}

Page 46: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

index.ejs

46

<!DOCTYPE html><html lang="en"> <head><!-- ... --></head> <body> <nav class="navbar navbar-inverse navbar-fixed-top"> <div class="container"> <div id="navbar" class="navbar-collapse collapse"> <%= React.renderToString(React.createElement(CommentForm)) %> </div> </div> </nav> <div class="container"> <div id="comments" class="row"> <%= React.renderToString(React.createElement(CommentList, { comments: comments} )) %> </div> </div> <script src="lib/js/jquery.min.js"></script> <script src="lib/js/bootstrap.min.js"></script> <script src="webjars/react/0.13.1/react.js"></script> <script src="output/comment.js"></script> <<!-- ... --> </body></html>

Page 47: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Server side rendering

47

<div id="navbar" class="navbar-collapse collapse"> <%= React.renderToString(React.createElement(CommentForm)) %></div>

<div id="navbar" class="navbar-collapse collapse"> <form class="navbar-form navbar-right" data-reactid=".1ptxdrtnx2v" data-react-checksum="382509970"> <div class="form-group" data-reactid=".1ptxdrtnx2v.0"> <input placeholder="Your name" class="form-control" data-reactid=".1ptxdrtnx2v.0.0"></div> <div class="form-group" data-reactid=".1ptxdrtnx2v.1"> <input placeholder="Say something..." class="form-control " data-reactid=".1ptxdrtnx2v.1.0"> </div> <button type="submit" class="btn btn-success" data-reactid=".1ptxdrtnx2v.2">Post comment</button> </form></div>

Page 48: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

client.js (client side rendering)

48

React.render( <CommentForm onCommentSubmit={ function(comment) { $.post('/', comment, null, ‘json'); }}/>, document.getElementById("navbar"));$.getJSON('/', function( data ) { React.render(<CommentList comments={ data }/>, document.getElementById("comments"));});

Page 49: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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

Page 50: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

polyfill.js

50

var global = this;var console = {};console.debug = print;console.warn = print;console.log = print;

Page 51: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

render.js

51

function render(template, model) { var data = toJsonObject(model); return new EJS({text: template}).render(data);}

Page 52: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Issue: script duplication

52

<script src="lib/js/jquery.min.js"></script><script src="lib/js/bootstrap.min.js"></script><script src="webjars/react/0.13.1/react.js"></script><script src="output/comment.js"></script><script src="output/comment-list.js"></script><script src="output/comment-form.js"></script><script src="output/client.js"></script>

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");

Page 53: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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")));

(

Page 54: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

SSE (server)

54

@Controllerpublic class CommentController { private final List<SseEmitter> 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; }}

Page 55: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/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}); }; }, // ...});

Page 56: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Demo

56

Page 57: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

What’s next?

57

Page 58: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 58

EcmaScript 6

Page 59: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 59

TypeScript

TypeScript = EcmaScript 6+ types + decorators (annotations) + …

Page 60: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 60

Ember 2

Page 61: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 61

Angular 2

Page 62: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 62

Angular 2

@Component({selector: 'my-app'})@View({template: '<h1>Hi {{ name }}</h1>'})// Component controllerclass MyAppComponent { constructor() { this.name = 'Ali'; }}

Page 63: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 63

Routing

Need to build a bridge between server side and client side routing …

Page 64: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 64

Experiments and contributions welcomed!

Page 65: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/ 65

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!

Page 66: Isomorphic Templating with Spring Boot, Nashorn and React

Unless otherwise indicated, these s l ides are © 2013-2015 Pivotal Software, Inc. and l icensed under a Creat ive Commons Attr ibut ion-NonCommercial l icense: ht tp: / /creat ivecommons.org/ l icenses/by-nc/3.0/

Thanks!

66

https://github.com/sdeleuze/spring-boot-sample-web-handlebars'https://github.com/sdeleuze/spring-react-isomorphic'

@sdeleuze