Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can spray unmarshall a list in query parameters

I'm new to spray. Im playing around with building the routes, and while I manage to get parameters out of the query string using the parameters directive, I'm having trouble when I want one of the parameters to be a list.

For this example I've defined this case class:

case class Person(name: String, friends: Int)

my route currently looks like this:

path("test") { 
    get { parameters('name, 'friend ).as(Person) { p => complete(p) } }
}

this works fine and I can do a get: localhost:8080/test?name=jo&friends=12 and get what I expect.

I want to pass a list of friends ids, rather than just the number of friends, so I started by changing my case class like so:

case class Person(name: String, friends: Array[Int])

and my call to: localhost:8080/test?name=jo&friends=1,2

this does not compile. I get a type mismatch: found : Person.type required: spray.routing.HListDeserializer[shapeless.::[String,shapeless.::[String,shapeless.HNil]],?] get { parameters('name, 'friend ).as(Person) { p => ^ comment: this points at the P in .as(Person)

Any idea on what I'm doing wrong? I'd love an answer on how to do it. Even better would be an explanation to what is this shapeless type that it's looking for. Thanks

like image 389
user3911709 Avatar asked Sep 29 '22 18:09

user3911709


1 Answers

The first example worked since the parameter 'friend could be automatically converted from String to Int, hence satisfying the requirements of the Person case class.

The latter doesn't work because there's no String => Array[Int] conversion available, so it's impossible to materialize a Person from two strings.

You can tell that it's treating both 'friend and 'name as strings by looking at the message error

spray.routing.HListDeserializer[shapeless.::[String,shapeless.::[String,shapeless.HNil]],?]

can be simplified to something like

String :: String :: HNil

i.e. it's looking for something that can deserialize two strings into something else.

Bottom line, you will need to provide a custom deserializer in order to parse "1,2" into an Array[Int].

Here's the relevant documentation: http://spray.io/documentation/1.1-SNAPSHOT/spray-httpx/unmarshalling/#unmarshalling

like image 169
Gabriele Petronella Avatar answered Oct 10 '22 07:10

Gabriele Petronella