15
みんなでWAIWAI Webアプリ みんなでWAIWAI Webアプリ みんなでWAIWAI Webアプリ みんなでWAIWAI Webアプリ みんなでWAIWAI Webアプリ Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe Kiwamu Okabe

みんなでWAIWAI Webアプリ

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: みんなでWAIWAI Webアプリ

みんなでWAIWAI WebアプリみんなでWAIWAI WebアプリみんなでWAIWAI WebアプリみんなでWAIWAI WebアプリみんなでWAIWAI Webアプリ

Kiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu OkabeKiwamu Okabe

Page 2: みんなでWAIWAI Webアプリ

Web流行ってますねWeb流行ってますねWeb流行ってますねWeb流行ってますねWeb流行ってますね

猫も杓子もWebアプリ。猫も杓子もWebアプリ。猫も杓子もWebアプリ。猫も杓子もWebアプリ。猫も杓子もWebアプリ。

WebアプリをHaskellでも作れるとWebアプリをHaskellでも作れるとWebアプリをHaskellでも作れるとWebアプリをHaskellでも作れるとWebアプリをHaskellでも作れると

=> モテモテ?=> モテモテ?=> モテモテ?=> モテモテ?=> モテモテ?

Page 3: みんなでWAIWAI Webアプリ

WebアプリといえばRailsWebアプリといえばRailsWebアプリといえばRailsWebアプリといえばRailsWebアプリといえばRails

近年のWebアプリは↓の連携で設計するみたい。近年のWebアプリは↓の連携で設計するみたい。近年のWebアプリは↓の連携で設計するみたい。近年のWebアプリは↓の連携で設計するみたい。近年のWebアプリは↓の連携で設計するみたい。

☆ Webアプリ☆ Webアプリ☆ Webアプリ☆ Webアプリ☆ Webアプリ

☆ Webアプリケーションフレームワーク☆ Webアプリケーションフレームワーク☆ Webアプリケーションフレームワーク☆ Webアプリケーションフレームワーク☆ Webアプリケーションフレームワーク

☆ Webサーバ☆ Webサーバ☆ Webサーバ☆ Webサーバ☆ Webサーバ

Page 4: みんなでWAIWAI Webアプリ

アプリとサーバの連携はどうやる?アプリとサーバの連携はどうやる?アプリとサーバの連携はどうやる?アプリとサーバの連携はどうやる?アプリとサーバの連携はどうやる?

WSGIとかRackが有名みたい。WSGIとかRackが有名みたい。WSGIとかRackが有名みたい。WSGIとかRackが有名みたい。WSGIとかRackが有名みたい。* http://www.python.org/dev/peps/pep-0333/* http://rack.github.com/* http://www.python.org/dev/peps/pep-0333/* http://rack.github.com/* http://www.python.org/dev/peps/pep-0333/* http://rack.github.com/* http://www.python.org/dev/peps/pep-0333/* http://rack.github.com/* http://www.python.org/dev/peps/pep-0333/* http://rack.github.com/

☆ Webアプリケーションフレームワーク☆ Webアプリケーションフレームワーク☆ Webアプリケーションフレームワーク☆ Webアプリケーションフレームワーク☆ Webアプリケーションフレームワーク

☆ Webサーバ☆ Webサーバ☆ Webサーバ☆ Webサーバ☆ Webサーバ

の界面をAPI化したものらしい。の界面をAPI化したものらしい。の界面をAPI化したものらしい。の界面をAPI化したものらしい。の界面をAPI化したものらしい。

CGIしかなかった20世紀からずいぶん遠くへ。CGIしかなかった20世紀からずいぶん遠くへ。CGIしかなかった20世紀からずいぶん遠くへ。CGIしかなかった20世紀からずいぶん遠くへ。CGIしかなかった20世紀からずいぶん遠くへ。

Page 5: みんなでWAIWAI Webアプリ

アプリとサーバを分離(Rackの場合)アプリとサーバを分離(Rackの場合)アプリとサーバを分離(Rackの場合)アプリとサーバを分離(Rackの場合)アプリとサーバを分離(Rackの場合)require 'rubygems'require 'rack'

class HelloWorld def call(env) [200, {"Content-Type" => "text/html"}, "Hello Rack!"] endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

require 'rubygems'require 'rack'

class HelloWorld def call(env) [200, {"Content-Type" => "text/html"}, "Hello Rack!"] endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

require 'rubygems'require 'rack'

class HelloWorld def call(env) [200, {"Content-Type" => "text/html"}, "Hello Rack!"] endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

require 'rubygems'require 'rack'

