#ccc_m2Clojureを用いたWebアプリケーション開発普通のベンチャー企業編2016.12.03JJUG CCC 2016 Fall@_ayato_pָ͍͠
View Slide
#ccc_m2(keyword "括弧 is ")
#ccc_m2あやぴー•サイボウズスタートアップス株式会社•一般的なClojureエンジニア•好きなもの: 前置記法、Emacs、SKK•得意料理: 唐揚げ、さばの味噌煮•好きなwebサービス: 白ごはん.com•好きな料理研究家: 冨田ただすけ_ayato_payato-p
#ccc_m2•Clojureの日本語ガイド•clojure.orgの翻訳(手伝い)こんなの書いてる人
#ccc_m2サイボウズスタートアップス•社員数20名以下•安否確認サービス、kintone連携サービスの提供•(今までは)全部PHPで作られたシステム•よくある普通(?)のベンチャー企業
#ccc_m2サイボウズスタートアップス情報サービスをとおして、 世界の豊かな社会生活の 実現に貢献する
#ccc_m2もくじ1. 普通のベンチャー企業が何故Clojureを選んだのか2. 安否確認サービスについて3. Clojureを採用して良かったところ4. Clojureを採用して苦労したこと5. まとめ
#ccc_m2普通のベンチャー企業が 何故Clojureを選んだのか(CTOに聞いてみた%)
#ccc_m2背景 (何故、新しい言語?)ྑ͍αʔϏεΛੈͷதʹఏڙ͍ͨ͠
#ccc_m2背景 (何故、新しい言語??)༏लͳΤϯδχΞ͕ඞཁྑ͍αʔϏεΛੈͷதʹఏڙ͍ͨ͠
#ccc_m2背景 (何故、新しい言語???)ϒϥϯυͷߏங͕ඞཁ༏लͳΤϯδχΞ͕ඞཁྑ͍αʔϏεΛੈͷதʹఏڙ͍ͨ͠
#ccc_m2背景 (何故、新しい言語????)ٕज़ϚʔέςΟϯάͷඞཁੑϒϥϯυͷߏங͕ඞཁ༏लͳΤϯδχΞ͕ඞཁྑ͍αʔϏεΛੈͷதʹఏڙ͍ͨ͠
#ccc_m2条件•すぐに廃れないこと(FWやライブラリで選択しない)•エンジニアが成長出来るテーマであること•テーマに対するチャレンジにワクワクできること•テーマにアンテナを張るエンジニアが優秀である場合が 多いこと•ニッチでも良い(大量の採用は考えてない)•採用面で競合が少ないこと•日本で一番になれる可能性があるテーマであること
#ccc_m2選ばれたのはClojureでした•条件に当てはまっていた•社内にClojureに関する知見を持ったメンバーがいた•当たり前だけど使えそうかどうかというのも しっかり考慮されてます
#ccc_m2安否確認サービス⛑ について
#ccc_m2気象庁
#ccc_m2•大災害を想定した堅牢なシステム構成•気象庁の地震速報と連動•地域/部署別の安否状況が確認できる•全社員または個別に対策支持が出せる•パケット通信による通信•フィーチャーフォンやスマホからでも操作できる•安否確認システム
#ccc_m2言い換えると…•企業向けのシステム•緊急時に高い可用性が求められている•外部サービスと連携している•モバイルアプリと連携している•レガシーブラウザやフィーチャーフォンをサポート
#ccc_m2言い換えると…•企業向けのシステム•緊急時に高い可用性が求められている•外部サービスと連携している•モバイルアプリと連携している•レガシーブラウザやフィーチャーフォンをサポートどちらかと言えば 堅いサービス
#ccc_m2Clojureでリプレース♻•規模の大きいクライアントが増えてきた•根幹からの作り直し•2015年の初夏くらいから1.5人くらいで開発がスタート• 現在3人で開発中•2016年12月中旬リリース予定!!
#ccc_m2プロジェクト構成•lein-modulesでマルチモジュールプロジェクト構成anpi├── lib // アプリ共通ライブラリ├── db // データベース接続用のライブラリ├── ymir // Quenoteクライアントライブラリ├── web // メインのアプリ├── worker // 非同期処理用アプリ├── admin // 管理画面用アプリ└── project.clj
#ccc_m2利用しているライブラリ•サーバー: Immutant Web•ルーティング: bidi•テンプレートエンジン: Enlive•SQLビルダー: stch.sql, HugSQL•ライフサイクル, DI: Component•フロントエンド: Reagent, re-frame•テスト: Midje, kerodon, clojure.test•ユーティリティ: Plumbing, Medley
#ccc_m2Componentベース
#ccc_m2ネームスペース間の依存
#ccc_m2規模感•総ファイル数: 650超•総コード行数: 50000超•含まれているライブラリの数: 400弱•テーブルの数: 123•uberjarのサイズ: 153MB•JavaScriptのサイズ: 852KB
#ccc_m2インフラ概要
#ccc_m2Clojureを採用して 良かったところ☀
#ccc_m2SimplicityImmutabilityInteroperabilityIsomorphismExtensibilityCompatibilityComposability
#ccc_m2シンプルさhttps://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.htmlVS?
#ccc_m2シンプルさhttps://docs.oracle.com/javase/tutorial/java/nutsandbolts/operators.htmlVS()
#ccc_m2https://www.youtube.com/watch?v=rI8tNMsozo0Rails Conf 2012 Keynote: Simplicity Mattersby Rich Hickey
#ccc_m2不変性•オブジェクトは不変(一部の参照型を除く)•関数を呼び出して引数を変更される恐れがないuser> (def m {:username "ayato-p" :age "25"})#'user/muser> (update m :age inc){:age 26, :username "ayato-p"}user> m{:age 25, :username "ayato-p"}
#ccc_m2σϑΥϧτͰϛϡʔλϒϧͳͷ ૣ͗͢Δ࠷దԽͩɻLuminus作者 Dmitri Sotnikov(@yogthos)https://twitter.com/yogthos/status/688250762334343170
#ccc_m2Java資産の活用•Clojureで記述されたライブラリがなくても Javaのライブラリが使えるという安心感•Clojureを書くように自然にJavaを呼び出せる
#ccc_m2(import [com.orangesignal.csv Csv])(defprotocol CsvLoader(load [this]))(extend-protocol CsvLoadercom.orangesignal.csv.CsvReader(load [csv-reader](->> (Csv/load csv-reader (str-ary-handler))(map vec))))
#ccc_m2Server/Clientを同一言語で•コンテキストスイッチがなくなる•プラットフォームに依存するようなコードがあっても 共通化できる•ReaderConditionals since Clojure 1.7•Transit formatで流れるようにデータの受け渡し(defn str->int [s]#?(:clj (java.lang.Integer/parseInt s):cljs (js/parseInt s)))
#ccc_m2拡張性の高さ•ライブラリに拡張ポイントが残されている•clojure.java.jdbcなど•Protocols / Multimethods•既存のJavaクラスも拡張できる
#ccc_m2(require [clojure.java.jdbc :as jdbc])(import org.postgresql.jdbc4.Jdbc4Arrayorg.postgresql.util.PGobject)(extend-protocol jdbc/IResultSetReadColumnJdbc4Array(result-set-read-column [val rsmeta idx](sequence (.getArray val)))PGobject(result-set-read-column [val rsmeta idx](parse-pgobject val)))
#ccc_m2高い後方互換性•バージョンを上げても、ほとんど影響がない•Clojure 1.3で動けばだいたい動くはず•関数の名前が衝突することは稀にある•古いライブラリでもたいてい問題なく動作する
#ccc_m2ݹͷϓϩδΣΫτͷϝδϟʔϦϏδϣϯΛ্ͭ͛ͯյΕͳ͔ͬͨΑɻ$MPKVSFޓੑΛେࣄʹͨ͠ઃܭ͔ͩΒͶɻCognitectの偉い人 Stuart Halloway(@stuarthalloway)https://twitter.com/stuarthalloway/status/793614590781390852
#ccc_m2組み合わせの容易性•少ないデータ型に対して大量の関数がある•個々のライブラリは独立している•特定のフレームワークを前提に設計されていない
#ccc_m2http://tomasp.net/blog/2015/library-frameworks/
#ccc_m2SimplicityImmutabilityInteroperabilityIsomorphismExtensibilityCompatibilityComposabilityand more
#ccc_m2•覚えることが少ないのにパワフル•単純なマップやベクタを渡せばいいのでテストが容易•Nil PunningによってNPEをある程度回避できる•REPLがあるので小さい粒度で確認ができる•マクロを適切に使えば一定の処理を一般化できる•Transducersを使うことで計算量が減らせることがある•Checkout Dependencyによってライブラリを同時開発可•Emacsを使うことに大義名分がある
#ccc_m2Clojureを利用していて 苦労したこと
#ccc_m2•大きなアプリの作り方が分からなかった•フレームワークがなかった•スタックトレースが難しかった•Jar地獄に陥った•なんだかんだでJavaの知識が欲しくなる•日本のコミュニティが小さかった•日本語の情報が少なかった
#ccc_m2まとめ
#ccc_m2•Clojureを選んだのは良いサービスを作るため•弊社はStuart Sierra's Componentベースで 開発している•シンプルさは選ばないと手に入らない•WAFやORMを使わない(使えない)のは良い面も 悪い面もある•Clojureを使ってもWebアプリは作れる