{-# LANGUAGE TypeOperators, ConstraintKinds, MultiParamTypeClasses, TypeFamilies, TypeSynonymInstances, DataKinds, FlexibleContexts, FlexibleInstances, ScopedTypeVariables #-} {- | Module : Servant.Prelude Copyright : (c) Zalora SEA 2014 License : BSD3 Maintainer : Alp Mestanogullari Stability : experimental Some standard REST-y operations your 'Resource's can support out of the box. Your type will have to implement a couple of class instances to be usable with a backend. For the scotty backend, this means having 'FromJSON' or 'ToJSON' instances and the appropriate 'toResponse' implementations for the return types of your database. -} module Servant.Prelude ( -- * Defining 'Resource's module Servant.Resource , module Servant.Context , module Servant.Error , -- * Standard operations Add , addWith , Delete , deleteWith , ListAll , listAllWith , Update , updateWith , View , viewWith ) where import Servant.Context import Servant.Error import Servant.Resource -- | A dummy type representing an operation that adds an entry. data Add instance Show Add where show _ = "Add" -- | A dummy type representing an operation that deletes an entry. data Delete instance Show Delete where show _ = "Delete" -- | A dummy type representing an operation that lists all entries. data ListAll instance Show ListAll where show _ = "ListAll" -- | A dummy type representing an operation that updates an entry. data Update instance Show Update where show _ = "Update" -- | A dummy type representing an operation that looks up an entry. data View instance Show View where show _ = "View" -- | To 'Add' an entry, we require a function of type @c -> a -> IO r@. type instance Operation Add c a i r = a -> c -> IO (r Add) -- | To 'Delete' an entry, we require a function of type @c -> i -> IO r@. type instance Operation Delete c a i r = i -> c -> IO (r Delete) -- | To 'List' all entries, we require a function of type @c -> IO [a]@. type instance Operation ListAll c a i r = c -> IO [a] -- | To 'Update' an entry, we require a function of type @c -> i -> a -> IO r@. type instance Operation Update c a i r = i -> a -> c -> IO (r Update) -- | To 'View' an entry, we require a function of type @c -> i -> IO (Maybe a)@. type instance Operation View c a i r = i -> c -> IO (Maybe a) -- | Make a 'Resource' support the 'Add' -- operation by using your function. -- -- Given: -- -- > addPerson :: PGSQL.Connection -> Person -> IO Bool -- -- you could do: -- -- > mkResource "persons" postgresContext noErrorHandling -- > & addWith addPerson addWith :: Contains Add ops ~ False => (a -> c -> IO (r Add)) -> Resource c a i r e ops -> Resource c a i r e (Add ': ops) addWith = addOperation -- | Make a 'Resource' support the 'Delete' -- operation by using your function. -- -- Given: -- -- > deletePerson :: PGSQL.Connection -> PersonId -> IO Bool -- -- you could do: -- -- > mkResource "persons" postgresContext noErrorHandling -- > & deleteWith addPerson deleteWith :: Contains Delete ops ~ False => (i -> c -> IO (r Delete)) -> Resource c a i r e ops -> Resource c a i r e (Delete ': ops) deleteWith = addOperation -- | Make a 'Resource' support the 'ListAll' -- operation by using your function. -- -- Given: -- -- > listAllPersons :: PGSQL.Connection -> IO [Person] -- -- you could do: -- -- > mkResource "persons" postgresContext noErrorHandling -- > & listAllWith listAllPersons listAllWith :: Contains ListAll ops ~ False => (c -> IO [a]) -> Resource c a i r e ops -> Resource c a i r e (ListAll ': ops) listAllWith = addOperation -- | Make a 'Resource' support the 'Update' -- operation by using your function. -- -- Given: -- -- > updatePerson :: PGSQL.Connection -> PersonId -> Person -> IO Bool -- -- you could do: -- -- > mkResource "persons" postgresContext noErrorHandling -- > & updateWith updatePerson updateWith :: Contains Update ops ~ False => (i -> a -> c -> IO (r Update)) -> Resource c a i r e ops -> Resource c a i r e (Update ': ops) updateWith = addOperation -- | Make a 'Resource' support the 'View' -- operation by using your function. -- -- Given: -- -- > viewPerson :: PGSQL.Connection -> PersonId -> IO (Maybe Person) -- -- you could do: -- -- > mkResource "persons" postgresContext noErrorHandling -- > & viewWith viewPerson viewWith :: Contains View ops ~ False => (i -> c -> IO (Maybe a)) -> Resource c a i r e ops -> Resource c a i r e (View ': ops) viewWith = addOperation