Chapter 20. 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
Network.Wai
(
Response
,
responseLBS
,
Application
,
requestBody
)
import
Network.HTTP.Types
(
status200
,
status400
)
import
Network.Wai.Handler.Warp
(
run
)
import
Data.Aeson.Parser
(
json
)
import
Data.Conduit.Attoparsec
(
sinkParser
)
import
Control.Monad.IO.Class
(
liftIO
)
import
Data.Aeson
(
Value
,
encode
,
object
,
(
.=
))
import
Control.Exception
(
SomeException
)
import
Data.ByteString
(
ByteString
)
import
Data.Conduit
(
ResourceT
,
(
$$
))
import
Control.Exception.Lifted
(
handle
)
main
::
IO
()
main
=
run
3000
app
app
::
Application
app
req
=
handle
invalidJson
$
do
value
<-
requestBody
req
$$
sinkParser
json
newValue
<-
liftIO
$
modValue
value
return
$
responseLBS
status200
[(
"Content-Type"
,
"application/json"
)]
$
encode
newValue
invalidJson
::
SomeException
->
ResourceT
IO
Response
invalidJson
ex
=
return
$
responseLBS
status400
[(
"Content-Type" ...
Get Developing Web Applications with Haskell and Yesod 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.