rest-core 0.38 → 0.39
raw patch · 5 files changed
+42/−18 lines, 5 filesdep ~HUnitdep ~aesondep ~base
Dependency ranges changed: HUnit, aeson, base, errors
Files
- CHANGELOG.md +7/−0
- rest-core.cabal +4/−4
- src/Rest/Api.hs +23/−9
- src/Rest/Driver/Routing/Internal.hs +6/−3
- tests/Runner.hs +2/−2
CHANGELOG.md view
@@ -1,5 +1,12 @@ # Changelog +## 0.39++* Add support for versionless APIs, thanks to Tenor Biel. This is a+ breaking change. Old API users will have to add `Versioned` before+ their list of api versions, so it becomes `Versioned [ (mkVersion+ ...) ]`.+ ## 0.38 * Add `RawJsonO`, `RawJsonI`, `RawJsonAndXmlI`, and `RawJsonAndXmlO`.
rest-core.cabal view
@@ -1,5 +1,5 @@ name: rest-core-version: 0.38+version: 0.39 description: Rest API library. synopsis: Rest API library. maintainer: code@silk.co@@ -40,8 +40,8 @@ Rest.Schema Rest.ShowUrl build-depends:- base >= 4.5 && < 4.9- , aeson >= 0.7 && < 0.11+ base >= 4.5 && < 4.10+ , aeson >= 0.7 && < 0.12 , aeson-utils >= 0.2 && < 0.4 , base-compat >= 0.8 && < 0.10 , bytestring >= 0.9 && < 0.11@@ -73,7 +73,7 @@ main-is: Runner.hs type: exitcode-stdio-1.0 build-depends:- base >= 4.5 && < 4.9+ base >= 4.5 && < 4.10 , HUnit >= 1.2 && < 1.4 , bytestring >= 0.9 && < 0.11 , mtl >= 2.0 && < 2.3
src/Rest/Api.hs view
@@ -8,7 +8,8 @@ -- to generate clients or documentation using 'rest-gen'. module Rest.Api ( -- * Api data types.- Api+ Api (..)+ , VersionSet , Router (..) , Some1 (..) @@ -113,13 +114,21 @@ instance Show Version where show v = show (full v) ++ "." ++ show (major v) ++ maybe "" (\x -> "." ++ show x) (minor v) --- | An API is a list of versioned routers.+-- | A version set is a list of versioned routers. -type Api m = [(Version, Some1 (Router m))]+type VersionSet m = [(Version, Some1 (Router m))] +-- | An API can be versioned or unversioned.+-- A versioned API is a set of versioned routers.+-- An unversioned API is just a single router.++data Api m where+ Unversioned :: Some1 (Router m) -> Api m+ Versioned :: VersionSet m -> Api m+ -- | Get the latest version of an API. -latest :: Api m -> Maybe (Version, Some1 (Router m))+latest :: VersionSet m -> Maybe (Version, Some1 (Router m)) latest = headMay . reverse . sortBy (compare `on` fst) -- | Parse a 'String' as a 'Version'. The string should contain two or@@ -135,13 +144,13 @@ -- | Look up a version in an API. The string can either be a valid -- version according to 'parseVersion', or "latest". -lookupVersion :: String -> Api m -> Maybe (Some1 (Router m))+lookupVersion :: String -> VersionSet m -> Maybe (Some1 (Router m)) lookupVersion "latest" = fmap snd . latest lookupVersion str = (parseVersion str >>=) . flip lookupVersion' -- | Look up a version in the API. -lookupVersion' :: Version -> Api m -> Maybe (Some1 (Router m))+lookupVersion' :: Version -> VersionSet m -> Maybe (Some1 (Router m)) lookupVersion' v versions = best (filter (matches v . fst) versions) where best = fmap snd . headMay . sortBy (flip (comparing fst)) matches :: Version -> Version -> Bool@@ -160,10 +169,15 @@ -- * If not parsed or found, return the fallback. withVersion :: String -> Api m -> r -> (Version -> Some1 (Router m) -> r) -> r-withVersion ver api err ok =+withVersion ver (Versioned vrs) err ok = maybe err (uncurry ok) $ case ver of- "latest" -> latest api+ "latest" -> latest vrs _ -> do pv <- parseVersion ver- r <- lookupVersion' pv api+ r <- lookupVersion' pv vrs return (pv, r)+withVersion ver (Unversioned r) err ok =+ maybe err (uncurry ok) $+ case ver of+ "latest" -> return (mkVersion 1 0 0, r)+ _ -> Nothing
src/Rest/Driver/Routing/Internal.hs view
@@ -80,9 +80,12 @@ routeWith :: Config m -> Maybe Method -> UriParts -> Rest.Api m -> Either Reason_ (RunnableHandler m) routeWith _ Nothing _ _ = apiError UnsupportedMethod-routeWith cfg (Just mtd) uri api = runRouter cfg mtd uri $- do versionStr <- popSegment- case versionStr `Rest.lookupVersion` api of+routeWith cfg (Just mtd) uri api = runRouter cfg mtd uri $ do+ case api of+ Rest.Unversioned (Some1 router) -> routeRoot router+ Rest.Versioned vrs -> do+ versionStr <- popSegment+ case versionStr `Rest.lookupVersion` vrs of Just (Some1 router) -> routeRoot router _ -> apiError UnsupportedVersion
tests/Runner.hs view
@@ -191,13 +191,13 @@ checkRouteFailure :: (Applicative m, Monad m) => Method -> Uri -> Rest.Router m s -> Assertion checkRouteFailure method uri router =- case route (Just method) (splitUriString $ "v1.0/" <> uri) [(Version 1 0 Nothing, Some1 router)] of+ case route (Just method) (splitUriString $ "v1.0/" <> uri) (Versioned [(Version 1 0 Nothing, Some1 router)]) of Left _ -> return () Right _ -> assertFailure ("Should be no route to " ++ show method ++ " " ++ uri ++ ".") checkRouteSuccess :: (Applicative m, Monad m) => Method -> Uri -> Rest.Router m s -> Assertion checkRouteSuccess method uri router =- case route (Just method) (splitUriString $ "v1.0/" <> uri) [(Version 1 0 Nothing, Some1 router)] of+ case route (Just method) (splitUriString $ "v1.0/" <> uri) (Versioned [(Version 1 0 Nothing, Some1 router)]) of Left e -> assertFailure ("No route to " ++ show method ++ " " ++ uri ++ ": " ++ show e) Right _ -> return ()