Chapter 24. JSON Web Service
Let’s create a very simple web service: it takes a JSON request and returns a
JSON response. We’re going to write the server in WAI/Warp and the client in
http-conduit
. We’ll be using aeson
for JSON parsing and rendering. We could
also write the server in Yesod itself, but for such a simple example, the extra
features of Yesod don’t add much.
Server
WAI uses the conduit
package to handle streaming request bodies and
efficiently generates responses using blaze-builder
. aeson
uses attoparsec
for
parsing; by using attoparsec-conduit
we get easy interoperability with WAI.
This plays out as:
{-# LANGUAGE OverloadedStrings #-}
import
Control.Exception
(
SomeException
)
import
Control.Exception.Lifted
(
handle
)
import
Control.Monad.IO.Class
(
liftIO
)
import
Data.Aeson
(
Value
,
encode
,
object
,
(
.=
))
import
Data.Aeson.Parser
(
json
)
import
Data.ByteString
(
ByteString
)
import
Data.Conduit
((
$$
))
import
Data.Conduit.Attoparsec
(
sinkParser
)
import
Network.HTTP.Types
(
status200
,
status400
)
import
Network.Wai
(
Application
,
Response
,
responseLBS
)
import
Network.Wai.Conduit
(
sourceRequestBody
)
import
Network.Wai.Handler.Warp
(
run
)
main
::
IO
()
main
=
run
3000
app
app
::
Application
app
req
sendResponse
=
handle
(
sendResponse
.
invalidJson
)
$
do
value
<-
sourceRequestBody
req
$$
sinkParser
json
newValue
<-
liftIO
$
modValue
value
sendResponse
$
responseLBS
status200
[(
"Content-Type"
,
"application/json"
)]
$
encode
newValue
invalidJson
::
SomeException
->
Response
invalidJson ...
Get Developing Web Apps with Haskell and Yesod, 2nd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.