React, Client를 넘어 Server-Side에서 활용하기

(Isomorphic)
KSUG 2015 Seminar

Modern Java web application with Spring 

정성용
Whoami
$ SK planet (2012~)

$ bungubbang57@gmail.com

$ facebook.com/sungyong.jung
and
2014 04 05
Isomorphic
동형 : 同形(같은 모양)
같은 모양 같은 형태를 공유
ServerSide와 ClientSide가 같은 코드를 사용해서 개발
Javascript template Library으로

Viewtemplate 및 Client를 개발
Q1 >

nodejs에서 개발하면 isomorphic 한것인가?
같은 Language가 아니라 같은 Code를 공유해야 함
(개인적인 Isomorphic 범위에 대한 생각)
No!
Server Rendering 와 Browser Rendering 간의
Code 및 Skill set이 다르다면 isomorphic하다가 할수 없다
Spring에서 View를 표현하는 방법
대다수의 View
View template jQuery
HTML 구성 및 Data-Binding 등

대부분의 View를 View template을 이용해 개발 후,

이벤트만 jQuery로 관리
Spring에서 View를 표현하는 방법
Javascript Library 위주
View template
AngularJS
HTML틀만 View Template으로 구성하고

서버와의 API통신을 통해 대부분의 View구성 및 Data-Biding, Event를

Javascript Library를 사용해서 구성하는 방법
ReactJS
jQuery Mobile
어떤 방식을 더 선호 하시나요?
Javascript Library 위주View Template 위주
VS
어떤 방식을 더 선호 하시나요?
Javascript Library 위주View Template 위주
VS
•	기능 및 특징에 따른 다양한 

Library들이 존재

•	다양한 Data-Binding 지원

•	View Components의 재활용

•	Components간 다양한 이벤트 

적용가능

•	독립적인 개발 및 테스트 용이

• 최근 가장 Trendy한 기술이기

때문에 릴리즈가 활발
•	서버에서 연산 작용

- 속도의 효율성

•	검색엔진에 해당 내용을 

노출할수 있다. 

- SEO 최적화

•	민감한 API를 노출 하지

않아도 된다.

- 보안
•	서버에서 연산 작용

- 속도의 효율성

•	검색엔진에 해당 내용을 

노출할수 있다. 

- SEO 최적화

•	민감한 API를 노출 하지

않아도 된다.

- 보안

Isomorphic 장점
•	기능 및 특징에 따른 다양한 

Library들이 존재

•	다양한 Data-Binding 지원

•	View Components의 재활용

•	Components간 다양한 이벤트 

적용가능

•	독립적인 개발 및 테스트 용이

• 최근 가장 Trendy한 기술이기

때문에 릴리즈가 활발
+
Q2 >

둘다 장점을 적절히 섞어 사용할 수 있었지 않냐?
하나의 View Library만 학습하면 된다.
같은 View 를 그릴때 Server와 Client에서의 코드 재활용이 가능 하다.
초기화면에서 필요한 내용들은 Thymeleaf를 사용하고 Browser에서 React로 그리면 된다!?
Q3 >

Spring ViewTemplate도 충분히 Data-Binding 및
View재활용을 할 수있지 않나?
최초로 페이지를 그릴때
View Template과 JS View Lib는 기능상의 큰 차이점은 찾기
힘들다.
이후 이벤트에 의해서 페이지를 그려질때
Isomorphic한 개발 만이 Server에서 ViewTemplate을 그릴때 썼
던 코드 그대로, Client에서 재활용할 수 있다. ReactJS나
Angular를 사용했다면 Component 재활용 및 Event 역시 손쉽게
다시 적용 할 수 있다.
Spring에서 ScriptTemplate 사용하기
Spring에서 ScriptTemplate 사용하기
Requirements
Java 8 +
Java8부터 Nashorn(Javscript Engine: JSR 223)이 도입되면서

