Introduce JSONResponse.

This data type allows us to return a domain type in our handlers, even
if we eventually want to send JSON to the client.

See: https://tech.freckle.com/2015/12/21/servant-style-handlers-for-yesod/
This commit is contained in:
Steven Leiva 2019-04-12 16:13:53 -05:00
parent 6a7370a9e6
commit ab096c649c
3 changed files with 26 additions and 0 deletions

View File

@ -1,5 +1,9 @@
# ChangeLog for yesod-core # ChangeLog for yesod-core
## 1.6.14
* Introduce `JSONResponse`. [issue #1481](https://github.com/yesodweb/yesod/issues/1481) and [PR #1592](https://github.com/yesodweb/yesod/pull/1592)
## 1.6.13 ## 1.6.13
* Introduce `maxContentLengthIO`. [issue #1588](https://github.com/yesodweb/yesod/issues/1588) and [PR #1589](https://github.com/yesodweb/yesod/pull/1589) * Introduce `maxContentLengthIO`. [issue #1588](https://github.com/yesodweb/yesod/issues/1588) and [PR #1589](https://github.com/yesodweb/yesod/pull/1589)

View File

@ -107,6 +107,8 @@ instance ToContent (ContentType, Content) where
toContent = snd toContent = snd
instance ToContent TypedContent where instance ToContent TypedContent where
toContent (TypedContent _ c) = c toContent (TypedContent _ c) = c
instance ToContent (JSONResponse a) where
toContent (JSONResponse a) = toContent $ J.toEncoding a
instance ToContent Css where instance ToContent Css where
toContent = toContent . renderCss toContent = toContent . renderCss
@ -160,6 +162,8 @@ deriving instance ToContent RepJson
instance HasContentType RepPlain where instance HasContentType RepPlain where
getContentType _ = typePlain getContentType _ = typePlain
deriving instance ToContent RepPlain deriving instance ToContent RepPlain
instance HasContentType (JSONResponse a) where
getContentType _ = typeJson
instance HasContentType RepXml where instance HasContentType RepXml where
getContentType _ = typeXml getContentType _ = typeXml
@ -292,6 +296,8 @@ instance ToTypedContent [Char] where
toTypedContent = toTypedContent . pack toTypedContent = toTypedContent . pack
instance ToTypedContent Text where instance ToTypedContent Text where
toTypedContent t = TypedContent typePlain (toContent t) toTypedContent t = TypedContent typePlain (toContent t)
instance ToTypedContent (JSONResponse a) where
toTypedContent c = TypedContent typeJson (toContent c)
instance ToTypedContent a => ToTypedContent (DontFullyEvaluate a) where instance ToTypedContent a => ToTypedContent (DontFullyEvaluate a) where
toTypedContent (DontFullyEvaluate a) = toTypedContent (DontFullyEvaluate a) =
let TypedContent ct c = toTypedContent a let TypedContent ct c = toTypedContent a

View File

@ -8,8 +8,10 @@
{-# LANGUAGE MultiParamTypeClasses #-} {-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE TypeFamilies #-} {-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE UndecidableInstances #-} {-# LANGUAGE UndecidableInstances #-}
{-# LANGUAGE GADTs #-}
module Yesod.Core.Types where module Yesod.Core.Types where
import Data.Aeson (ToJSON)
import qualified Data.ByteString.Builder as BB import qualified Data.ByteString.Builder as BB
import Control.Arrow (first) import Control.Arrow (first)
import Control.Exception (Exception) import Control.Exception (Exception)
@ -303,6 +305,20 @@ newtype RepXml = RepXml Content
type ContentType = ByteString -- FIXME Text? type ContentType = ByteString -- FIXME Text?
-- | Wrapper around types so that Handlers can return a domain type, even when
-- the data will eventually be encoded as JSON.
-- Example usage in a type signature:
--
-- > postSignupR :: Handler (JSONResponse CreateUserResponse)
--
-- And in the implementation:
--
-- > return $ JSONResponse $ CreateUserResponse userId
--
-- @since 1.6.14
data JSONResponse a where
JSONResponse :: ToJSON a => a -> JSONResponse a
-- | Prevents a response body from being fully evaluated before sending the -- | Prevents a response body from being fully evaluated before sending the
-- request. -- request.
-- --