| Stability | experimental |
|---|---|
| Maintainer | Alp Mestanogullari <alp@zalora.com> |
| Safe Haskell | None |
Servant.Scotty.Arguments
Description
Functions and typeclasses for automatically fetching the arguments of the "database operations" from either the request path or from the request body, by decoding it from JSON to your type.
Deducing an argument from the request path
What it means for a scotty Resource
to have an index type.
-
idxshould lookup in the request path whatever is necessary to get theiofResource c a i r e ops, for operations that take it as an argument, e.g Delete, Update or View. -
routeshould return aStringthat'll be passed tocapture. You may use one or more "path parameters" (calls toparam, instances ofParam) to compute your value of typek. You probably want to usenameon theResourceto generate the beginning of the path.
Deducing an argument from the JSON body
js :: (MonadIO m, ScottyError e, FromJSON a) => ActionT e m aSource
Simply gets the request's body as JSON (or raises an exception if the decoding fails)
class FromJSON a
A type that can be converted from JSON, with the possibility of failure.
When writing an instance, use empty, mzero, or fail to make a
conversion fail, e.g. if an Object is missing a required key, or
the value is of the wrong type.
An example type and instance:
{-# LANGUAGE OverloadedStrings #-}
data Coord = Coord { x :: Double, y :: Double }
instance FromJSON Coord where
parseJSON (Object v) = Coord <$>
v .: "x" <*>
v .: "y"
-- A non-Object value is of the wrong type, so use mzero to fail.
parseJSON _ = mzero
Note the use of the OverloadedStrings language extension which enables
Text values to be written as string literals.
Instead of manually writing your FromJSON instance, there are three options
to do it automatically:
- Data.Aeson.TH provides template-haskell functions which will derive an instance at compile-time. The generated instance is optimized for your type so will probably be more efficient than the following two options:
- Data.Aeson.Generic provides a generic
fromJSONfunction that parses to any type which is an instance ofData. - If your compiler has support for the
DeriveGenericandDefaultSignatureslanguage extensions,parseJSONwill have a default generic implementation.
To use this, simply add a deriving clause to your datatype and
declare a GenericFromJSON instance for your datatype without giving a definition
for parseJSON.
For example the previous example can be simplified to just:
{-# LANGUAGE DeriveGeneric #-}
import GHC.Generics
data Coord = Coord { x :: Double, y :: Double } deriving Generic
instance FromJSON Coord
Note that, instead of using DefaultSignatures, it's also possible
to parameterize the generic decoding using genericParseJSON applied
to your encoding/decoding Options:
instance FromJSON Coord where
parseJSON = genericParseJSON defaultOptions
Instances