Script template 기술이 가능해 졌음
SpringFramework 4.2+ or Spring boot 1.3+
ScriptTemplateConfig지원
Spring + MustacheJS
Server Template 사용
Spring에서 ScriptTemplate 사용하기
Spring + MustacheJS
https://github.com/bungubbang/spring-mustache-isomorphic-example
@Bean

public ScriptTemplateConfigurer mustacheConfigurer() {

ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();

configurer.setEngineName("nashorn");

configurer.setScripts(

"/META-INF/resources/webjars/mustache/2.1.2/mustache.js",

"/static/js/render.js");

configurer.setRenderFunction("render");

return configurer;

}
Spring에서 ScriptTemplate 사용하기
https://github.com/bungubbang/spring-mustache-isomorphic-example
@Controller

public class MustacheViewController {

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

public String index(Model model) {

model.addAttribute("title", "KSUG 2015 Web Seminar");

model.addAttribute("subject", "Spring Isomorphic example");

return "index";

}

}
Spring + MustacheJS
Spring에서 ScriptTemplate 사용하기
https://github.com/bungubbang/spring-mustache-isomorphic-example
function render(template, model) {

// Create a real Javascript Object from the model Map

var data = {};

for (var k in model) {

// Convert Java Iterable and List to real Javascript arrays

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

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

} else { // String, Float, Date , etc..

data[k] = model[k];

}

}

return Mustache.render(template, data);

}
Spring + MustacheJS
Spring에서 ScriptTemplate 사용하기
https://github.com/bungubbang/spring-mustache-isomorphic-example
<html>

<body>

<h1>KSUG 2015 Web Seminar</h1>

<h2>Spring Isomorphic example</h2>

</body>

</html>
<html>

<body>

<h1>{{title}}</h1>

<h2>{{subject}}</h2>

</body>

</html>
Spring + MustacheJS
Spring + Handlebars
Client 전용 View Library 사용
Spring에서 ScriptTemplate 사용하기
Spring + Handlebars
https://github.com/bungubbang/spring-handlebars-isomorphic-example
@Bean

