SlideShare a Scribd company logo
マイクロフレームワーク
Enkan(とKotowari)ではじめる
REPL駆動開発
kawasima
JJUG CCC 2016 Sping CD-7
Enkan
http://enkan.github.io/
Background
A new server-side framework
Why now?
The twelve factor app
Microservices
主流のJavaフレームワークで大丈夫か?
Focus on mean time to recovery
Requirements
Java8 以上
Maven3以上
Enkan's backbone
Connect
javascript
Ring
clojure
duct
clojure
liberator
clojure
Rack
ruby
Component
clojure
Enkan Kotowari
Middleware / Component Web application framework based on Enkan
(Routing, HTML Template, ...)
Trade-off
Implicit utility 暗黙的な便利機能
High level dependency injection
Easy configuration by many annotations
Understability 理解のしやすさ
Explicit declaration
Concepts
Key Concepts
Explicitness 明示的であること
Ease of deveopment 開発がしやすいこと
Ease of Operation 保守運用が簡単であること
Explicitness
Middleware pattern
No configuration files
Anti-blackbox
Avoid annotation hell
Middleware
Applicationの共通なコードはすべてMiddlewareに集約されている
Filter? Interceptor? Containerの機能? など迷うことが無くなる
app.use(new DefaultCharsetMiddleware());
app.use(new MetricsMiddleware<>());
app.use(NONE, new ServiceUnavailableMiddleware<>(
    new ResourceEndpoint("/public/html/503.html")));
app.use(envIn("development"), new StacktraceMiddleware());
Middleware
Params
NestedParams
MultipartParams
Session
Conversation
Flash
Normalization
Authenticate
ContentNegotiation
SerDes
Routing
ValidateForm
ControllerInvoker
Trace
その他、多くのMiddlewareがあります
http://enkan.github.io/reference/middlewares.html
Predicate
ここが他のミドルウェアフレームワークと違う
以下のPredicateが標準で利用可能
None 全てのリクエストに適用しない
Any 全てのリクエストに適用する
Path パス、methodのマッチしたものだけ
Authenticated 認証されたリクエストのみ
Permission 権限を持っているリクエストのみ
Env 指定した環境のみ
適用するミドルウェアの条件をカスタマイズできる
Predicateの合成
Predicateはjava.utilfunction.Predicateの実装なので、
negate(), and(), or()で合成が可能。
app.use(and(path("^/guestbook/"), authenticated().negate()),
(Endpoint<HttpRequest, HttpResponse>) req ->
HttpResponseUtils.redirect("/guestbook/login?url=" + req.getUri(),
HttpResponseUtils.RedirectStatusCode.TEMPORARY_REDIRECT));
↓ /guestbook 配下のURIで、認証されていないリクエスト
(をログインページにリダイレクトする)
No configuration files
&
Avoid annotaion hell
???「評判の悪かったXMLは、Annotationに形を変
え生き残っていると言えよう」
Java8 Syntaxを活かせば、DSL的に書けるようになる
Routes routes = Routes.define(r -> {
r.get("/").to(HomeController.class, "index");
r.get("/login").to(LoginController.class, "index");
r.post("/login").to(LoginController.class, "login");
r.scope("/admin", admin -> {
admin.resource(UserController.class);
});
}).compile();
例えばルーティングの定義
割と可読性高いのでは!?
EnkanとKotowariで使うAnnotation
@Inject
コントローラのフィールドにComponentをインジェクションする
ためのマーカー
@Named
同型のコンポーネントを区別する場合にのみ使用
@Transactional
コントローラメソッドをトランザクション境界にする
Anti Blackbox
Component, Middlewareの初期化は
すべて明示的にnewする
黒魔術を使わない
バイトコードを触る
Proxy
Default or Using BeanBuilder
builder(new UndertowComponent())
.set(UndertowComponent::setPort, 77777)
.build();
例えばポートをデフォルトから変更する場合
build() コール時に、BeanValidationされるので、
MisconfigurationExceptionが発生する
デフォルトで十分動作するように設定されていて、
変更する場合もBeanBuilderを使っていれば
設定ミスにすぐ気づくことができる
http://qiita.com/kawasima/items/0bee34fea7749aa2e776
Ease of development
Hot reloading
Easy to realize misconfiguration
Trace the request / response
Hot Reloading
 Dispose ClassLoader
