packages feed

firefly-example (empty) → 0.1.0.0

raw patch · 5 files changed

+205/−0 lines, 5 filesdep +aesondep +basedep +blaze-htmlsetup-changed

Dependencies added: aeson, base, blaze-html, firefly, mtl, text, wai

Files

+ LICENSE view
@@ -0,0 +1,30 @@+Copyright Chris Penner (c) 2017++All rights reserved.++Redistribution and use in source and binary forms, with or without+modification, are permitted provided that the following conditions are met:++    * Redistributions of source code must retain the above copyright+      notice, this list of conditions and the following disclaimer.++    * Redistributions in binary form must reproduce the above+      copyright notice, this list of conditions and the following+      disclaimer in the documentation and/or other materials provided+      with the distribution.++    * Neither the name of Chris Penner nor the names of other+      contributors may be used to endorse or promote products derived+      from this software without specific prior written permission.++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ README.md view
@@ -0,0 +1,104 @@+# Firefly++- [Example App](./firefly-example/app/Main.hs)+- [Hackage Docs](http://hackage.haskell.org/package/firefly-0.1.0.0/docs/Web-Firefly.html)++Firefly is dead simple http framework written in Haskell.++It strives for simplicity in implementation (and in use).+It's great for people learning Haskell, fiddling with Monads,+or who just need a really simple server for something.++Here's the minimal app:++```haskell+{-# language OverloadedStrings #-}+import Web.Firefly+import qualified Data.Text as T++main :: IO ()+main = run 3000 app++app :: App ()+app = do+  route "/hello" (return "hello" :: Handler T.Text)+```++Just that easy!++Check out the [Example App](./firefly-example/app/Main.hs) for more!++Specify your routes using regex patterns, the first one which matches will run.++`Handler` is a monad with access to the incoming request. You can access parts+of it using helpers, then return a response.++Here are some valid response types and their inferred Content-Type++- `Data.Text.Text`: `text/plain` +- `Data.Aeson.Value`: `application/json` +- `Blaze.Html.Html`: `text/html`++There are more in `Web.Firefly.Response`.++You can specify your status code using `(body, Status)` where body is any of+the above types and Status is an Integer status code.++Or, add headers too with `(body, Status, HeaderMap)` where `HeaderMap` is a map+of names to values.++## Examples++Let's write some more interesting handlers:++```haskell+hello :: App T.Text+hello = do+  -- | Get the 'name' query param from the url, if it doesn't exist use 'Stranger'+  name <- getQuery "name"+  -- If we just return some Text the response will be status 200 with a Content-Type of "text/plain"+  return $ "Hello " <> fromMaybe "Stranger" name+```++Here's an example of responding with JSON:++```haskell+import Data.Aeson (ToJSON, FromJSON)+import GHC.Generics (Generic)+import qualified Data.Text as T+import qualified Network.Wai as W+import Web.Firefly++data User = User+  { username::T.Text+  , age::Int+  } deriving (Generic, ToJSON, FromJSON) -- Derive JSON instances++-- A reguler 'ol user+steve :: User+steve = User{username="Steve", age=26}++-- | Get a user by username+getUser :: App W.Response+getUser = do+  uname <- getQuery "username"+  return $ case uname of+             -- The Json constructor signals to serialize the value and respond as "application/json"+             Just "steve" -> toResponse $ Json steve +             Just name -> toResponse ("Couldn't find user: " `mappend` name, notFound404)+             Nothing -> toResponse ("Please provide a 'username' parameter" :: T.Text, badRequest400)+```++## Should I/Shouldn't I use Firefly?++You should use Firefly if:++- You're intimidated by monads and want to learn more!+- You want to write a hobby project+- You like understanding the stack you're working with (The whole lib is ~300 lines without docs/imports)++Don't use Firefly if:++- You'll have thousands of users+- You want the most performant server possible+- You want to have lots of helper libs available
+ Setup.hs view
@@ -0,0 +1,2 @@+import Distribution.Simple+main = defaultMain
+ app/Main.hs view
@@ -0,0 +1,38 @@+{-# language OverloadedStrings #-}+{-# language DeriveAnyClass #-}+{-# language DeriveGeneric #-}+module Main where++import Data.Aeson (ToJSON, FromJSON)+import GHC.Generics (Generic)+import qualified Data.Text as T+import qualified Network.Wai as W+import Web.Firefly++-- | The Main app; this runs our app on port 3000 with logger middleware+main :: IO ()+main = run 3000 app++app :: App ()+app = do+  route "/users" getUser++data User = User+  { username::T.Text+  , age::Int+  } deriving (Generic, ToJSON, FromJSON) -- Derive JSON instances++-- A reguler 'ol user+steve :: User+steve = User{username="Steve", age=26}++-- | Get a user by username+getUser :: App W.Response+getUser = do+  uname <- getQuery "username"+  return $ case uname of+             -- | We can use 'toResponse' to convert differing response types+             -- to a common Wai Response.+             Just "steve" -> toResponse $ Json steve -- If you just provide a body the status defaults to 200+             Just name -> toResponse ("Couldn't find user: " `mappend` name, notFound404)+             Nothing -> toResponse ("Please provide a 'username' parameter" :: T.Text, badRequest400)
+ firefly-example.cabal view
@@ -0,0 +1,31 @@+name:                firefly-example+version:             0.1.0.0+synopsis:           A simple example using Firefly+-- description:+homepage:            https://github.com/ChrisPenner/Firefly#readme+license:             BSD3+license-file:        LICENSE+author:              Chris Penner+maintainer:          christopher.penner@gmail.com+copyright:           2017 Chris Penner+category:            Web+build-type:          Simple+extra-source-files:  README.md+cabal-version:       >=1.10++executable firefly-example-exe+  hs-source-dirs:      app+  main-is:             Main.hs+  ghc-options:         -threaded -rtsopts -with-rtsopts=-N+  build-depends:       base >= 4.7 && < 5+                     , firefly+                     , text+                     , aeson+                     , blaze-html+                     , mtl+                     , wai+  default-language:    Haskell2010++source-repository head+  type:     git+  location: https://github.com/ChrisPenner/Firefly