メンテナンス性の良いWebシステムを構築するためにjavaとフロントエンドでやるべきこと

13,506 views
13,306 views

Published on

2013/11/09 JJUG CCCでの発表資料です。

メンテナンス性の良いWebシステムを構築するためにjavaとフロントエンドでやるべきこと

  1. 1. メンテナンス性の良い Webシステムを構築するために Javaとフロントエンドでやるべきこと 2013/11/09 JJUG CCC HTML5jエンタープライズ部 小川充(@mitsuruog) photo credit http://www.ashinari.com/2013/09/06-381684.php
  2. 2. 自己紹介 小川充(おがわみつる) 株式会社クレスコ 技術研究所 フロントエンジニア 進化し続けるフロントエンド技術と システム開発の現場をいかに融合させるか! 業務システムエンジニア目線で活動しています。 ・HTML5jエンタープライズ部 運営メンバー ・OSSドキュメント翻訳コミュニティ  enja-ossメンバー ・Github:https://github.com/mitsuruog ・Twitter:https://twitter.com/mitsuruog
  3. 3. はじめに サーバサイドにはうるさい業務系フロントエンジニアです。 2013/09/09にHTML5jエンタープライズ部とJJUGと共催で 「Web×Java」をテーマに勉強会を企画、開催しました。 業務系WebアプリケーションがStrutsから旅立つ日 http://www.slideshare.net/mitsuruogawa33/webstruts 「業務系システムは今すぐ脱Strutsを!」業務システムエンジニアのためのHTML5勉強会#04 活動報告 http://gihyo.jp/news/report/2013/09/1901
  4. 4. はじめに 昨今、UIがリッチになるに従い、サーバ側で実装されていたものがフロント側でも 実装されるようになってきました。 その際にWebシステムのメンテナンス性の上で大切なことは、フロント側とサーバ側 の役割分担を明確にし、影響しあう部分を局所化すること。 これからのJavaでのWeb開発において、フロント側とサーバ側の役割をどのように 考えれば良いかお話します。 話さないこと ・クライアントMV*系フレームワークの詳細 ・Javaサーバ側実装の詳細 ・CSS(←Webのメンテナンス性を語る上では重要な要素 ) ・JSF1.X ・Richfaces、Primefaces ・Scala、Groovy
  5. 5. 1.画面構築方式とアンチパターン
  6. 6. なぜ画面構築方式なのか? ・フロント側のロジックのほとんどは画面構築に関するもの。 ・Ajaxの登場以来、画面の部分更新が多く行われるようになり、画面構築方法が複雑 化し、フロント側の実装量が増えてきた。 ・画面構築の部分が、最もサーバ側との機能重複が発生しやすい箇所。
  7. 7. 画面構築方式(従来型・画面遷移方式) サーバサイド フロントエンド Model Contoller HTML テンプレート View ロジック HTML ・画面はサーバ側で生成。 ・レスポンスはHTMLベース Ajaxで画面を部分更新し始めると危険なパターン (よくある)
  8. 8. 画面構築方式(次世代型・REST API方式) サーバサイド フロントエンド VM*系フレームワーク Contoller (View) Model Contoller JSON HTML View テンプレート ロジック ・レスポンスはJSONベース ・画面はフロント側で生成(データバインディング) サーバ側で画面を部分構築し始めると危険なパターン (あまりない、要員スキルなど途中で妥協した場合などに起こる。) Model
  9. 9. 画面構築方式(まとめ) ・2つの方式も混ざり合わない間は問題ない。 ・2つの方式が混ざり合う部分で機能的な重複が起こる。 ・混ざり合う部分での方針やルールが定まっていない場合に混乱が起こり、機能重複 が起こる。
  10. 10. 2.フロントエンドの役割とは何か? ~Javascriptの場合~
  11. 11. フロントエンドの役割(従来型) DOM操作 (アニメーション) Ajax フロントエンド役割があまりなかった時代
  12. 12. フロントエンドの役割(次世代型) DOM操作 (アニメーション) Ajax テンプレートエンジン テンプレート リソース同期 MV*系フレームワーク 構造化 JAX-RSの場合はこの構成
  13. 13. フロントエンドの役割(JSFの場合) DOM操作 (アニメーション) Ajax テンプレート リソース同期 JSF 構造化 サーバサイドに大きく依存しており フロントとの役割分担の見極めが難しい (アンチパターン)
  14. 14. フロントエンドの役割(まとめ) ・フロントエンドが求められる役割は主に5つ。 (DOM操作、Ajax、テンプレート、データ同期、構造化) ・JSFの場合は、フロントエンドとの役割分担の見極めが難しくアンチパターンに陥りや すい。
  15. 15. 3. JAX-RS、JSF(2.0+) それぞれとの組み合わせ方 ~フロントエンド組み合わせの留意事項~
  16. 16. JAX-RSの場合 ・画面構築方式は次世代型。画面はフロント側で生成。 ・JAX-RSはREST仕様に則ったWebAPIが容易に作成可能。 例)サーバ側REST実装例 ルーティング、JSONシリアライズが直感的 @RequestScoped @Path("hoge") public class HogeResource { @GET @Path("product") @Produces(MediaType.APPLICATION_JSON) public Product getProduct() { Product product = new Product(); product.setId(1); product.setName("Mattress"); product.setDescription("Queen size mattress"); product.setPrice(500); return product; } } 呼び出すURL http://localhost:8080/web_root/webresources/hoge/product
  17. 17. JAX-RSの場合 ・サーバとのREST API呼び出しを隠蔽するようなJavascriptMV*系F/Wと相性がよい。 (個人的にはBackbone.js、Anguler.js推奨) フロント側実装 (Backbone.js) Java側の実装(URLは「hoge/product」) @RequestScoped var Model = Backbone.Model.extend({ @Path("hoge") url: 'webresources/hoge/product' public class HogeResource { }); @GET var View = Backbone.View.extend({ @Path("product") @Produces(MediaType.APPLICATION_JSON) initialize: function() { public Product getProduct() { this.model = new Model(); Product product = new Product(); this.model.fetch(); this.render(); //画面の再構築 //省略 }, render: function(){ return product; } //省略 } } }); fetch()呼び出し時にGETリクエストを投げる //Viewの初期化 受信後、F/W側で勝手にModelのデータを更新する new View(); (Backbone.sync)
  18. 18. JAX-RSの場合(その他留意事項) ・フロント側に実装量が増えるため、JavascriptMV*系F/Wでの構造化が必須。 ・フロント側にテンプレートエンジンが必要。 ・初期表示時に表示データ取得用の余計なリクエストが1回飛ぶ。 (これをどう捕らえるか次第…) ・本格的にフロントエンジニアの参画が必要。
  19. 19. JSF(2.0+)の場合 ・画面構築方式は基本的に従来型。 ・画面構築はサーバ側。Ajax通信時もサーバ側で画面構築する。 ・Ajaxでの画面部分構築は<f:ajax>を使用すること。 例)Ajax入力チェック「 JSF側」 <h:form id="form"> <h:inputText id="name" value="#{user.name}" validator="#{user.validateName}"> <f:ajax execute="name" render="nameError" event="blur" /> </h:inputText> <h:message for="name" id="nameError" style="color: red"/> </h:form> サーバ側のロジック <f:ajax>でJavascriptを記述することなくAjax呼び出しが可能
  20. 20. JSF(2.0+)の場合 ・jQueryなどから画面部分更新したいケースは、JSFライブラリのAjax通信機能を使用 すること。 ⇒画面構築部分はJSFの影響力が強すぎるため、テンプレートとAjax部分は割り 切って任せたほうが良い。(後述) jQueryからフックする例) $(document).on('click', '#form:validate', function(e) { jsf.ajax.request(e.target, e, { execute: 'form:name', render: 'form:nameError' 正直、書き方が気持ち悪いw }); e.preventDefault(); そもそも、無理にフックする必要ない。 }); そうなるようであれば設計を見直した方がいいかも。
  21. 21. JSF(2.0+)の場合 ・JSFが持つ、テンプレートとUIコンポーネント化の仕組みが優秀。 ⇒UIのコンポーネント化にTaglibのように面倒な手続きが不要。 ・<f:metadata>の登場により、GETパラメータの扱いが容易になった。 UIテンプレート化 <ui:insert>と<ui:define> UIコンポーネント化 <composite:interface>と<composite:implementation> GETリクエストとの親和性向上 <f:metadata>と<f:viewParam>
  22. 22. JSF(2.0+)の場合(その他留意事項) ・(注意)JSFのAjax通信のレスポンスはXML形式で、かつ独自色が強い。 例)先ほどの入力チェック時に返ってきたレスポンス <?xml version='1.0' encoding='UTF-8'?> <partial-response id="j_id1"> <changes> 部分的なHTMLが返ってくる。 <update id="form:nameError"> <![CDATA[<span id="form:nameError" style="color: red">必須入力です </span>]]> </update> <update id="j_id1:javax.faces.ViewState:0"> <![CDATA[8183146577291182963:-4484956516055255891]]> </update> </changes> </partial-response> レスポンスを受けて、自前で何かしようとか思わないほうがいい。
  23. 23. JSF(2.0+)の場合(その他留意事項) ・サーバ側の依存度が高いため、Javascriptとの役割分担が難しい。 ⇒むしろ、フロントエンドの出番はあまりない(ようにするべき)。 ・JavascriptMV*系F/Wとの組み合わせるべきではない。 ・Javascriptライブラリ選定はJSFと機能の包含関係を考慮して行うべき。
  24. 24. 4.まとめ
  25. 25. まとめ(JAX-RS) ・サーバ側の役割はREST APIに徹する。 ・フロント側の役割はテンプレートと画面構築を担う。 ・別途、JavascriptMV*系F/Wなどで構造化が必須。 長所 ・基本的にどんな UIにも対応可能。 ・フロントエンドの分業が可能。 ・様々なJavascriptMV*系F/Wやライブラリが選択可能。 ・JSONベースの小さいデータのやり取りが主流であるため、通信環境の悪いモバイルに適してい る。 短所 ・フロントエンジニア的にはないw。 ・気をつけないと、 Javascriptがメモリリークしやすい。 ・規模や難易度に見合うフロントエンジニアの調達・教育が課題。
  26. 26. まとめ(JSF2.0+) ・フロントエンドとの役割分担を見極めれば、非常に優秀はWebフレームワーク。 ・JSFのテンプレートとAjax通信機能をフルで使う前提で設計するべき。 ・むしろフロント側の役割は多く持たせるべきではない。 ・JavascriptMV*系F/Wとの組み合わせるべきではない。 長所 ・Javaエンジニアのみで、ある程度リッチな Webシステムを安全に構築可能。 ・JSFの<f:ajax>タグを使っている範囲であれば、 Javascriptを意識する必要はない。 ・テンプレート、 UIコンポーネント化機能が優秀で、 UIの再利用性が高くなる。 短所 ・リッチなUIには向かない。 ・HTML/XMLベースのやり取りが主流であるため、モバイル環境には適していない場合がある。 ・安易にAjaxの部分更新ができるため、更新する範囲のコントロールに注意が必要。 ・フロントエンジニアにアンチファンが多い。
  27. 27. ご静聴ありがとうございました! 2013/11/09 JJUG CCC HTML5jエンタープライズ部 小川充(@mitsuruog) photo credit http://www.ashinari.com/2007/05/07-002031.php

×