Last active
January 17, 2020 13:07
-
-
Save Decoherence/70ad2317ab7e1c2e7f30 to your computer and use it in GitHub Desktop.
Haskell: Bookstore REST API with PostgreSQL backend using Servant
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 DataKinds #-} | |
{-# LANGUAGE DeriveGeneric #-} | |
{-# LANGUAGE OverloadedStrings #-} | |
{-# LANGUAGE PolyKinds #-} | |
{-# LANGUAGE TypeFamilies #-} | |
{-# LANGUAGE TypeOperators #-} | |
import Control.Applicative | |
import Control.Monad.IO.Class | |
import Data.Aeson | |
import Data.Proxy | |
import Data.Text (Text) | |
import Database.PostgreSQL.Simple | |
import Database.PostgreSQL.Simple.FromRow | |
import Database.PostgreSQL.Simple.ToField | |
import Database.PostgreSQL.Simple.ToRow | |
import GHC.Generics | |
import Network.Wai.Handler.Warp hiding (Connection) | |
import Servant | |
data Book = Book | |
{ title :: Text | |
, author :: Text | |
} deriving Generic | |
-- JSON instances | |
instance FromJSON Book | |
instance ToJSON Book | |
-- PostgreSQL instances | |
instance FromRow Book where | |
fromRow = Book <$> field <*> field | |
instance ToRow Book where | |
toRow book = [ toField (title book) | |
, toField (author book)] | |
-- we explicitly say we expect a request body, of type Book | |
type BookApi = "books" :> ReqBody Book :> Post Book -- POST /books | |
:<|> "books" :> Get [Book] -- GET /books | |
server :: Connection -> Server BookApi | |
server conn = postBook | |
:<|> getBooks | |
where | |
-- the aforementioned 'ReqBody' automatically makes this handler | |
-- receive a Book argument | |
postBook book = liftIO $ execute conn "insert into books values (?, ?)" book >> return book | |
getBooks = liftIO $ query_ conn "select * from books" | |
bookApi :: Proxy BookApi | |
bookApi = Proxy | |
main :: IO () | |
main = do | |
conn <- connectPostgreSQL "host=localhost user=qubit dbname=bookstore" | |
run 8080 (serve bookApi $ server conn) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment