A simple, sinatra-inspired web framework. http://github.com/moonmaster9000/bird
|Latest on Hackage:||0.0.19|
This package is not currently in any snapshots. If you're interested in using it, we recommend adding it to Stackage Nightly. Doing so will make builds more reliable, and allow stackage.org to host generated Haddocks.
A sinatra-ish web framework written in haskell, riding on top of Hack.
Sinatra has a beautiful, simple, elegant syntax, but it's essentially an attempt to bring pattern matching to a language never intended for pattern matching. Why not attempt something similar in a language with not just beautiful pattern matching, but with all the declarative bells and whistles: lazy evaluation, first-class functions, currying, polymorphism?
λ cabal update && cabal install bird
Note: make sure $HOME/.cabal/bin is in your PATH.
Create an app
λ bird hatch StarWars A fresh bird app has been created in StarWars.
Compile your app
λ cd StarWars λ bird nest [1 of 2] Compiling StarWars ( StarWars.hs, StarWars.o ) [2 of 2] Compiling Main ( Main.hs, Main.o ) Linking Main ... λ
Start your app (runs on port 3000)
λ bird fly A bird was just spotted in flight at http://localhost:3000
Try it out
λ curl http://localhost:3000 Hello, Bird!
-- StarWars.bird.hs import Data.String.Utils (join) get ["droids"] = do body "These aren't the droids you're looking for. Move along." status 404 post ["jedi"] = do name <- param "name" teacher <- param "teacher" case teacher of Just "Yoda" -> body "The force is strong with this one!" >> status 201 _ -> body "Sorry. The force is not with this one." >> status 400 get ("force":xs) = do body $ "May the force be with you " ++ (join ", " xs) ++ "!" get  = do name <- param "name" log "I'm about to greet a Jedi. Teehee!" body $ "Greetings, " ++ (maybe "Jedi!" id name)
Now recompile your app and start it flying:
λ bird nest λ bird fly & λ curl -i http://localhost:3000/force/Han/Chewie HTTP/1.1 200 OK Connection: close Content-Type: text/html Date: Sat, 31 Jul 2010 14:07:17 GMT Server: Happstack/0.5.0.2 May the force be with you Han, Chewie! λ curl -i -X POST http://localhost:3000/jedi -d name=Luke -d teacher=Yoda HTTP/1.1 201 Created Connection: close Content-Type: text/html Date: Sat, 21 Aug 2010 21:38:11 GMT Server: Happstack/0.5.0.2 The force is strong with this one! λ curl -i http://localhost:3000/droids HTTP/1.1 404 Not Found Connection: close Content-Type: text/html Date: Sat, 31 Jul 2010 14:08:35 GMT Server: Happstack/0.5.0.2 These aren't the droids you're looking for. Move along.
You have four functions to implement: get, post, put, and delete. They each accept a Bird Request.
Inside the function body, you can use the following methods (don't worry, this is a growing list):
param :: String -> Maybe String -- ex: for the request GET /droids?name=c3po, -- then `p <- param "name"' would bind the value `Just "c3po"' to the variable "p" body :: String -> BirdResponder () -- takes a string and sets the Http Response body to whatever the string contained. status :: Integer -> BirdResponder () -- takes a number, and sets the HTTP Reponse header "Status" to that number. mime :: String -> BirdResponder () -- sets the mime type to whatever you provide -- ex: get  = body "Hello World" >> mime "text/plain" header :: String -> String -> BirdResponder () -- creates/updates a header -- ex: get  = body "Hello World" >> header "X-Powered-By" "BIRD!" log :: String -> BirdResponder () -- adds to the log -- ex: get  = body "Hello World" >> log "Why did I just greet the world?"
This project is still in its infancy. Coming features:
- support for multipart forms submissions
- helpers for popular html generation solutions (Hamlet, HStringTemplate, HAXML, BlazeHTML, etc.)
- WAI support
- static asset serving
- support for sending files