jordan-servant-0.1.0.0: Servant Combinators for Jordan
Safe HaskellNone
LanguageHaskell2010

Jordan.Servant.Query

Synopsis

Servant Combinators

data JordanQuery' (baseStr :: Symbol) (options :: [*]) (a :: *) Source #

A query argument at some key, that will be parsed via Jordan. If the query needs to contain nested data, it will all be nested under the same key.

We do not support lenient queries as figuring out what to return in the case where the Jordan parser would have parsed nested keys is too difficult.

Note: this type *does not* have a HasLink instance, because unfortunately Servant is way too restrictive of what it exports, making such an instance impossible to write. I will open up a PR against Servant to fix this soon.

type OptionalJordanQuery (baseStr :: Symbol) (a :: *) = JordanQuery' (baseStr :: Symbol) '[] (a :: *) Source #

A query argument that is *optional*.

Will render an error message, in JSON format, if the query was bad in some way.

type RequiredJordanQuery (baseStr :: Symbol) (a :: *) = JordanQuery' baseStr '[Required] a Source #

A query argument that is required.

Will render an error message, in JSON format, if the query was bad in some way.

Using Jordan with query strings

This module provides a way to use Jordan to parse to or render from query strings.

An example is helpful:

>>> renderQueryAtKey "person" (Person { firstName = "Rich", lastName = "Evans" })
[("person[firstName]",Just "Rich"),("person[lastName]",Just "Evans")]
>>> renderQuery True $ renderQueryAtKey "person" (Person { firstName = "Rich", lastName = "Evans" })
"?person%5BfirstName%5D=Rich&person%5BlastName%5D=Evans"
>>> parseQueryAtKey @Person "person" $ renderQueryAtKey "person" (Person { firstName = "Mike", lastName = "Stoklassa" })
Right (Person {firstName = "Mike", lastName = "Stoklassa"})

The format of parsed and rendered queries is designed to be "similar enough" to how Rails does it, which is also used in several other libraries.

Parsing Queries

parseQueryAtKey :: FromJSON a => Text -> Query -> Either String a Source #

Like parseQueryAtKeyWith, but uses the FromJSON instance, which is what you want 90% of the time.

parseQueryAtKeyWith Source #

Arguments

:: (forall jsonParser. JSONParser jsonParser => jsonParser a)

JSON parser to use. Note the rank-N type.

-> Text

Base key to use in the query string.

-> Query

Query string

-> Either String a

Either a value, or a brief (not super helpful) description of what went wrong.

Use Jordan to parse a query at a given "base" key.

We need a base key in case the JSON type is "just an int" or something.

hasQueryAtKey :: Text -> Query -> Bool Source #

Determine if there are any query keys that match this base key.

>>> hasQueryAtKey "foo" (parseQuery "foo[bar][baz]=true")
True
>>> hasQueryAtKey "foo" (parseQuery "bar[baz]=true&bar[foo]=true&foo=true")
True
>>> hasQueryAtKey "foo" (parseQuery "bar[baz]=true&bar[foo]=true")
False

Rendering queries

renderQueryAtKey :: ToJSON a => Text -> a -> Query Source #

Render a query at a given key, using the ToJSON instance, which is what you want most of the time.

renderQueryAtKeyWith Source #

Arguments

:: (forall jsonSerializer. JSONSerializer jsonSerializer => jsonSerializer a)

Query renderer to use.

-> Text

Base key

-> a

Value to serialize

-> Query

Query