packages feed

rest-core 0.28.0.1 → 0.29

raw patch · 5 files changed

+62/−30 lines, 5 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

- Rest.Driver.Routing: Router :: ReaderT Method (StateT UriParts (EitherT Reason_ Identity)) a -> Router a
- Rest.Driver.Routing: apiError :: MonadError (Reason e) m => Reason e -> m a
- Rest.Driver.Routing: fromMaybeT :: Monad m => m a -> MaybeT m a -> m a
- Rest.Driver.Routing: guardMethod :: (MonadPlus m, MonadReader Method m) => Method -> m ()
- Rest.Driver.Routing: guardNullPath :: (MonadPlus m, MonadState UriParts m) => m ()
- Rest.Driver.Routing: hasMethod :: Method -> Router ()
- Rest.Driver.Routing: lookupRouter :: String -> [Some1 (Router s)] -> Maybe (Some1 (Router s))
- Rest.Driver.Routing: mkListAction :: Monad m => (Env h p i -> ErrorT (Reason e) m [a]) -> Env h (Range, p) i -> ErrorT (Reason e) m (List a)
- Rest.Driver.Routing: mkMultiGetHandler :: (Applicative m, Monad m) => Router m s -> Handler m
- Rest.Driver.Routing: mkMultiPutHandler :: Monad m => Id id -> (id -> Run s m) -> Handler s -> Maybe (Handler m)
- Rest.Driver.Routing: multiPut :: Resource m s sid mid aid -> Id sid -> Router (RunnableHandler m)
- Rest.Driver.Routing: newtype Router a
- Rest.Driver.Routing: noRestPath :: Router ()
- Rest.Driver.Routing: parseIdent :: MonadError (Reason e) m => Id id -> String -> m id
- Rest.Driver.Routing: popSegment :: Router String
- Rest.Driver.Routing: routeCreate :: Resource m s sid mid aid -> MaybeT Router (RunnableHandler m)
- Rest.Driver.Routing: routeGetter :: Getter sid -> Resource m s sid mid aid -> [Some1 (Router s)] -> Router (RunnableHandler m)
- Rest.Driver.Routing: routeListGetter :: Monad m => Getter mid -> (mid -> ListHandler m) -> Router (RunnableHandler m)
- Rest.Driver.Routing: routeListHandler :: Monad m => ListHandler m -> Router (RunnableHandler m)
- Rest.Driver.Routing: routeMultiGet :: Router m s -> MaybeT Router (RunnableHandler m)
- Rest.Driver.Routing: routeName :: String -> Router ()
- Rest.Driver.Routing: routeNamed :: Resource m s sid mid aid -> [Some1 (Router s)] -> Endpoint sid mid aid -> Router (RunnableHandler m)
- Rest.Driver.Routing: routeRoot :: Router m s -> Router (RunnableHandler m)
- Rest.Driver.Routing: routeRouter :: Router m s -> Router (RunnableHandler m)
- Rest.Driver.Routing: routeSingle :: sid -> Resource m s sid mid aid -> Router (RunnableHandler m)
- Rest.Driver.Routing: routeStep :: Resource m s sid mid aid -> [Some1 (Router s)] -> Step sid mid aid -> Router (RunnableHandler m)
- Rest.Driver.Routing: routeToplevel :: Resource m s sid mid aid -> [Some1 (Router s)] -> Maybe (Cardinality sid mid) -> MaybeT Router (RunnableHandler m)
- Rest.Driver.Routing: routeUnnamed :: Resource m s sid mid aid -> [Some1 (Router s)] -> Cardinality (Id sid) (Id mid) -> Router (RunnableHandler m)
- Rest.Driver.Routing: runResource :: (Applicative m, Monad m) => Router m s -> Resource -> m BodyPart
- Rest.Driver.Routing: runRouter :: Method -> UriParts -> Router (RunnableHandler m) -> Either Reason_ (RunnableHandler m)
- Rest.Driver.Routing: splitUri :: Uri -> UriParts
- Rest.Driver.Routing: splitUriString :: String -> UriParts
- Rest.Driver.Routing: type Uri = ByteString
- Rest.Driver.Routing: unRouter :: Router a -> ReaderT Method (StateT UriParts (EitherT Reason_ Identity)) a
- Rest.Driver.Routing: withSegment :: Router a -> (String -> Router a) -> Router a
- Rest.Driver.Routing: withSubresource :: sid -> Resource m s sid mid aid -> [Some1 (Router s)] -> Router (RunnableHandler m)
+ Rest.Dictionary.Types: instance Show (Dict h0 p0 i0 o0 e0)
+ Rest.Dictionary.Types: instance Show (Header h)
+ Rest.Dictionary.Types: instance Show (Param p)
+ Rest.Driver.Routing: mkMultiHandler :: Monad m => Id id -> (id -> Run s m) -> Handler s -> Maybe (Handler m)
- Rest.Dictionary.Types: data Dict h_a7xp p_a7xq i_a7xr o_a7xs e_a7xt
+ Rest.Dictionary.Types: data Dict h_a7yA p_a7yB i_a7yC o_a7yD e_a7yE

