やりたいこと
全くやったこと無いが、関数型言語を使ってみたい。
具体的には、「scalatraでちっちゃいAPIアプリつくる」
ってことにしよう。
ついでにフロントははやりのreactを使ってみよう。これは別記事で。
scalatraっていうのはscalaのsinatraみたいな感じで、マイクロフレームワークだろう。
最初はclojureでcompojureっていうのを使ってみたかったんだけど、検索してもあんまり出てこなかったから諦めた。
scalaなどインストール
java7のインストール
http://www.oracle.com/technetwork/jp/java/javase/downloads/jdk7-downloads-1880260.html
こっからjdk-7u75-macosx-x64をダウンロード
実行
java -version
で1.7とかなんとかでたらOK
公式参考
http://www.scalatra.org/2.2/getting-started/installation.html
giter8,sbtのインストール
brew install giter8 brew install sbt
sbtはビルドツールだって。
giter8はgitからプロジェクトひな形とか取ってくる便利つーるらしい。
ためしにscalaでちょっと
なんせscalaなんて使ったこと無いので。
参考
http://www.scala-sbt.org/0.13/tutorial/ja/Hello.html
helloディレクトリ作り、移動して、なんかオブジェクト作ってビルドする
mkdir hello cd hello echo 'object Hi { def main(args: Array[String]) = println("Hi!") }' > hw.scala sbt Getting org.scala-sbt sbt 0.13.7 ... downloading https://repo.ty以下略
sbtってやったらなんかいろいろダウンロードし始めた。
終わったら
> run [info] Running Hi Hi! [success] Total time: 0 s, completed 2015/04/14 13:32:24
こうやって実行すんのか。
コンソールに入らなくても以下で実行できるらしい
sbt run [info] Set current project to hello (in build file:/Users/XXXXX/hello/) [info] Running Hi Hi! [success] Total time: 1 s, completed 2015/04/14 13:33:00
Scalatraのプロジェクトを作る
g8 scalatra/scalatra-sbt
対話的にプロジェクトを作れる。
またいろいろインストールしてた。
終わったらアプリ名とかいろいろ聞かれた。
g8 scalatra/scalatra-sbt organization [com.example]: aoyagiya name [My Scalatra Web App]: testScalaApp version [0.1.0-SNAPSHOT]: 0.0.1 servlet_name [MyScalatraServlet]: testScalaServlet package [com.example.app]: jp.saizoaoyagi.app scala_version [2.11.1]: 2.11.1 sbt_version [0.13.5]: 0.13.5 scalatra_version [2.3.0]: 2.3.0 Template applied in ./testscalaapp
公式の流れ通りビルドしてみる。
cd testscalaapp chmod u+x sbt ./sbt
あとは、最初にできたサーブレットをエディタで開いてみる
vi src/main/scala/jp/saizoaoyagi/app/testScalaServlet.scala
package jp.saizo-aoyagi.app import org.scalatra._ import scalate.ScalateSupport class testScalaServlet extends TestscalaappStack { get("/") { <html> <body> <h1>Hello, world!</h1> Say <a href="hello-scalate">hello to Scalate</a>. </body> </html> } }
閉じて、以下でwebアプリ立ち上げ
./sbt > container:start
http://localhost:8080
にアクセスすればなにか見えてOKだ
あと、以下のようにすればファイルを変えると勝手にリロードしてくれるらしい。そうじゃなきゃいちいちビルドすんのはpainfulだって。
./sbt > container:start > ~ ;copy-resources;aux-compile
おまけでjson返すように
ここを見ながら、json返すように改造
Scalatra2.2+scalatra-jsonでJSONを処理する | Developers.IO
scalatraが2.3.0でscalaが211.1だったので、
build.scalaに追記する内容がちょっと違った
libraryDependencies ++= Seq( 略 "org.scalatra" %% "scalatra-json" % ScalatraVersion, "org.json4s" %% "json4s-jackson" % "3.2.11", 略
参考
Maven Repository: org.scalatra » scalatra-json_2.10 » 2.3.0
package jp.saizoaoyagi.app import org.scalatra._ import scalate.ScalateSupport import org.fusesource.scalate.{ TemplateEngine, Binding } import org.fusesource.scalate.layout.DefaultLayoutStrategy import javax.servlet.http.HttpServletRequest import collection.mutable trait TestscalaappStack extends ScalatraServlet with ScalateSupport { /* wire up the precompiled templates */ override protected def defaultTemplatePath: List[String] = List("/WEB-INF/templates/views") override protected def createTemplateEngine(config: ConfigT) = { val engine = super.createTemplateEngine(config) engine.layoutStrategy = new DefaultLayoutStrategy(engine, TemplateEngine.templateTypes.map("/WEB-INF/templates/layouts/default." + _): _*) engine.packagePrefix = "templates" engine } /* end wiring up the precompiled templates */ override protected def templateAttributes(implicit request: HttpServletRequest): mutable.Map[String, Any] = { super.templateAttributes ++ mutable.Map.empty // Add extra attributes here, they need bindings in the build file } notFound { // remove content type in case it was set through an action contentType = null // Try to render a ScalateTemplate if no route matched findTemplate(requestPath) map { path => contentType = "text/html" layoutTemplate(path) } orElse serveStaticResource() getOrElse resourceNotFound() } }
case classって書き方について
Scalaクラスメモ(Hishidama's Scala class Memo)
これでサーバ起動して以下にアクセス
http://localhost:8080/json
jsonが返ってきた
感想
必要なものを勝手にインストールしてくれるのって結構いいな。
環境構築はそんなにめんどくさくなかった。
でも感覚としてはすっげえ時間かかる。