tungd / haskell-www

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

www

Wai helper library. It started out as a colelction of helpers I wrote while building my own web project in Haskell. As for the package name, when I decided to extract to its own library I noticed the module name Network.Wai.Web would naturally make for package name wai-web and couldn't help myself :)

Motivation

I wanted a a web library for Haskell, with type-safe routing, monad transformers yet simple and doesn't requires TemplateHaskell. I looked at the frameworks available and did not find the one that suits my taste.

  • Yesod: TemplateHaskell all over the place
  • Scotty, Simple: Text-based routing
  • Spock: the name was weird (I'm a Starwars fan, what's up?), no monad transformer, and in generall I dislike the fact that everything has to be in one place, in one single monad
  • Snap: Snap is better than Spock in that it can compose smaller apps - a.k.a Snaplets, still no monad transformer
  • Fn, Firefly: these are actually very close to my need; in fact they're the inspiration for www, but IMO they're too far away from the Wai Application interface

Example

I highly recommend using www along with rio and data-has. As for database my recommendation is selda. This example include features required in a typical webapp:

  • Logging
  • Database connection
  • HTML
  • JSON
module Main where

import Data.Has
import Database.Selda
import Database.Selda.Backend
import Network.Wai.Handler.Warp
import Network.Wai.Application.Static
import Network.Wai.Web
import RIO
import RIO.Orphans ()
import Web.Routes


data Sitemap = Post Text | Category Text
  deriving (Show, Generic)

instance PathInfo Sitemap

instance {-# OVERLAPPING #-}
  (Has LogFunc env) => HasLogFunc env where
  logFuncL = hasLens

instance (Has SeldaConnection env) => MonadSelda (RIO env) where
  seldaConnection = pure =<< asks getter


main :: IO ()
main = do
  conn <- sqliteOpen "db.sqlite"
  (logger, closeLogger) <- newLogFunc =<< logOptionsHandle stdout True

  runRIO (logger) server

  seldaClose conn
  closeLogger


server
  :: (Has SeldaConnection env, HasLogFunc env)
  => RIO env ()
server = do
  env <- ask
  liftIO . runEnv 3000
    $ routeT "sitemap.xml" (runRIO env) sitemapHandler
    $ routeT "" (runRIO env) blogHandler
    $ routeT "" (runRIO env) homeHandler
    $ staticApp (defaultWebAppSettings "public")

sitemapHandler
  :: (Has SeldaConnection env, HasLogFunc env)
  => Root -> ApplicationT (RIO env)
sitemapHandler _ _ = respond $ Xml $ ...

blogHandler
  :: (Has SeldaConnection env, HasLogFunc env)
  => Sitemap -> ApplicationT (RIO env)

blogHandler (Blog slug) req = do
  respond $ ...

blogHandler (Category cat) req = do
  respond $ ...

homeHandler
  :: (Has SeldaConnection env, HasLogFunc env)
  => Root -> ApplicationT (RIO env)
homeHandler Root _ = ...
homeHandler (Fallback _) _ = ...

License

Copyright 2018 Tung Dao

Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

About

License:Apache License 2.0


Languages

Language:Haskell 100.0%