Files

+ CHANGELOG.md view
@@ -0,0 +1,13 @@+# Changelog++## 0.29++* Add multi-delete handler. It is used on a DELETE to+  `/<resource>/<id>/` and is derived from the single delete handler.+* Don't put `Cache-Control: private` header on served files. This way+  they can be cached by public proxies, e.g. cloudfront.+* Add `Show` instances for `Header`, `Param` and `Dict`.+* Renamed `mkMultiPutHandler` to `mkMultiHandler` in+  `Rest.Driver.Routing`.+* Explicit exports in `Rest.Driver.Routing`, removing a lot of+  private functions from the public interface.
rest-core.cabal view
@@ -1,13 +1,14 @@-Name:             rest-core-Version:          0.28.0.1-Description:      Rest API library.-Synopsis:         Rest API library.-Maintainer:       code@silk.co-Category:         Web-Build-Type:       Simple-Cabal-Version:    >= 1.8-License:          BSD3-License-File:     LICENSE+Name:               rest-core+Version:            0.29+Description:        Rest API library.+Synopsis:           Rest API library.+Maintainer:         code@silk.co+Category:           Web+Build-Type:         Simple+Cabal-Version:      >= 1.8+License:            BSD3+License-File:       LICENSE+Extra-Source-Files: CHANGELOG.md  Library   GHC-Options:     -Wall
src/Rest/Dictionary/Types.hs view
@@ -94,6 +94,10 @@   NoHeader ::                                                       Header ()   Header   :: [String] -> ([Maybe String] -> Either DataError h) -> Header h +instance Show (Header h) where+  showsPrec _ NoHeader      = showString "NoHeader"+  showsPrec n (Header hs _) = showParen (n > 9) (showString "Header " . showsPrec 10 hs)+ -- | The explicit dictionary `Parameter` describes how to translate the request -- parameters to some Haskell value. The first field in the `Header` -- constructor is a white list of paramters we can recognize, used in generic@@ -110,6 +114,15 @@   Param     :: [String] -> ([Maybe String] -> Either DataError p) -> Param p   TwoParams :: Param p -> Param q                                 -> Param (p, q) +instance Show (Param p) where+  showsPrec _ NoParam         = showString "NoParam"+  showsPrec n (Param ns _)    = showParen (n > 9) (showString "Param " . showsPrec 10 ns)+  showsPrec n (TwoParams p q) = showParen (n > 9) ( showString "TwoParams "+                                                  . showsPrec 10 p+                                                  . showString " "+                                                  . showsPrec 10 q+                                                  )+ -- | The explicitly dictionary `Input` describes how to translate the request -- body into some Haskell value. We currently use a constructor for every -- combination of input type to output type. For example, we can use XML input@@ -187,7 +200,7 @@     , inputs  :: Inputs  i     , outputs :: Outputs o     , errors  :: Errors  e-    }+    } deriving Show   |]  -- | The empty dictionary, recognizing no types.
src/Rest/Driver/Perform.hs view
@@ -332,7 +332,7 @@         tryD (MultipartO : _ ) _            = outputMultipart v         tryD (FileO      : _ ) FileFormat   = do mime <- fromMaybe "application/octet-stream" <$> lookupMimeType (map toLower (snd v))                                                  setHeader "Content-Type" mime-                                                 setHeader "Cache-Control" "private, max-age=604800"+                                                 setHeader "Cache-Control" "max-age=604800"                                                  ok (fst v)         tryD []                t            = throwError (UnsupportedFormat (show t))         tryD (_          : xs) t            = tryD xs t
src/Rest/Driver/Routing.hs view
@@ -9,8 +9,14 @@            , DeriveDataTypeable            , TupleSections            #-}-module Rest.Driver.Routing where+module Rest.Driver.Routing+  ( route+  , mkListHandler+  , mkMultiHandler +  , UriParts+  ) where+ import Prelude hiding (id, (.))  import Control.Applicative@@ -24,11 +30,9 @@ import Control.Monad.State (StateT, evalStateT, MonadState) import Control.Monad.Trans.Either import Control.Monad.Trans.Maybe-import Data.ByteString (ByteString) import Network.Multipart (BodyPart (..), HeaderName (..)) import Safe import qualified Control.Monad.State       as State-import qualified Data.ByteString.UTF8      as UTF8 import qualified Data.ByteString.Lazy.UTF8 as LUTF8 import qualified Data.Label.Total          as L import qualified Data.Map                  as Map@@ -51,7 +55,6 @@  import qualified Rest.Driver.RestM as Rest -type Uri = ByteString type UriParts = [String]  apiError :: (MonadError (Reason e) m) => Reason e -> m a@@ -146,7 +149,7 @@              -> Router (RunnableHandler m) routeUnnamed resource@(Rest.Resource { Rest.list }) subRouters cardinality =   case cardinality of-    Rest.Single sBy -> withSegment (multiPut resource sBy) $ \seg ->+    Rest.Single sBy -> withSegment (multi resource sBy) $ \seg ->       parseIdent sBy seg >>= \sid -> withSubresource sid resource subRouters     Rest.Many   mBy ->       do seg <- popSegment@@ -162,18 +165,23 @@ routeGetter getter resource subRouters =   case getter of     Rest.Singleton sid -> getOrDeep sid-    Rest.By        sBy -> withSegment (multiPut resource sBy) $ \seg ->+    Rest.By        sBy -> withSegment (multi resource sBy) $ \seg ->                             parseIdent sBy seg >>= getOrDeep   where     getOrDeep sid = withSubresource sid resource subRouters -multiPut :: Rest.Resource m s sid mid aid -> Rest.Id sid -> Router (RunnableHandler m)-multiPut (Rest.Resource { Rest.update, Rest.enter }) sBy =-  do hasMethod PUT-     maybe (apiError UnsupportedRoute) return $-       do updateH    <- update-          putHandler <- mkMultiPutHandler sBy enter updateH-          return (RunnableHandler id putHandler)+multi :: Rest.Resource m s sid mid aid -> Rest.Id sid -> Router (RunnableHandler m)+multi (Rest.Resource { Rest.update, Rest.remove, Rest.enter }) sBy =+  ask >>= \method ->+  case method of+    PUT    -> handleOrNotFound update+    DELETE -> handleOrNotFound remove+    _      -> apiError UnsupportedMethod+  where+    handleOrNotFound handler =+      maybe (apiError UnsupportedRoute)+            (return . RunnableHandler id)+            (handler >>= mkMultiHandler sBy enter)  routeListGetter :: Monad m                 => Rest.Getter mid@@ -241,9 +249,6 @@     Nothing  -> throwError (IdentError (ParseError $ "Failed to parse " ++ seg))     Just sid -> return (byF sid) -splitUri :: Uri -> UriParts-splitUri = splitUriString . UTF8.toString- splitUriString :: String -> UriParts splitUriString = filter (/= "") . map decode . splitOn "/" @@ -296,8 +301,8 @@   xs <- act (Env h p i)   return (List f (min c (length xs)) (take c xs)) -mkMultiPutHandler :: Monad m => Rest.Id id -> (id -> Run s m) -> Handler s -> Maybe (Handler m)-mkMultiPutHandler sBy run (GenHandler dict act sec) = GenHandler <$> mNewDict <*> pure newAct <*> pure sec+mkMultiHandler :: Monad m => Rest.Id id -> (id -> Run s m) -> Handler s -> Maybe (Handler m)+mkMultiHandler sBy run (GenHandler dict act sec) = GenHandler <$> mNewDict <*> pure newAct <*> pure sec   where     newErrDict = L.modify errors reasonE dict     mNewDict =  L.traverse inputs mappingI