7

I want to produce the decoded result for POST data. Much code is 'wasted' in converting 'string'. That makes code ugly. Any better solutions?

import           Codec.Binary.Url (decode')
import qualified Data.ByteString.Lazy.Char8 as L (unpack)
import qualified Data.ByteString.Char8 as S (unpack, pack)
import qualified Data.ByteString.Lazy as LBS (pack)

decodeUrlHandler :: Snap()
decodeUrlHandler = do
    body <- readRequestBody (maxBound :: Int64)
    writeLBS $ LBS.pack $ map (fromMaybe 0) $ decode' $ L.unpack body

What would your code for this purpose be?

mightybyte
  • 7,282
  • 3
  • 23
  • 39
wenlong
  • 1,434
  • 1
  • 13
  • 22
  • 1
    Maybe add my own function `fromMaybeW8sToLBS = LBS.pack . map (fromMaybe 0)` – wenlong Nov 18 '11 at 14:46
  • Why do you need to decode the request body yourself? Are you sure that Snap doesn't do that for you? – nponeccop Nov 18 '11 at 15:35
  • @nponeccop, request body has type ByteString, I want regard it as url encoded string and decode it. But decode' (url decode) want String and returns [Maybe Word8]. – wenlong Nov 18 '11 at 16:11

1 Answers1

9

Snap automatically decodes the request and makes it available to you through the Request data type. It provides functions getRequest and withRequest for retrieving the request and a number of other accessor functions for getting various parts.

There are also convenience functions for common operations. To get a POST or GET parameter see getParam.

Snap gives it to you as a ByteString because this API sits at a fairly low level of abstraction, leaving it up to the user how to handle things like text encoding. I would recommend that you use the much more efficient Text type instead of String. The Readable type class also provides a mechanism for eliminating some of the boilerplate of these conversions. The default instances for numbers and Text assume UTF8 encoding.

mightybyte
  • 7,282
  • 3
  • 23
  • 39
  • I second the suggestion to use Data.Text along with {-# LANGUAGE OverloadedStrings #-} if you aren't already. You might also find that you have to 'import Data.String (IsString)' for some conversions, but Snap makes this pretty straightforward. – clintm Nov 18 '11 at 19:12
  • If I use Text type, I need an extra convertion to apply some functions that accept String type, Codec.Binary.Url.decode' in this case. – wenlong Nov 19 '11 at 00:17
  • 1
    The fromBS function provided by the Readable type class does this as well. – mightybyte Nov 20 '11 at 23:23