0

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.

1 Answer 1

0

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.