class HelloWorld def call(env) [200, {"Content-Type" => "text/html"}, "Hello Rack!"] endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

require 'rubygems'require 'rack'

class HelloWorlddef call(env)

[200, {"Content-Type" => "text/html"}, "Hello Rack!"]endend

Rack::Handler::Mongrel.run HelloWorld.new, :Port => 9292

みごとにcallメソッドで分離されてます。みごとにcallメソッドで分離されてます。みごとにcallメソッドで分離されてます。みごとにcallメソッドで分離されてます。みごとにcallメソッドで分離されてます。

Page 6: みんなでWAIWAI Webアプリ

そーゆーのHaskellにないの?そーゆーのHaskellにないの?そーゆーのHaskellにないの?そーゆーのHaskellにないの?そーゆーのHaskellにないの?

WAIってのがありますよ。WAIってのがありますよ。WAIってのがありますよ。WAIってのがありますよ。WAIってのがありますよ。

Page 7: みんなでWAIWAI Webアプリ

WAIのインターフェイスWAIのインターフェイスWAIのインターフェイスWAIのインターフェイスWAIのインターフェイス

Webアプリケーションフレームワークの例Webアプリケーションフレームワークの例Webアプリケーションフレームワークの例Webアプリケーションフレームワークの例Webアプリケーションフレームワークの例-- wai-app-staticstaticApp :: StaticSettings -> Application-- wai-app-file-cgicgiApp :: ClassicAppSpec -> CgiAppSpec -> CgiRoute -> Application

-- wai-app-staticstaticApp :: StaticSettings -> Application-- wai-app-file-cgicgiApp :: ClassicAppSpec -> CgiAppSpec -> CgiRoute -> Application

-- wai-app-staticstaticApp :: StaticSettings -> Application-- wai-app-file-cgicgiApp :: ClassicAppSpec -> CgiAppSpec -> CgiRoute -> Application

-- wai-app-staticstaticApp :: StaticSettings -> Application-- wai-app-file-cgicgiApp :: ClassicAppSpec -> CgiAppSpec -> CgiRoute -> Application

-- wai-app-staticstaticApp :: StaticSettings -> Application-- wai-app-file-cgicgiApp :: ClassicAppSpec -> CgiAppSpec -> CgiRoute -> Application

Webサーバの例Webサーバの例Webサーバの例Webサーバの例Webサーバの例-- warprun :: Port -> Application -> IO ()-- wai-extrarunSendfile :: B.ByteString -> Application -> IO ()-- wai-handler-webkitrun :: String -> Application -> IO ()

-- warprun :: Port -> Application -> IO ()-- wai-extrarunSendfile :: B.ByteString -> Application -> IO ()-- wai-handler-webkitrun :: String -> Application -> IO ()

-- warprun :: Port -> Application -> IO ()-- wai-extrarunSendfile :: B.ByteString -> Application -> IO ()-- wai-handler-webkitrun :: String -> Application -> IO ()

-- warprun :: Port -> Application -> IO ()-- wai-extrarunSendfile :: B.ByteString -> Application -> IO ()-- wai-handler-webkitrun :: String -> Application -> IO ()

-- warprun :: Port -> Application -> IO ()-- wai-extrarunSendfile :: B.ByteString -> Application -> IO ()-- wai-handler-webkitrun :: String -> Application -> IO ()

Application型がキモ。Application型がキモ。Application型がキモ。Application型がキモ。Application型がキモ。

Page 8: みんなでWAIWAI Webアプリ

じゃあ作ってみようじゃあ作ってみようじゃあ作ってみようじゃあ作ってみようじゃあ作ってみよう

ファイルの中身返すだけのWebサーバ。 使用ライブラリは以下。ファイルの中身返すだけのWebサーバ。 使用ライブラリは以下。ファイルの中身返すだけのWebサーバ。 使用ライブラリは以下。ファイルの中身返すだけのWebサーバ。 使用ライブラリは以下。ファイルの中身返すだけのWebサーバ。 使用ライブラリは以下。

☆ フレームワーク: wai-app-static☆ フレームワーク: wai-app-static☆ フレームワーク: wai-app-static☆ フレームワーク: wai-app-static☆ フレームワーク: wai-app-static

☆ サーバ: Warp☆ サーバ: Warp☆ サーバ: Warp☆ サーバ: Warp☆ サーバ: Warp

Page 9: みんなでWAIWAI Webアプリ

材料1: Warp材料1: Warp材料1: Warp材料1: Warp材料1: Warp

run関数を使えば簡単そう。run関数を使えば簡単そう。run関数を使えば簡単そう。run関数を使えば簡単そう。run関数を使えば簡単そう。

Page 10: みんなでWAIWAI Webアプリ

材料2: wai-app-static その1材料2: wai-app-static その1材料2: wai-app-static その1材料2: wai-app-static その1材料2: wai-app-static その1

Application作りたいんだけど、StaticSettingsってのはどこから?Application作りたいんだけど、StaticSettingsってのはどこから?Application作りたいんだけど、StaticSettingsってのはどこから?Application作りたいんだけど、StaticSettingsってのはどこから?Application作りたいんだけど、StaticSettingsってのはどこから?

Page 11: みんなでWAIWAI Webアプリ

材料3: wai-app-static その2材料3: wai-app-static その2材料3: wai-app-static その2材料3: wai-app-static その2材料3: wai-app-static その2

ルートディレクトリを指定したらイイ感じなStaticSettingsを作ってくれる関数発見。ルートディレクトリを指定したらイイ感じなStaticSettingsを作ってくれる関数発見。ルートディレクトリを指定したらイイ感じなStaticSettingsを作ってくれる関数発見。ルートディレクトリを指定したらイイ感じなStaticSettingsを作ってくれる関数発見。ルートディレクトリを指定したらイイ感じなStaticSettingsを作ってくれる関数発見。

Page 12: みんなでWAIWAI Webアプリ

