---
title: 【JavaEE Advent Calendar 2013 15日目 JAX-RSとJavaFXで作るThin Server Architectureのマルチプロジェクト構成
tags: []
categories: ["Programming", "Java", "JavaEE", "AdventCalendar", "2013"]
date: 2013-12-15T13:10:43Z
updated: 2013-12-15T13:10:43Z
---

この記事は[Java EE Advent Calendar 2013][1]の15日目の記事です。[JavaアプリケーションサーバでThreadLocal利用時の注意点][2]でした。

これまでThin Server Architecture(TSA)について[何回か触れてきました][3]。

ざっくりいうとサーバーサイドでドメインロジックをREST APIでのみ提供し、アプリケーション毎の見栄えに関する処理はクライアント毎に用意してREST APIを叩きましょう。というもの。

いぜんGlassFish勉強会で話したのはクライアントとしてJSFを使うパターンでした。

<iframe src="http://www.slideshare.net/slideshow/embed_code/22971482?startSlide=33" width="427" height="356" frameborder="0" marginwidth="0" marginheight="0" scrolling="no" style="border:1px solid #CCC;border-width:1px 1px 0;margin-bottom:5px" allowfullscreen> </iframe> <div style="margin-bottom:5px"> <strong> <a href="https://www.slideshare.net/makingx/glass-fish2013-06" title="JSFとJAX-RSで作る Thin Server Architecture #glassfishjp" target="_blank">JSFとJAX-RSで作る Thin Server Architecture #glassfishjp</a> </strong> from <strong><a href="http://www.slideshare.net/makingx" target="_blank">makingx</a></strong> </div>


このとき作ったTodoListアプリのサーバーサイドはそのままでクライアントサイドを[昨日学んだばかり][4]のJavaFXで作ってみました。

JSF版はこんなやつでした。

<a href='/api/v1/files/00124/todo-tsa-jsf.png'><img src='/api/v1/files/00124/todo-tsa-jsf.png' /></a>

JavaFXで作る場合に、サーバーサイドのコードは不要です。ただし、一部使いたい部分はあります。ドメインオブジェクトやRepositoryなど。ぼくはこのへんをDDDの用語を借りてドメイン層といっています。アプリケーションによらず必要なクラス。これらを別プロジェクトにして、Web用、JavaFX用のウプロジェクトから使うようにします。

* todo-domain ... TodoListのドメイン層
* todo-web ... TodoListのアプリケーション層(Web版)
* todo-fx ... TodoListのアプリケーション層(JavaFX版)

本当はREST APIの実装はtodo-apiプロジェクトにした方が良い気がしましたが、今回はwebに含めました。Repositoryの実装もほんとうは別プロジェクト(todo-infra)にした方が良い気がしましたが、今回はdomainに含めました。この辺はアプリの大きさに合わせて柔軟に選べばいいでしょう。

IntelliJ IDEA 13で開発しました。以下のようなマルチモジュール構成になります。

<a href='/api/v1/files/00127/todo-tsa-idea.png'><img src='/api/v1/files/00127/todo-tsa-idea.png' /></a>

todo-domainの構成要素はこんな感じ

<a href='/api/v1/files/00128/todo-domain.png'><img src='/api/v1/files/00128/todo-domain.png' /></a>

todo-webの構成要素はこんな感じ

<a href='/api/v1/files/00129/todo-web.png'><img src='/api/v1/files/00129/todo-web.png' /></a>

todo-fxの構成要素はこんな感じ

<a href='/api/v1/files/00130/todo-fx.png'><img src='/api/v1/files/00130/todo-fx.png' /></a>

ソースコードは[Github][5]にあげました。

JavaFXの実装に特に工夫はありません。[昨日の例][6]のように`Service`使って非同期にした方がいいでしょう。
(本当はWeldを使ってCDIでRepositoryをインジェクションするつもりでしたが、複雑になりそうなのでやめました)

また、ぼくのJavaFX力が低くて、TableViewにボタンを埋め込む方法がわからなかったし、セルのチェックボックの値が変わったところでイベントハンドリングする方法もよくわかりませんでした。なのでUpdateとDeleteボタンを上につけてみました。ぐだぐだですね。

Scene Builder上はこんな感じ。

<a href='/api/v1/files/00125/todo-tsa-sb.png'><img src='/api/v1/files/00125/todo-tsa-sb.png' /></a>

実行するとこんな感じです。

<a href='/api/v1/files/00126/todo-tsa-fx.png'><img src='/api/v1/files/00126/todo-tsa-fx.png' /></a>

JavaFXから外部のREST APIを叩けるようにするにはRESTサーバー側でCross-Origin Resource Sharing (CORS) の設定が必要です。今回は[Springのサンプル][7]を使いました。
localhostの場合はいらないですがいちおう設定しておきます。

詳細は[コード][5]読んでください。

最近TSAが流行ってきているので、複数クライアントを開発する際の参考になればと。

  [1]: http://www.adventar.org/calendars/152
  [2]: http://d.hatena.ne.jp/yamadamn/20131214/1386996898
  [3]: /#/entries/176
  [4]: /#/entries/210
  [5]: https://github.com/making/todo-tsa
  [6]: /#/entries/210
  [7]: http://spring.io/guides/gs/rest-service-cors/
