Reputation: 6264
I'm scala newbie and come from a Ruby background so and am having trouble rendering json response in my web service for which I use scalatra, mongodb with liftweb mongo record and argonaut for JSon serialisation and deserialisation.
However based on the examples given at http://argonaut.io/ I'm unable to figure out how this would work when using the net.liftweb.mongo.record library.
On compiling this i get a error which says a type mismatch
. The error description follows the code snippet.
package firstscalatraapp import org.scalatra import net.liftweb.mongodb._ import net.liftweb.mongodb.record.MongoRecord import net.liftweb.mongodb.record.field.ObjectIdPk import net.liftweb.record.field.StringField import net.liftweb.record.field.IntField import net.liftweb.record.field.PasswordField import net.liftweb.record.field.DateTimeField import net.liftweb.mongodb.record.MongoMetaRecord import argonaut._ import Argonaut._ case class Person private extends MongoRecord[Person] with ObjectIdPk[Person] { def meta = Person object age extends IntField(this, 3) object name extends StringField(this, 29) object created_at extends DateTimeField(this) object password extends PasswordField(this) } object Person extends Person with MongoMetaRecord[Person] { implicit def PersonCodecJson: CodecJson[Person] = casecodec3(Person.apply, Person.unapply)("name", "age", "things") }
The Error i get is
[error] found : () => firstscalatraapp.Person
[error] required: (?, ?, ?) => ?
[error] casecodec3(Person.apply, Person.unapply)("name", "age", "things")
[error] ^
[error] one error found
[error] (compile:compile) Compilation failed
which seems logical because the constructor does not accept any parameters and the mongo library seems to be generating the val
for the fields that i need for the class (I still don't fully understand what the lift mongo wrapper does yet).
So how do i define the implicit to be able to find serialise an object of type person.
Also how do I define serialisation capabilities when i'm dealing with collections. For instance when I have a List[Person]
.
Thanks in advance. I would really appreciate any help i can get on this.
Upvotes: 0
Views: 292
Reputation: 3914
I'm just about to start using Argonaut so I'm no expert on that but with that said your initial problem seems obvious.
casecodec3 needs a constructor and a deconstructor for the class you're defining the codec for. In the examples of Argonaut they're using case classes and these have automatically generated companion objects with apply/unapply for the fields defined. Which for casecodec3 needs to be 3. In your case, the case class is of zero-arity - you have no case class fields at all. The fields of the record are defined as inner objects with their own apply-methods (very imperative stuff). That's just the way lifts records are defined. So your apply method is just () => Person.
casecodec3 wants a function from a 3-tuple to Person and from Person to a 3-tuple. I would suggest skipping the case definition if you're going to use lift record. And create functions on the side instead. Something like:
object Person extends Person with MongoMetaRecord[Person] {
implicit def PersonCodecJson: CodecJson[Person] =
casecodec3(parse, serialize)("name", "age", "things")
// Something like
def parse(name: String, age: Int, things: Something) = {
val p = Person.createRecord
p.name(name)
...
}
def serialize(p: Person) = (p.name.get, p.age.get, p.things.get)
}
As for your other questions I think you can head back to argonaut.io again. Their documentation seems quite alright - maybe it was worse when you posted this question as it is kind of old?
I'm going to try to replace all my serialization from lift-json to argonaut right now so if you're still stuck (probably not) I might be able to answer better in a bit.
Upvotes: 0