2

私はplay2.0-Scalaの初心者であり、HTMLページを生成するためにいくつかのWebサービスを呼び出す必要があります。

Play WSAPIページとSadekDrobiからの非常に興味深い記事を読んだ後、これを達成するための最良の方法がまだわかりません。

この記事には、Playの初心者としては完全には理解していないコードスニペットがいくつか示されています。

4ページの図2

val response: Either[Response,Response] =
  WS.url("http://someservice.com/post/123/comments").focusOnOk

val responseOrUndesired: Either[Result,Response] = response.left.map {
  case Status(4,0,4) => NotFound
  case Status(4,0,3) => NotAuthorized
  case _ => InternalServerError
}

val comments: Either[Result,List[Comment]] = 
responseOrUndesired.right.map(r => r.json.as[List[Comment]])

// in the controller
comment.fold(identity, cs => Ok(html.showComments(cs)))

最後の行は何をしfoldますか?commentする必要がありcommentsますか?最後のステートメントをAsyncブロックにグループ化していませんか?

図4は、複数のIO呼び出しを1つの式で組み合わせる方法を示していますfor

for {
  profile <- profilePromise
  events <- attachedEventsPromise
  articles <- topArticlesPromise
} yield Json.obj(
  "profile" -> profile,
  "events" -> events,
  "articles" -> articles )

}

// in the controller
def showInfo(...) = Action { rq =>
  Async {
    actorInfo(...).map(info => Ok(info))
  }
}

このスニペットはどのように使用できますか?(for-expressionの後のextra-に少し混乱してい}ます。)このようなものを書く必要がありますか?

var actorInfo = for {                // Model
  profile <- profilePromise
  events <- attachedEventsPromise
  articles <- topArticlesPromise
} yield Json.obj(
  "profile" -> profile,
  "events" -> events,
  "articles" -> articles )

def showInfo = Action { rq =>         // Controller
  Async {
    actorInfo.map(info => Ok(info))
  }
}

図2と図4のスニペットを組み合わせる最良の方法は何ですか(エラー処理+ IOノンブロッキング呼び出しの構成)?(例:呼び出されたWebサービスのいずれかがエラー404を生成した場合、エラー404ステータスコードを生成したい)。

たぶん誰かがPlayFrameworkでWebサービスを呼び出す完全な例を知っています(Playサンプルアプリケーションや他の場所で例を見つけることができません)。

4

1 に答える 1

2

図2に示す例では、記事が間違っていると言わざるを得ません。この方法focusOnOkはPlay2.0には存在しません。その時、記事の作者はプレリリース版のPlay2を使用したと思います。

に関してcommentは、はい、そうあるべきですcommentsfoldステートメント内のはで動作していますEither。パラメータとして2つの関数を取ります。1つ目は、左の値の場合に適用する関数です。2つ目は、正しい値の場合に適用する関数です。より詳細な説明はここにあります:http://daily-scala.blogspot.com/2009/11/ether.html

つまり、この行は何をするのかということです。値が残っている場合(つまり、望ましくない応答があった場合)、identity値を返すだけの組み込み関数を適用します。値が正しい場合(つまり、OKの応答が得られた場合)、コメントを表示する新しい結果を作成します。

に関してAsyncは、実際には非同期ではありません。focusOnOkはブロッキング関数です(Play 1.xの古いJava時代の名残)。ただし、これは有効なPlay2コードではないことを忘れないでください。

図4の場合、実際には、末尾}は図3にあるものの部分的な代替であるためです。多数のpromiseflatMapの代わりに。代わりに、理解のために行うことができます。userInfo(...).mapまた、の代わりにすべきだと思いますactorInfo(...).map

リンクしたPlayのドキュメントには、完全な例がすでに示されています。

def feedTitle(feedUrl: String) = Action {
  Async {
    WS.url(feedUrl).get().map { response =>
      Ok("Feed title: " + (response.json \ "title").as[String])
    }
  }  
}

feedUrlにあるものは何でも取得し、それが404か何か他のものであるかどうかを確認できるフィールドを持つでmap何かを実行します。responsestatus

そのためには、リンクされた記事の図3と4が出発点になるはずです。だからあなたは次のようなものを持っているでしょう、

def getInfo(...) : Promise[String] = {
  val profilePromise = WS.url(...).get()
  val attachedEventsPromise = WS.url(...).get()
  val topArticlesPromise = WS.url(...).get()

  for {
    profile <- profilePromise
    events <- attachedEventsPromise
    articles <- topArticlesPromise
  } yield {
    // or return whatever you want
    // remember to change String to something else in the return type
    profile.name 
  }
}

def showInfo(...) = Action { rq =>
  Async { 
    getInfo(...).map { info =>
      // convert your info to a Result
      Ok(info)
    }
  }
}
于 2012-09-03T16:00:13.023 に答える