Seasar2型のHot deployと同じ方式だが、毎リクエスト破棄するのでは
なく、REPLから/resetを実行したタイミングで再ロードされる。
/autoresetするとクラスの変更を監視し、自動でResetしてくれる
 将来的には、JVM containerを使うことで、より高速かつ
安全にリロード可能になる
(詳しくはJDT2016でお話します)
Exception
MisconfigurationException
設定のミスと思われるものは問題と対策をもった専用の
Exceptionを出力する。
Trace the request/response
どのミドルウェアをとおり、
どこでどれだけ時間がかかっているのかを
1リクエスト毎に可視化して表示できる
Ease of Operation
Start application quickly
Metrics
REPL
Start application quickly
Enkan application starts 1~3 sec
Causes starting application is slow
Scanning classes
Loading and parsing many configurations
Metrics
Dropwizard metrics
アクティブなリクエスト数
エラーになったリクエスト数
1リクエストあたりの性能
スループット
View in the REPL
REPL
Connect a remote Enkan application
Start, stop, restart a server
Show the middlewares
Change the predicate of a middleware
Show the routes
Show the metrics
Restart components automatically
Compile sources
Why not JShell
現段階では以下の問題があり未対応
動いているプロセスにアタッチできない
コマンドを追加できない
将来的にはJShell REPL対応する予定です。
(多分 Java 10)
Show the routes
ルーティングの定義を一覧化します
enkan> /routes app
GET / {controller=class hoge.controller.IndexController, action=index}
GET /product/ {controller=class hoge.controller.ProductController, action=index}
GET /product/:id {controller=class hoge.controller.ProductController, action=show}
GET /product/new {controller=class hoge.controller.ProductController, action=newForm}
POST /product/ {controller=class hoge.controller.ProductController, action=create}
GET /product/:id/edit {controller=class hoge.controller.ProductController, action=edit}
PUT /product/:id {controller=class hoge.controller.ProductController, action=update}
DELETE /product/:id {controller=class hoge.controller.ProductController, action=delete}
Show the metrics
enkan> /metrics
-- Active Requests ----------------------------------
count = 16
-- Errors ------------------------------------
count = 0
mean rate = 0.00 events/s
1-minute rate = 0.00 events/s
5-minute rate = 0.00 events/s
15-minute rate = 0.00 events/s
-- Request Timer -----------------------------
count = 23815
mean rate = 176.33 calls/sec
1-minute rate = 176.33 calls/sec
5-minute rate = 73.44 calls/sec
15-minute rate = 24.78 calls/sec
min = 0.00 sec
max = 0.29 sec
mean = 0.01 sec
stddev = 0.02 sec
median = 0.00 sec
75% <= 0.00 sec
95% <= 0.04 sec
98% <= 0.07 sec
99% <= 0.09 sec
99.9% <= 0.29 sec
Show the middlewares
enkan> /middleware app list
ANY defaultCharset (enkan.middleware.DefaultCharsetMiddleware@64596fc4)
NONE serviceUnavailable
(enkan.middleware.ServiceUnavailableMiddleware@252e9fc0)
env = {development} stacktrace
(enkan.middleware.devel.StacktraceMiddleware@20ef35b2)
env = {development} traceWeb
(enkan.middleware.devel.TraceWebMiddleware@1b7068c2)
ANY trace (enkan.middleware.TraceMiddleware@34f80327)
ANY contentType (enkan.middleware.ContentTypeMiddleware@65f95ae7)
env = {development} httpStatusCat
(enkan.middleware.devel.HttpStatusCatMiddleware@3ce2b14f)
ANY params (enkan.middleware.ParamsMiddleware@244cf869)
ANY multipartParams (enkan.middleware.MultipartParamsMiddleware@50d936fc)
ANY methodOverride (enkan.middleware.MethodOverrideMiddleware@7f586062)
ANY normalization (enkan.middleware.NormalizationMiddleware@5619ce0f)
ANY nestedParams (enkan.middleware.NestedParamsMiddleware@1555fb15)
ANY cookies (enkan.middleware.CookiesMiddleware@c225195)
ANY session (enkan.middleware.SessionMiddleware@30c56b03)
Change the predicate of a middleware
enkan> /middleware app list
ANY defaultCharset (enkan.middleware.DefaultCharsetMiddleware@
NONE serviceUnavailable (enkan.middleware.ServiceUnavailableMi
ANY stacktrace (enkan.middleware.StacktraceMiddleware@545872dd
enkan> /middleware app predicate serviceUnavailable ANY
enkan> /middleware app list
ANY defaultCharset (enkan.middleware.DefaultCharsetMiddleware@
ANY serviceUnavailable (enkan.middleware.ServiceUnavailableMid
ANY stacktrace (enkan.middleware.StacktraceMiddleware@545872dd
現在はすべてのリクエストについて非適用
すべてのリクエストについて有効にする
Core parts
Architecture
Dependency policy
依存ライブラリは極力少なく
enkan-core
slf4j-api
javaee-api
enkan-webenkan-system
cache-apijline
msgpack
Component
Singleton scope
Field injection
Start/stop lifecycle
Componentとはアプリケーションの状態を管理するもの
Componentとはその状態を安全に開始、終了できるもの
Available components
Undertow / Jetty Web server
HikariCP DataSource
Doma2 O/R Mapper
Flyway Database migration
Freemarker / Thymeleaf HTML Templating
Jackson Bean converter
Metrics Metrics
Enkan System
Minimal DI container
EnkanSystem.of(
"doma", new DomaProvider(),
"jackson", new JacksonBeansConverter(),
"flyway", new FlywayMigration(),
"template", new FreemarkerTemplateEngine(),
"metrics", new MetricsComponent(),
"datasource", new HikariCPComponent(
OptionMap.of("uri", "jdbc:h2:mem:test")),
"app", new ApplicationComponent(
"kotowari.example.MyApplicationFactory"),
"http", builder(new UndertowComponent())
.set(UndertowComponent::setPort, Env.getInt("PORT", 3000))
.build()
).relationships(
component("http").using("app"),
component("app").using("datasource", "template", "doma", "jackson",
"metrics"),
component("doma").using("datasource", "flyway"),
component("flyway").using("datasource")
);
What's injected to Controller
Field injection
Component
Parameter injection
Parameters (Query string & Post body)
Session
Flash
User principal
Conversation / Conversation state
Request body object
Controller code
public class CustomerController {
@Inject
private TemplateEngine templateEngine;
@Inject
private DomaProvider daoProvider;
@Inject
private BeansConverter beans;
public HttpResponse index() {
CustomerDao customerDao = daoProvider.getDao(CustomerDao.class);
List<Customer> customers = customerDao.selectAll();
return templateEngine.render("customer/list",
"customers", customers);
}
public List<Customer> list() {
CustomerDao customerDao = daoProvider.getDao(CustomerDao.class);
Session
Selectable session store
In-memory
JCache
Separate between the request session and response session
リクエストセッションとレスポンスセッションが分離しているのが
HttpSessionとの大きな違い
Sessionを使ったコード
public HttpResponse login(Parameters params,
Conversation conversation) {
if (!conversation.isTransient()) conversation.end();
CustomerDao dao = daoProvider.getDao(CustomerDao.class);
String email = params.get("email");
Customer customer = dao.loginByPassword(email, params.get("password"
if (customer == null) {
return templateEngine.render("guestbook/login");
} else {
Session session = new Session();
session.put("principal", new LoginPrincipal(email));
return builder(redirect(GuestbookController.class,
"list", SEE_OTHER))
.set(HttpResponse::setSession, session)
.build();
}
}
Conversation
入力-確認-完了のような遷移で、Conversation IDを
発行し、それに状態をもつことができる
Servlet APIのHttpSessionのように、複数タブの操
作で状態が混ざりあうことがない
二重サブミット対策にセッションを使う必要がない
Routing
Rails-like
scopeによるグルーピングやresourceによるRESTfulな
ルーティングの定義が可能
Routes routes = Routes.define(r -> {
r.get("/").to(HomeController.class, "index");
r.scope("/admin", admin -> {
admin.resource(UserController.class);
});
}).compile();
Generate routes
Routes routes = Routes.define(r -> {
r.get("/a/b/").to(TestController.class, "index");
r.get("/a/b/:id").to(TestController.class, "show");
}).compile();
// Generates "/a/b/"
routes.generate(OptionMap.of("controller", TestController.class,
"action", "index"));
// Generates "/a/b/1"
routes.generate(OptionMap.of("controller", TestController.class,
"action", "show", "id", 1));
Content Negotiation
RESTful APIをEasyに作る
JAX-RSのBodyWriter, BodyReaderがそのまま利用できる。
public List<Customer> list() {
CustomerDao customerDao = daoProvider
                .getDao(CustomerDao.class);
return customerDao.selectAll();
}
Getting Started
http://enkan.github.io/getting-started.html
Maven archetype
最小限のアプリケーションを出力します
デフォルトコンポーネントを組み込んだEnkanSystem
REPLサーバを起動するMain
% mvn archetype:generate 
-DarchetypeGroupId=net.unit8.enkan 
-DarchetypeArtifactId=kotowari-archetype 
-DarchetypeVersion=0.1.0-beta2
Scaffolding
テーブル(Flyway migration)の生成
CRUDアプリケーションの生成
enkan> /generate table PRODUCT (id identity primary key,
name varchar(255))
enkan> /generate crud PRODUCT
Amagicman
Yeoman的なものをJVMで。
Yoeman含むよくあるScaffoldingツールとは違い、
テンプレートはピュアJavaファイル
つまり、Amagicmanのタスクは、テンプレートを
いじること
https://github.com/kawasima/amagicman
Conclusion
Javaでも結構REPL-Drivenできそう
仕事でJavaで書かなきゃいけないClojure好きな人は
是非使ってみてください
Java EE、Spring派の方も、ポートフォリオとして
Enkanを加えていただけるとウレシイです
さぁ、みなさんも、
EnkanとKotowariに
導かれるのです…
円 環 理

More Related Content

PDF
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
PDF
Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!
PDF
元気玉的 分散テスト 実行システム TestStreamer
PDF
テストゼロからイチに進むための戦略と戦術
PDF
Jjug ccc 2016 spring i 5 javaデスクトッププログラムを云々
PDF
WildFly Swarmではじめる「パーツとしてのJavaEE」
PDF
SpringMVC
PDF
20160521 大規模映像配信サービスの Java8による全面リニューアルの裏側
Javaの進化にともなう運用性の向上はシステム設計にどういう変化をもたらすのか
Spring Bootでチャットツールを作りながらWebの仕組みを理解しよう!
元気玉的 分散テスト 実行システム TestStreamer
テストゼロからイチに進むための戦略と戦術
Jjug ccc 2016 spring i 5 javaデスクトッププログラムを云々
WildFly Swarmではじめる「パーツとしてのJavaEE」
SpringMVC
20160521 大規模映像配信サービスの Java8による全面リニューアルの裏側

What's hot (19)

PPTX
はじめてのSpring Boot
PDF
大規模な負荷でもドキドキしない為のJava EE
PDF
JavaOne2013報告会 JavaFX Update
PDF
Jsug 20160422 slides
PDF
OpenJDK コミュニティに参加してみよう #jjug
PDF
Sd Loader Seasar Con2009 White
PPTX
Java EE パフォーマンスTips #glassfish_jp
PDF
プログラミング言語Clojureのニャンパスでの活用事例
PDF
WildFly Swarm - Rightsize Your Java EE Apps
PDF
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
PDF
Javaで1から10まで書いた話(sanitized)
PDF
Awsで実現するseleniumテスト高速術
PDF
JavaScriptでWebDriverのテストコードを書きましょ
PDF
Spring bootでweb セキュリティ(ログイン認証)編
PPTX
Spring frameworkが大好きなおはなし
PDF
JobStreamerではじめるJavaBatchのクラウド分散実行
PPT
Spring3.1概要 データアクセスとトランザクション処理
PPTX
JVM上でのストリーム処理エンジンの変遷
PDF
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
はじめてのSpring Boot
大規模な負荷でもドキドキしない為のJava EE
JavaOne2013報告会 JavaFX Update
Jsug 20160422 slides
OpenJDK コミュニティに参加してみよう #jjug
Sd Loader Seasar Con2009 White
Java EE パフォーマンスTips #glassfish_jp
プログラミング言語Clojureのニャンパスでの活用事例
WildFly Swarm - Rightsize Your Java EE Apps
Javaチョットデキルへの道〜JavaコアSDKに見る真似したいコード10選〜
Javaで1から10まで書いた話(sanitized)
Awsで実現するseleniumテスト高速術
JavaScriptでWebDriverのテストコードを書きましょ
Spring bootでweb セキュリティ(ログイン認証)編
Spring frameworkが大好きなおはなし
JobStreamerではじめるJavaBatchのクラウド分散実行
Spring3.1概要 データアクセスとトランザクション処理
JVM上でのストリーム処理エンジンの変遷
CDI2.0アップデート&クックブック #JavaDayTokyo #jdt2016_4c
Ad

Viewers also liked (20)

PDF
キメるClojure
PDF
既婚プログラマの時間捻出術
PDF
SIerにとっての越境 @ DevLOVE 199
PDF
なぜデータモデリングが重要なのか?
PDF
Boilerplate vs Magic
PDF
週刊Webサイトのアーキテクチャ
PDF
たとえ日本人同士でも必要な異文化理解力
PDF
Antifragile Clojure
PDF
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure
PDF
で、次は何がくるの? - 第2回 TIS Matsuri
PDF
Seasar conference 2015 sa-compojure
PDF
イミュータブルデータモデル(世代編)
PDF
イミュータブルデータモデル(入門編)
PDF
エスイーのしごと
PDF
Clojureによるログ収集と解析
PDF
SIerもはじめる わたしたちのDevOps #jjug_ccc
PDF
イマドキのExcelスクショの撮り方
PDF
Code Anything
PDF
JJUG CCC 2015 Spring 総会資料
PDF
言語設計者が意味論を書くときに考えていたこと
キメるClojure
既婚プログラマの時間捻出術
SIerにとっての越境 @ DevLOVE 199
なぜデータモデリングが重要なのか?
Boilerplate vs Magic
週刊Webサイトのアーキテクチャ
たとえ日本人同士でも必要な異文化理解力
Antifragile Clojure
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure
で、次は何がくるの? - 第2回 TIS Matsuri
Seasar conference 2015 sa-compojure
イミュータブルデータモデル(世代編)
イミュータブルデータモデル(入門編)
エスイーのしごと
Clojureによるログ収集と解析
SIerもはじめる わたしたちのDevOps #jjug_ccc
イマドキのExcelスクショの撮り方
Code Anything
JJUG CCC 2015 Spring 総会資料
言語設計者が意味論を書くときに考えていたこと
Ad

Similar to マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発 (20)

PPTX
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
PPTX
Cloud Native Application on DEIS by using 12 factor
PDF
[AC06] クラウド・ネイティブなスケーラブル・アプリ開発のために~12 Factor App on Kubernetes on Azure
PDF
Kubernetes 導入から始める DevOps について
PDF
~ Cloud First から Cloud Optimized へ ~ .NET on Cloud が描くモダナイゼーション
PPTX
Java on Kubernetes on Azure
PPTX
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
PDF
企業システムで使えるマイクロサービスの特長と実践 (Oracle Cloudウェビナーシリーズ: 2021年4月15日)
PDF
アドテク×Scala×パフォーマンスチューニング
PDF
ソフトバンクにおける Java による クラウドネイティブの実現
PDF
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
PDF
OpenFlow Controller lily
PDF
20140329 modern logging and data analysis pattern on .NET
PPTX
AKS と ACI を組み合わせて使ってみた
PDF
20120528 aws meister-reloaded-awssd-kforjava-public
PDF
Cloudstack networking の内側
PDF
Jenkins study jenkins build-cicdi
PDF
デバイスからクラウドへ ~組み込みエンジニアと IoT
PDF
VMwareの歩き方 ~SDDCに向けた最強アンダーレイとは?
PDF
OpenStack on OpenStack with CI
DeClang 誕生!Clang ベースのハッキング対策コンパイラ【DeNA TechCon 2020 ライブ配信】
Cloud Native Application on DEIS by using 12 factor
[AC06] クラウド・ネイティブなスケーラブル・アプリ開発のために~12 Factor App on Kubernetes on Azure
Kubernetes 導入から始める DevOps について
~ Cloud First から Cloud Optimized へ ~ .NET on Cloud が描くモダナイゼーション
Java on Kubernetes on Azure
WebAssemblyとBlazor 、WebAssembly System Interfaceでコンテナライズの設計を解説
企業システムで使えるマイクロサービスの特長と実践 (Oracle Cloudウェビナーシリーズ: 2021年4月15日)
アドテク×Scala×パフォーマンスチューニング
ソフトバンクにおける Java による クラウドネイティブの実現
クラウド環境向けZabbixカスタマイズ紹介(第5回Zabbix勉強会)
OpenFlow Controller lily
20140329 modern logging and data analysis pattern on .NET
AKS と ACI を組み合わせて使ってみた
20120528 aws meister-reloaded-awssd-kforjava-public
Cloudstack networking の内側
Jenkins study jenkins build-cicdi
デバイスからクラウドへ ~組み込みエンジニアと IoT
VMwareの歩き方 ~SDDCに向けた最強アンダーレイとは?
OpenStack on OpenStack with CI

More from Yoshitaka Kawashima (19)

PDF
Grokking Simplicity探訪
PDF
ブルックスのいう銀の弾丸とは何か?
PDF
Are Design Patterns Dead?
PDF
強いて言えば「集約どう実装するのかな、を考える」な話
PDF
ソフトウェアにおける 複雑さとは何なのか?
PDF
Tackling Complexity
PDF
イミュータブルデータモデルの極意
PDF
ソフトウェア開発における『知の高速道路』
PDF
ソフトウェア設計における 意思決定とそのレビューの秘訣
PDF
本番障害に至る病
PDF
システムダウンのひみつ
PDF
Mavenの真実とウソ
PDF
アンチフラジャイルの世界
PDF
Atomic Architecture
PDF
それはYAGNIか? それとも思考停止か?
PDF
思考停止しないアーキテクチャ設計 ➖ JJUG CCC 2018 Fall
PDF
ウォーターフォールとアジャイルのフェアな比較
PDF
How to find tech books
PDF
Antifragile Java - Java Day Tokyo 2017 D1-E1
Grokking Simplicity探訪
ブルックスのいう銀の弾丸とは何か?
Are Design Patterns Dead?
強いて言えば「集約どう実装するのかな、を考える」な話
ソフトウェアにおける 複雑さとは何なのか?
Tackling Complexity
イミュータブルデータモデルの極意
ソフトウェア開発における『知の高速道路』
ソフトウェア設計における 意思決定とそのレビューの秘訣
本番障害に至る病
システムダウンのひみつ
Mavenの真実とウソ
アンチフラジャイルの世界
Atomic Architecture
それはYAGNIか? それとも思考停止か?
思考停止しないアーキテクチャ設計 ➖ JJUG CCC 2018 Fall
ウォーターフォールとアジャイルのフェアな比較
How to find tech books
Antifragile Java - Java Day Tokyo 2017 D1-E1

マイクロフレームワークEnkan(とKotowari)ではじめるREPL駆動開発