public ScriptTemplateConfigurer handlebarsConfigurer() {

ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();

configurer.setEngineName("nashorn");

configurer.setScripts(

“/static/js/polyfill.js”,

"/META-INF/resources/webjars/handlebars/4.0.2/handlebars.js",

"/static/js/render.js");

configurer.setRenderFunction(“render");

configurer.setSharedEngine(false);

return configurer;

}
Spring에서 ScriptTemplate 사용하기
Polyfill
(https://en.wikipedia.org/wiki/Polyfill)
오래된 브라우져에 최신 기능(HTML5등)을 작동 가능하도록 만드는 기술
예) html5shiv.js, json2.js, es5-shim
Javascript in Java(Nashorn) vs Javscript in browser
Browser의 특성을 사용한 Javascript Library 코드가 Nashorn에서 에러가

발생하지 않도록 설정한 파일
1. Nashorn 에는 window 객체가 없다.

• console.log, document, location 등의 function을 지원 하지 않음

2. Nashorn에서는 Java Object를 이용 할 수 있다.

• Java Type 및 Class 이용 가능
Spring에서 ScriptTemplate 사용하기
polyfill.js
(https://en.wikipedia.org/wiki/Polyfill)
Mustache
var window = {};

ReactJS
var global = this;

var console = {};

console.debug = print;

console.warn = print;

console.log = print;
Spring에서 ScriptTemplate 사용하기
SharedEngine
Nashorn은 Thread Safe하지 않게 설계되어있다.

ScriptTemplate에서는 View 및 Engine을 재활용(Cache)하여 사용한다.
false로 설정하게 되면 내부적으로 ThreadLocal을 사용해서 engine을 공유하지 않고,

request마다 새롭게 만들게 script engine을 생성하게 된다.
HandleBars, React등은 Thread Safe하지 않기때문에 (전역변수 사용)

false로 설정해야 한다.
https://blogs.oracle.com/nashorn/entry/nashorn_multi_threading_and_mt
Javascript Template Library가 Tread Safe한지 확인후 사용해야 함
Spring에서 ScriptTemplate 사용하기
Spring + Handlebars
https://github.com/bungubbang/spring-handlebars-isomorphic-example
function render(template, model) {

// Create a real Javascript Object from the model Map

var data = {};

for (var k in model) {

// Convert Java Iterable and List to real Javascript arrays

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

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

} else { // String, Float, Date , etc..

data[k] = model[k];

}

}

var compiledTemplate = Handlebars.compile(template);

return compiledTemplate(data);

}
Spring + React(with ejs)
Spring + React(with ejs) Example
https://github.com/bungubbang/spring-react-isomorphic-example
Spring에서 ScriptTemplate 사용하기
Spring + React
https://github.com/bungubbang/spring-react-isomorphic-example
@Bean

public ScriptTemplateConfigurer reactConfigurer() {

ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer();

configurer.setEngineName("nashorn");

configurer.setScripts(

"/static/js/polyfill.js",

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

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

“/static/js/render.js",

“/static/output/music.js”, // 이하 ReactJS component files

“/static/output/music-list.js”,

“/static/output/music-search.js”,

“/static/output/music-more.js");

configurer.setRenderFunction(“render");

configurer.setSharedEngine(false);

return configurer;

}
Spring에서 ScriptTemplate 사용하기
Spring + React
<%= React.renderToString

<MusicApp />

<MusicSearch />

<MusicList />

<MusicItem />

<MusicMore />

%>
index.ejs
• Server rendering

• React Dom으로 구성된 View를 내려줌
<MusicSearch />
<MusicList />

<MusicItem />
<MusicMore />
Spring에서 ScriptTemplate 사용하기
Spring + React
React.render

<MusicApp />

<MusicSearch />

<MusicList />

<MusicItem />

<MusicMore />

init.js
• Client rendering

• 한번 더 Render를 호출하지만 React 특성상 DOM을 다시 그리지 않고,

기존에 적용 되지 않았던 이벤트만 추가하게 됨 (Virtual DOM)
검색 이벤트
상세페이지 이동 이벤트
리스트 추가 이벤트
ScriptTemplate 아쉬운점
configurer.setScripts(

"/static/js/polyfill.js",

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

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

“/static/js/render.js",

“/static/output/site-list.js”,

"/static/output/site.js");
1. folder import기능이 없다.

- Ordering 문제때문이지 않을까? 

하지만 숫자를 붙여서라도 import가 되면 좋겠다.

2. path별 설정기능이 없다.

- 특정 주소별로 사용하는 js파일까지 일단 전부 import해야 한다.

JS가 많아 질수록 초기 로드 속도가 느려질 뿐만 아니라, 

관리를 함에 있어 어려움이 발생.

setScript(…)
결론
• Isomorphic은 Spring에 국한된 기술이 아니다.

• Meteor, Vaddin 등 Isomorphic한 Framework 이 등장되어지고 있다.

• NodeJs, Django, RoR 등의 기존 Famework의 Isomorphic 지원이 개발되
었거나, 개발되어지고 있는 중이다.

• Isomorphic을 통해서 Spring ViewTemplate들이 발빠르게 지원
하지 못했던 기능들을 다양한 Javascript Library을 통해서
View를 구성해 볼 수 있는 기회가 열렸다.

• Viewtemplate의 삼국지 -> 춘추 전국시대의 도래

• 트렌드를 이끄는 다양한 Javascript Library가 계속해서 등장
함에 따라 앞으로 Isomorphic기술은 더욱 유용성이 높아 질 것
이다.

Isomorphicspring Isomorphic - spring web seminar 2015

  • 1.
    React, Client를 넘어Server-Side에서 활용하기 (Isomorphic) KSUG 2015 Seminar Modern Java web application with Spring 정성용
  • 2.
    Whoami $ SK planet(2012~) $ bungubbang57@gmail.com $ facebook.com/sungyong.jung and 2014 04 05
  • 3.
    Isomorphic 동형 : 同形(같은모양) 같은 모양 같은 형태를 공유 ServerSide와 ClientSide가 같은 코드를 사용해서 개발 Javascript template Library으로 Viewtemplate 및 Client를 개발
  • 4.
    Q1 > nodejs에서 개발하면isomorphic 한것인가? 같은 Language가 아니라 같은 Code를 공유해야 함 (개인적인 Isomorphic 범위에 대한 생각) No! Server Rendering 와 Browser Rendering 간의 Code 및 Skill set이 다르다면 isomorphic하다가 할수 없다
  • 5.
    Spring에서 View를 표현하는방법 대다수의 View View template jQuery HTML 구성 및 Data-Binding 등 대부분의 View를 View template을 이용해 개발 후, 이벤트만 jQuery로 관리
  • 6.
    Spring에서 View를 표현하는방법 Javascript Library 위주 View template AngularJS HTML틀만 View Template으로 구성하고 서버와의 API통신을 통해 대부분의 View구성 및 Data-Biding, Event를 Javascript Library를 사용해서 구성하는 방법 ReactJS jQuery Mobile
  • 7.
    어떤 방식을 더선호 하시나요? Javascript Library 위주View Template 위주 VS
  • 8.
    어떤 방식을 더선호 하시나요? Javascript Library 위주View Template 위주 VS • 기능 및 특징에 따른 다양한 Library들이 존재 • 다양한 Data-Binding 지원 • View Components의 재활용 • Components간 다양한 이벤트 적용가능 • 독립적인 개발 및 테스트 용이 • 최근 가장 Trendy한 기술이기
 때문에 릴리즈가 활발 • 서버에서 연산 작용 - 속도의 효율성 • 검색엔진에 해당 내용을 노출할수 있다. - SEO 최적화 • 민감한 API를 노출 하지 않아도 된다. - 보안
  • 9.
    • 서버에서 연산 작용 -속도의 효율성 • 검색엔진에 해당 내용을 노출할수 있다. - SEO 최적화 • 민감한 API를 노출 하지 않아도 된다. - 보안 Isomorphic 장점 • 기능 및 특징에 따른 다양한 Library들이 존재 • 다양한 Data-Binding 지원 • View Components의 재활용 • Components간 다양한 이벤트 적용가능 • 독립적인 개발 및 테스트 용이 • 최근 가장 Trendy한 기술이기
 때문에 릴리즈가 활발 +
  • 10.
    Q2 > 둘다 장점을적절히 섞어 사용할 수 있었지 않냐? 하나의 View Library만 학습하면 된다. 같은 View 를 그릴때 Server와 Client에서의 코드 재활용이 가능 하다. 초기화면에서 필요한 내용들은 Thymeleaf를 사용하고 Browser에서 React로 그리면 된다!?
  • 11.
    Q3 > Spring ViewTemplate도충분히 Data-Binding 및 View재활용을 할 수있지 않나? 최초로 페이지를 그릴때 View Template과 JS View Lib는 기능상의 큰 차이점은 찾기 힘들다. 이후 이벤트에 의해서 페이지를 그려질때 Isomorphic한 개발 만이 Server에서 ViewTemplate을 그릴때 썼 던 코드 그대로, Client에서 재활용할 수 있다. ReactJS나 Angular를 사용했다면 Component 재활용 및 Event 역시 손쉽게 다시 적용 할 수 있다.
  • 12.
  • 13.
    Spring에서 ScriptTemplate 사용하기 Requirements Java8 + Java8부터 Nashorn(Javscript Engine: JSR 223)이 도입되면서 Script template 기술이 가능해 졌음 SpringFramework 4.2+ or Spring boot 1.3+ ScriptTemplateConfig지원
  • 14.
  • 15.
    Spring에서 ScriptTemplate 사용하기 Spring+ MustacheJS https://github.com/bungubbang/spring-mustache-isomorphic-example @Bean public ScriptTemplateConfigurer mustacheConfigurer() { ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer(); configurer.setEngineName("nashorn"); configurer.setScripts( "/META-INF/resources/webjars/mustache/2.1.2/mustache.js", "/static/js/render.js"); configurer.setRenderFunction("render"); return configurer; }
  • 16.
    Spring에서 ScriptTemplate 사용하기 https://github.com/bungubbang/spring-mustache-isomorphic-example @Controller publicclass MustacheViewController { @RequestMapping(value = "/", method = RequestMethod.GET) public String index(Model model) { model.addAttribute("title", "KSUG 2015 Web Seminar"); model.addAttribute("subject", "Spring Isomorphic example"); return "index"; } } Spring + MustacheJS
  • 17.
    Spring에서 ScriptTemplate 사용하기 https://github.com/bungubbang/spring-mustache-isomorphic-example functionrender(template, model) { // Create a real Javascript Object from the model Map var data = {}; for (var k in model) { // Convert Java Iterable and List to real Javascript arrays if (model[k] instanceof Java.type("java.lang.Iterable")) { data[k] = Java.from(model[k]); } else { // String, Float, Date , etc.. data[k] = model[k]; } } return Mustache.render(template, data); } Spring + MustacheJS
  • 18.
    Spring에서 ScriptTemplate 사용하기 https://github.com/bungubbang/spring-mustache-isomorphic-example <html> <body> <h1>KSUG2015 Web Seminar</h1> <h2>Spring Isomorphic example</h2> </body> </html> <html> <body> <h1>{{title}}</h1> <h2>{{subject}}</h2> </body> </html> Spring + MustacheJS
  • 19.
    Spring + Handlebars Client전용 View Library 사용
  • 20.
    Spring에서 ScriptTemplate 사용하기 Spring+ Handlebars https://github.com/bungubbang/spring-handlebars-isomorphic-example @Bean public ScriptTemplateConfigurer handlebarsConfigurer() { ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer(); configurer.setEngineName("nashorn"); configurer.setScripts( “/static/js/polyfill.js”, "/META-INF/resources/webjars/handlebars/4.0.2/handlebars.js", "/static/js/render.js"); configurer.setRenderFunction(“render"); configurer.setSharedEngine(false); return configurer; }
  • 21.
    Spring에서 ScriptTemplate 사용하기 Polyfill (https://en.wikipedia.org/wiki/Polyfill) 오래된브라우져에 최신 기능(HTML5등)을 작동 가능하도록 만드는 기술 예) html5shiv.js, json2.js, es5-shim Javascript in Java(Nashorn) vs Javscript in browser Browser의 특성을 사용한 Javascript Library 코드가 Nashorn에서 에러가 발생하지 않도록 설정한 파일 1. Nashorn 에는 window 객체가 없다. • console.log, document, location 등의 function을 지원 하지 않음 2. Nashorn에서는 Java Object를 이용 할 수 있다. • Java Type 및 Class 이용 가능
  • 22.
    Spring에서 ScriptTemplate 사용하기 polyfill.js (https://en.wikipedia.org/wiki/Polyfill) Mustache varwindow = {}; ReactJS var global = this; var console = {}; console.debug = print; console.warn = print; console.log = print;
  • 23.
    Spring에서 ScriptTemplate 사용하기 SharedEngine Nashorn은Thread Safe하지 않게 설계되어있다. ScriptTemplate에서는 View 및 Engine을 재활용(Cache)하여 사용한다. false로 설정하게 되면 내부적으로 ThreadLocal을 사용해서 engine을 공유하지 않고, request마다 새롭게 만들게 script engine을 생성하게 된다. HandleBars, React등은 Thread Safe하지 않기때문에 (전역변수 사용) false로 설정해야 한다. https://blogs.oracle.com/nashorn/entry/nashorn_multi_threading_and_mt Javascript Template Library가 Tread Safe한지 확인후 사용해야 함
  • 24.
    Spring에서 ScriptTemplate 사용하기 Spring+ Handlebars https://github.com/bungubbang/spring-handlebars-isomorphic-example function render(template, model) { // Create a real Javascript Object from the model Map var data = {}; for (var k in model) { // Convert Java Iterable and List to real Javascript arrays if (model[k] instanceof Java.type("java.lang.Iterable")) { data[k] = Java.from(model[k]); } else { // String, Float, Date , etc.. data[k] = model[k]; } } var compiledTemplate = Handlebars.compile(template); return compiledTemplate(data); }
  • 25.
  • 26.
    Spring + React(withejs) Example https://github.com/bungubbang/spring-react-isomorphic-example
  • 27.
    Spring에서 ScriptTemplate 사용하기 Spring+ React https://github.com/bungubbang/spring-react-isomorphic-example @Bean public ScriptTemplateConfigurer reactConfigurer() { ScriptTemplateConfigurer configurer = new ScriptTemplateConfigurer(); configurer.setEngineName("nashorn"); configurer.setScripts( "/static/js/polyfill.js", "/static/lib/ejs.min.js", "/META-INF/resources/webjars/react/0.13.3/react.js", “/static/js/render.js", “/static/output/music.js”, // 이하 ReactJS component files “/static/output/music-list.js”, “/static/output/music-search.js”, “/static/output/music-more.js"); configurer.setRenderFunction(“render"); configurer.setSharedEngine(false); return configurer; }
  • 28.
    Spring에서 ScriptTemplate 사용하기 Spring+ React <%= React.renderToString <MusicApp /> <MusicSearch /> <MusicList /> <MusicItem /> <MusicMore /> %> index.ejs • Server rendering • React Dom으로 구성된 View를 내려줌 <MusicSearch /> <MusicList /> <MusicItem /> <MusicMore />
  • 29.
    Spring에서 ScriptTemplate 사용하기 Spring+ React React.render <MusicApp /> <MusicSearch /> <MusicList /> <MusicItem /> <MusicMore /> init.js • Client rendering • 한번 더 Render를 호출하지만 React 특성상 DOM을 다시 그리지 않고,
 기존에 적용 되지 않았던 이벤트만 추가하게 됨 (Virtual DOM) 검색 이벤트 상세페이지 이동 이벤트 리스트 추가 이벤트
  • 30.
    ScriptTemplate 아쉬운점 configurer.setScripts( "/static/js/polyfill.js", "/static/lib/ejs.min.js", "/META-INF/resources/webjars/react/0.13.3/react.js", “/static/js/render.js", “/static/output/site-list.js”, "/static/output/site.js"); 1. folderimport기능이 없다. - Ordering 문제때문이지 않을까? 
 하지만 숫자를 붙여서라도 import가 되면 좋겠다. 2. path별 설정기능이 없다. - 특정 주소별로 사용하는 js파일까지 일단 전부 import해야 한다.
 JS가 많아 질수록 초기 로드 속도가 느려질 뿐만 아니라, 
 관리를 함에 있어 어려움이 발생. setScript(…)
  • 31.
    결론 • Isomorphic은 Spring에국한된 기술이 아니다. • Meteor, Vaddin 등 Isomorphic한 Framework 이 등장되어지고 있다. • NodeJs, Django, RoR 등의 기존 Famework의 Isomorphic 지원이 개발되 었거나, 개발되어지고 있는 중이다. • Isomorphic을 통해서 Spring ViewTemplate들이 발빠르게 지원 하지 못했던 기능들을 다양한 Javascript Library을 통해서 View를 구성해 볼 수 있는 기회가 열렸다. • Viewtemplate의 삼국지 -> 춘추 전국시대의 도래 • 트렌드를 이끄는 다양한 Javascript Library가 계속해서 등장 함에 따라 앞으로 Isomorphic기술은 더욱 유용성이 높아 질 것 이다.