2

I am fairly new to Haskell and Yesod so I've been looking through many tutorials and documentation. I found another StackOverflow about parsing url queries: Lookup query parameters in Yesod That said, the solution there is not working for arrays of parameters in these url queries.

For example: http://localhost:3000/models/product?field[]=test1&field[]=test2&field[]=test3&domain[]=["id","name",True]&limit=25

As far as I can tell, the /models/product can be handled by defining a route, and I am able to even get the domain[] parameter. However if I do a lookup on field[] I can only get the first value test1 and I have no way to get the rest. Additionally, assuming that I have no foreknowledge of the size of this array, how would I accomplish this?

Thanks!

2 Answers2

1

I solved this via some hack code, but I'm sure there's probably a better solution out there. Just posting this for other's reference:

getProductR :: Handler Value
getProductR = do
    getParameters <- reqGetParams <$> getRequest
    let fields = [ b | (a,b) <- getParameters , a == "field[]"]
    let domains = cleanseInput getParameters "domain[]"
    let limit = Import.lookup (Import.pack "limit") getParameters

    return $ object [
                        (Import.pack "fields") .= fields,
                        (Import.pack "domains") .= domains,
                        (Import.pack "limit") .= limit
                    ]

cleanseInput params key = [ Data.List.filter (/= "") [Data.Text.filter (/= ',' ) x | x<-(Data.Text.splitOn "\"" (Data.Text.tail (Data.Text.init b)))] | (a,b) <- params , a == key]
1

To my knowledge, there isn't an HTTP standard way of handling arrays in query parameters. Several tools, like Ruby on Rails or PHP, have their own conventions for expressing arrays in query parameters.

Yesod doesn't have its own format for arrays (or dictionaries, or other data structures) in query parameters, so I don't think there's any official API to handle this.

If you can, I would recommend doing a POST request with a JSON body for this case. If it must be a GET request, you could also do a GET with JSON in the query parameters and parse that. This allows you to avoid writing custom parser code, leverages the power of existing aeson instances, will be more portable across HTTP clients like Android/iOS/the web. This advice is fairly non-standard, admittedly, but it's worked great for me in practice.

MaxGabriel
  • 7,617
  • 4
  • 35
  • 82