できたコードできたコードできたコードできたコードできたコード{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Warpimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run 9191 myWaiApp

{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Warpimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run 9191 myWaiApp

{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Warpimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run 9191 myWaiApp

{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Warpimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run 9191 myWaiApp

{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Warpimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run 9191 myWaiApp

http://localhost:9191 をWebブラウザで見てみましょう。http://localhost:9191 をWebブラウザで見てみましょう。http://localhost:9191 をWebブラウザで見てみましょう。http://localhost:9191 をWebブラウザで見てみましょう。http://localhost:9191 をWebブラウザで見てみましょう。

Page 13: みんなでWAIWAI Webアプリ

Webサーバをすげ替えることもWebサーバをすげ替えることもWebサーバをすげ替えることもWebサーバをすげ替えることもWebサーバをすげ替えることも{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Webkitimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run "MyWaiApp" myWaiApp

{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Webkitimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run "MyWaiApp" myWaiApp

{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Webkitimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run "MyWaiApp" myWaiApp

{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Webkitimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run "MyWaiApp" myWaiApp

{-# LANGUAGE OverloadedStrings #-}import Network.Waiimport Network.Wai.Handler.Webkitimport Network.Wai.Application.Static

myWaiApp :: ApplicationmyWaiApp = staticApp $ defaultFileServerSettings "."

main :: IO ()main = run "MyWaiApp" myWaiApp

Webkitのウィンドウが起動して、その中でWebアプリが動く。Webkitのウィンドウが起動して、その中でWebアプリが動く。Webkitのウィンドウが起動して、その中でWebアプリが動く。Webkitのウィンドウが起動して、その中でWebアプリが動く。Webkitのウィンドウが起動して、その中でWebアプリが動く。

Page 14: みんなでWAIWAI Webアプリ

ちょっとまともなApplicationちょっとまともなApplicationちょっとまともなApplicationちょっとまともなApplicationちょっとまともなApplication{-# LANGUAGE OverloadedStrings #-}import qualified Network.Wai as Wimport qualified Network.HTTP.Types as Himport qualified Network.Wai.Handler.Warp as WPimport qualified Data.ByteString.Lazy as L

header :: H.ResponseHeaders -- [(HeaderName, ByteString)]header = [("Content-Type", "text/plain")]

myWaiApp :: W.Application -- Request -> ResourceT IO ResponsemyWaiApp req | W.requestMethod req /= "GET" = return r where r = W.responseLBS H.status405 header "Only GET is supported"myWaiApp req = return r where s = "Path:" `L.append` L.fromChunks [W.rawPathInfo req] r = W.responseLBS H.status200 header s

main :: IO ()main = WP.run 9191 myWaiApp

{-# LANGUAGE OverloadedStrings #-}import qualified Network.Wai as Wimport qualified Network.HTTP.Types as Himport qualified Network.Wai.Handler.Warp as WPimport qualified Data.ByteString.Lazy as L

header :: H.ResponseHeaders -- [(HeaderName, ByteString)]header = [("Content-Type", "text/plain")]

myWaiApp :: W.Application -- Request -> ResourceT IO ResponsemyWaiApp req | W.requestMethod req /= "GET" = return r where r = W.responseLBS H.status405 header "Only GET is supported"myWaiApp req = return r where s = "Path:" `L.append` L.fromChunks [W.rawPathInfo req] r = W.responseLBS H.status200 header s

main :: IO ()main = WP.run 9191 myWaiApp

{-# LANGUAGE OverloadedStrings #-}import qualified Network.Wai as Wimport qualified Network.HTTP.Types as Himport qualified Network.Wai.Handler.Warp as WPimport qualified Data.ByteString.Lazy as L

header :: H.ResponseHeaders -- [(HeaderName, ByteString)]header = [("Content-Type", "text/plain")]

myWaiApp :: W.Application -- Request -> ResourceT IO ResponsemyWaiApp req | W.requestMethod req /= "GET" = return r where r = W.responseLBS H.status405 header "Only GET is supported"myWaiApp req = return r where s = "Path:" `L.append` L.fromChunks [W.rawPathInfo req] r = W.responseLBS H.status200 header s

main :: IO ()main = WP.run 9191 myWaiApp

{-# LANGUAGE OverloadedStrings #-}import qualified Network.Wai as Wimport qualified Network.HTTP.Types as Himport qualified Network.Wai.Handler.Warp as WPimport qualified Data.ByteString.Lazy as L

header :: H.ResponseHeaders -- [(HeaderName, ByteString)]header = [("Content-Type", "text/plain")]

myWaiApp :: W.Application -- Request -> ResourceT IO ResponsemyWaiApp req | W.requestMethod req /= "GET" = return r where r = W.responseLBS H.status405 header "Only GET is supported"myWaiApp req = return r where s = "Path:" `L.append` L.fromChunks [W.rawPathInfo req] r = W.responseLBS H.status200 header s

main :: IO ()main = WP.run 9191 myWaiApp

{-# LANGUAGE OverloadedStrings #-}import qualified Network.Wai as Wimport qualified Network.HTTP.Types as Himport qualified Network.Wai.Handler.Warp as WPimport qualified Data.ByteString.Lazy as L

header :: H.ResponseHeaders -- [(HeaderName, ByteString)]header = [("Content-Type", "text/plain")]

myWaiApp :: W.Application -- Request -> ResourceT IO ResponsemyWaiApp req | W.requestMethod req /= "GET" = return rwhere

r = W.responseLBS H.status405 header "Only GET is supported"myWaiApp req = return rwhere

s = "Path:" `L.append` L.fromChunks [W.rawPathInfo req] r = W.responseLBS H.status200 header s

main :: IO ()main = WP.run 9191 myWaiApp

Page 15: みんなでWAIWAI Webアプリ

参考資料参考資料参考資料参考資料参考資料* 「(続) Haskell で Web サーバーを実装してみました」 山本和彦 http://www.mew.org/~kazu/material/2011-mighttpd2.pdf* 「WAI」パッケージ http://hackage.haskell.org/package/wai* 「Warp」パッケージ http://hackage.haskell.org/package/warp* 「wai-app-static」パッケージ http://hackage.haskell.org/package/wai-app-static

* 「(続) Haskell で Web サーバーを実装してみました」 山本和彦 http://www.mew.org/~kazu/material/2011-mighttpd2.pdf* 「WAI」パッケージ http://hackage.haskell.org/package/wai* 「Warp」パッケージ http://hackage.haskell.org/package/warp* 「wai-app-static」パッケージ http://hackage.haskell.org/package/wai-app-static

* 「(続) Haskell で Web サーバーを実装してみました」 山本和彦 http://www.mew.org/~kazu/material/2011-mighttpd2.pdf* 「WAI」パッケージ http://hackage.haskell.org/package/wai* 「Warp」パッケージ http://hackage.haskell.org/package/warp* 「wai-app-static」パッケージ http://hackage.haskell.org/package/wai-app-static

* 「(続) Haskell で Web サーバーを実装してみました」 山本和彦 http://www.mew.org/~kazu/material/2011-mighttpd2.pdf* 「WAI」パッケージ http://hackage.haskell.org/package/wai* 「Warp」パッケージ http://hackage.haskell.org/package/warp* 「wai-app-static」パッケージ http://hackage.haskell.org/package/wai-app-static

* 「(続) Haskell で Web サーバーを実装してみました」 山本和彦 http://www.mew.org/~kazu/material/2011-mighttpd2.pdf* 「WAI」パッケージ http://hackage.haskell.org/package/wai* 「Warp」パッケージ http://hackage.haskell.org/package/warp* 「wai-app-static」パッケージ http://hackage.haskell.org/package/wai-app-static