F#で
シンプルな API
を作ろう
About Me
twitter
GitHub
作ったもの
題材
Web アプリケーションフレームワーク
Sinatraとか
Scalatraとか
Ruby : Sinatra
シンプル!
require 'sinatra'
get '/hi' do
"Hello World!"
end
Scala : Scalatra
シンプル!
import org.scalatra._ class ScalatraExample extends ScalatraServlet { get("/hi") { <h1>Hello World!</h1> } }
F# : Enku
し、シンプル??
open System
open System.Web.Http
open System.Web.Http.SelfHost
open Newtonsoft.Json.Serialization
open Enku
let config = new HttpSelfHostConfiguration("http://localhost:9090/")
config.Formatters.JsonFormatter.SerializerSettings.ContractResolver
<- CamelCasePropertyNamesContractResolver()
let route = Routing.route config
route "hi" <| fun _ ->
[
get, fun req -> async {
return Content.html "<h1>Hello World!</h1>" |> Response.Ok }
], fun req e -> Content.error e |> Response.InternalServerError
let server = new HttpSelfHostServer(config)
server.OpenAsync().Wait()
F# : Enku
本質的な部分はシンプル!
(前頁のコードを微調整してます)
route "hi" <| fun _ -> [ get, fun _ -> async { return html "<h1>Hello World</h1>" |> Ok } ]
シンプルにするために
- 短い名前
- 丸括弧を避ける
- 関数のタプル
- 関数のタプルのリストを返す関数
route "hi" <| fun _ -> [ get, fun _ -> async { return html "<h1>Hello World!</h1>" |> Ok }
post <|> put, fun _ -> async { return html "<h1>Thank You!</h1>" |> Ok }
]
クラス?
let hiController req = let h1 text = html <| sprintf "<h1>%s</h1>" text [ get, fun _ -> async { return h1 "Hello World!" |> Ok } post, fun _ -> async { return h1 "Thank You!" |> Ok } ] route "hi" hiController
コンストラクタ、メンバ、属性
本当のクラスより良いところ
関数合成できる
たとえば、メソッド(に相当する関数)のインターセプタ
route "hi" <| fun _ ->
[
get, around [log] <| fun _ -> async {
return html "<h1>Hello World!</h1>" |> Ok }
]
たとえば、属性(に相当する関数)の合成
route "hi" <| fun _ -> [ get <|> ajax, fun _ -> async { return html "<h1>Hello World!</h1>" |> Ok } ]
本当のクラスよりも悪いところ
-
シグネチャが複雑になりがち
- typeで別名つけたり判別共用体で緩和できる
- メソッド相当の関数のシグネチャはどれも同じ
- メソッド相当の関数を明示的には呼び出せない
- 名前がない
- 名前をつけたとしてもタイプセーフには呼べない
まとめ
- 関数、タプル、リストの組み合わせでシンプルに
- クラスっぽい構造が作れる
- 場合によっては本物のクラスよりよい選択かも?
- リフレクションで処理される前提のクラスの代わりとか
- 例) ASP.NET MVCのController
F# でシンプルなAPIを作ろう
By nakamura_to
F# でシンプルなAPIを作ろう
- 2,113