I am currently defining an API with:
```
type DeviceApi =
"v2/devices/catalog/search" :> Header "X-HEADER" String
:> QueryParam "name" String
:> QueryParam "description" String
:> QueryParam "page" Int
:> QueryParam "limit" Int
:> QueryParam "tags" [Tag]
:> QueryParam "serial" [Tag]
:> QueryParam "dir" SortDir
:> QueryParam "sort" SortBy
:> ReqBody '[JSON] FilterReqBody
:> Get '[JSON] DevicePaginatedListing
```
And using this to generate a function to call the endpoint
```
catalogSearch :: AuthHeader -> Maybe String -> Maybe String -> Maybe Int -> Maybe Int -> Maybe [Tag] -> Maybe [Tag] -> Maybe SortDir -> Maybe SortBy -> FilterReqBody -> ClientM DevicePaginatedListing
```
The issue is that the function signature is quite ugly, I'd like to define a record type and default params to be able to generate the function like this:
```
data CatalogSearchParams = CatalogSearchParams { deviceName :: Maybe String
, desc :: Maybe String
, page :: Maybe Int
, limit :: Maybe Int
, tags :: Maybe [Tag]
, serial :: Maybe [Tag]
, dir :: Maybe SortDir
, sort :: Maybe SortBy
, reqBody :: FilterReqBody}
defaultCatalogSearchParams = CatalogSearchParams { deviceName = Nothing
, desc = Nothing
, page = Just 1
, limit = Just 1000
, tags = Nothing
, serial = Nothing
, dir = Just Asc
, sort = Just Name
, reqBody = FilterReqBody [] }
catalogSearch :: AuthHeader -> CatalogSearchParams -> ClientM DevicePaginatedListing
catalogSearch = client api
```
Which of course does not work.
How do you normally deal with endpoints that accept a lot of query params? I am sure this is something not uncommon.