2013-12-09 2 views
4

Я использую Playframework 2.2.1 с Scala, и я пишу REST API, где пользователи могут устанавливать частично неструктурированные данные. В основном, пользователи POST JSON, который выглядит примерно так:Playframework: Как связать JSON с классом case, который содержит карту?

{ 
    "id": 1, 
    "name": "MyObject", 
    "properties": [ 
    "myFirstProperty": "Value 1", 
    "mySecondProperty": "Value 2" 
    ] 
} 

, и я хочу, чтобы привязать к делу класса, который выглядит как:

case class Preference(id: Long, name: String, properties: Map[String, String]) 

Я надеюсь воспользоваться формами API игрой для этого я могу получить кучу хороших вариантов проверки бесплатно, но я не смог найти простой способ сделать это. В идеале (по крайней мере, на мой взгляд), я смог бы определить объект формы вдоль линий:

Form(
    mapping(
    "id" -> longNumber, 
    "name" -> nonEmptyText(min = 5), 
    "properties" -> map(nonEmptyText, nonEmptyText) 
)(Preference.apply)(Preference.unapply) 
) 

К сожалению, «карта (текст, текст)» является вымышленным. Кто-нибудь сделал аналогичную привязку к этому, используя API форм? Если да, то как? Если нет, мне любопытно, что вы использовали вместо проверки. Все это было сделано вручную?

Заранее благодарим за помощь!

+0

Любое повезло с этим? –

ответ

1

Насколько я знаю, API форм и поддержка json не должны смешиваться. Но это не должно быть проблемой, так как вы можете выполнить почти все проверки с помощью любой формы или чтения json.

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 
import play.api.libs.json.Reads._ 
import play.api.data.validation.ValidationError 

val nonEmptyKeyValueMapReads = 
    filter[Map[String, String]](ValidationError("error.invalid"))(properties => 
    properties.keys.find(_.size == 0).isEmpty && properties.values.find(_.size == 0).isEmpty) 

val preferencesReads = 
    ((__ \ 'id).read[Long] and 
    (__ \ 'name).read[String](minLength[String](5)) and 
    (__ \ 'properties).read[Map[String, String]](nonEmptyKeyValueMapReads))(Preferences) 

Существует несколько способов достижения ваших свойств, это один из них. После определения чтения вы можете использовать его для проверки ваших данных, например. myJson.validate(preferencesReads)

2

Возможно, я не понимаю ваш вопрос, но не the reads macro делать то, что вы хотите?

import play.api.libs.json._ 
import play.api.libs.functional.syntax._ 

implicit val preferenceReads = Json.reads[Preference] 

С этими словами подразумевается в области видимости, вы можете использовать as, asOpt или validate для преобразования значения JSON в Preference (см the Play ScalaJson docs).

+0

Hi @Aaron - Я отредактировал вопрос, чтобы сделать его более понятным, так как в ретроспективе я не слишком хорошо писал. Мой вопрос был более конкретно о объединении JSON-анализа с API-интерфейсом Play's Forms, который делает выполнение базовой проверки (например, длины строк, например) очень простым и элегантным. – Joe

Смежные вопросы