Last active
August 29, 2015 14:14
-
-
Save thefish/a5ef2313c31131b00792 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: App | |
version: 0.1.0.0 | |
synopsis: App backend JSON API server | |
license: AllRightsReserved | |
license-file: LICENSE | |
author: Cidevant | |
maintainer: [email protected] | |
category: Web | |
build-type: Simple | |
cabal-version: >= 1.20 | |
executable App | |
hs-source-dirs: src | |
main-is: Main.hs | |
other-modules: Models | |
, ModelsJson | |
-- other-extensions: | |
build-depends: base >= 4 && < 5 | |
, scotty > 0.7 | |
, aeson | |
, persistent | |
, persistent-postgresql | |
, persistent-template | |
, http-types | |
, text | |
, bytestring | |
, time | |
, wai-extra | |
, wai-middleware-static | |
, transformers | |
, blaze-html | |
, scientific >= 0.2.0.2 | |
, yaml | |
, conduit | |
, aeson | |
-- hDevTools with cabal-sandbox env. | |
, cabal-cargs | |
-- Live reload | |
, fsnotify | |
, system-fileio | |
, system-filepath | |
, process | |
, mtl | |
default-language: Haskell2010 | |
ghc-options: -Wall -threaded |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE ScopedTypeVariables #-} | |
module Main where | |
import Control.Monad.IO.Class (liftIO) | |
import Network.HTTP.Types | |
import Network.Wai.Middleware.RequestLogger | |
import Network.Wai.Middleware.Static | |
import Web.Scotty | |
import qualified Database.Persist.Postgresql as Db | |
import Models | |
import ModelsJson | |
main :: IO() | |
main = Db.withPostgresqlPool connStr 10 $ \pool -> do | |
-- Migrate database | |
runDB pool $ Db.runMigration migrateAll | |
-- Start server | |
scotty 5001 $ do | |
middleware logStdoutDev | |
-- * Static content middleware | |
--middleware $ staticPolicy (noDots >-> addBase "public") | |
get "/" $ | |
html $ "<h1>Backend API server (haskell Scotty)</h1>" | |
-- * CRUD | |
get "/api/users" $ do | |
(users :: [Db.Entity User]) <- | |
liftIO $ runDB pool $ Db.selectList [] [] | |
json users | |
post "/api/users" $ do | |
(user :: User) <- jsonData | |
uid <- liftIO $ runDB pool $ Db.insert user | |
json $ Db.Entity uid user | |
get "/api/users/:id" $ do | |
(uid :: Integer) <- param "id" | |
let (key :: Db.Key User) = Db.Key (Db.PersistInt64 $ fromIntegral uid) | |
(userDb :: Maybe User) <- | |
liftIO $ runDB pool $ Db.get $ key | |
case userDb of | |
Just user -> do setHeader "Access-Control-Allow-Origin" "*" | |
json $ Db.Entity key user | |
Nothing -> status notFound404 | |
put "/api/users/:id" $ do | |
(uid :: Integer) <- param "id" | |
let (key :: Db.Key User) = Db.Key (Db.PersistInt64 $ fromIntegral uid) | |
(userJson :: User) <- jsonData | |
(userDb :: Maybe User) <- | |
liftIO $ runDB pool $ Db.get $ key | |
case userDb of | |
Just _ -> do liftIO $ runDB pool $ Db.replace key $ userJson | |
json $ Db.Entity key userJson | |
Nothing -> status notFound404 | |
delete "/api/users/:id" $ do | |
(uid :: Integer) <- param "id" | |
let key :: Db.Key User = Db.Key (Db.PersistInt64 $ fromIntegral uid) | |
(user :: Maybe User) <- | |
liftIO $ runDB pool $ Db.get $ key | |
case user of | |
Just _ -> do liftIO $ runDB pool $ Db.delete $ key | |
status noContent204 | |
Nothing -> status notFound404 | |
-- Error handlers | |
notFound $ do | |
status notFound404 | |
html $ "<h1>Not found</h1>" | |
connStr :: Db.ConnectionString | |
connStr = "host=localhost dbname=road_free_development user=cidevant password='' port=5432" | |
runDB :: Db.ConnectionPool -> Db.SqlPersistM a -> IO a | |
runDB = flip Db.runSqlPersistMPool |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE EmptyDataDecls #-} | |
{-# LANGUAGE FlexibleContexts #-} | |
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE GADTs #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE QuasiQuotes #-} | |
{-# LANGUAGE TemplateHaskell #-} | |
{-# LANGUAGE TypeFamilies #-} | |
module Models where | |
import Control.Applicative | |
import Control.Monad | |
import Data.Aeson | |
import qualified Data.Text as T | |
import Database.Persist | |
import Database.Persist.TH | |
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase| | |
User sql=users | |
name T.Text | |
client_id Int | |
deriving Show Eq | |
|] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{-# LANGUAGE FlexibleInstances #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE RecordWildCards #-} | |
{-# OPTIONS_GHC -fwarn-unused-matches -fwarn-unused-binds -fwarn-unused-imports #-} | |
module ModelsJson where | |
import Control.Applicative | |
import Control.Monad | |
import Data.Aeson | |
import Database.Persist | |
import Models | |
instance ToJSON (Entity User) where | |
toJSON (Entity uid (c@User{..})) = | |
object | |
[ "id" .= uid | |
, "name" .= userName | |
, "client_id" .= userClient_id | |
] | |
instance FromJSON User where | |
parseJSON (Object v) = | |
User <$> v .: "name" | |
<*> v .: "client_id" | |
parseJSON _ = mzero |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment