2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Play 2.5に入門  ⑥コレクション指向のRESTフレームワークPlay'R

Last updated at Posted at 2016-04-30

#Play'R v0.4
今回は、Play Scala 2.5で書かれているコレクション指向(?)のRESTフレームワークPlay'Rを試す。
https://github.com/26lights/PlayR

バージョンはまだ0.4と若いが、解説サイトが用意されている。
http://playr.26lights.com/index.html

使い方はシンプルで好感が持てる。

#例題を試す。
github側にかかれて通りように、sbtベースで動かす(compile/run)。
随時更新のようなので、動かないよ、とか怒られた時は、自ら直す。
サンプルのコードは短く見通しは良い。

##①playr-demo

コードは、
app/controller/PersonController.scala
のみのシンプルな例題。
Play'Rでは、以下のように書かれたPersonsをREST APIを介し公開できる。

case class Person(name: String)

@ImplementedBy(classOf[Persons])
trait PersonList {
  val persons: Map[Int, Person]
}

class Persons extends PersonList{
  val persons = Map(
    1 -> Person("john"),
    2 -> Person("jane")
  )
}

公開は、PlayのController経由にPlay'RのResource系traitを付したコントローラーで行う。

case class PersonController(personList: PersonList) extends Controller
                                                       with Resource[Person]
                                                       with ResourceRead
                                                       with ResourceList {
  def name = "person"

  implicit val personFormat = Json.format[Person]

  val persons = personList.persons

  def fromId(sid: String): Option[Person] = toInt(sid).flatMap(persons.get(_))

  def read(person: Person) = Action { Ok(Json.toJson(person)) }

  def list() = Action { Ok(Json.toJson(persons.keys)) }
}

class PersonRouter @Inject() (personList: PersonList) extends RestResourceRouter(PersonController(personList)) with ApiInfo {

  Logger.debug(s"Router instance created with person list: $personList")
}

解説は以下にある。
http://playr.26lights.com/demo.html

デバックモードで起動(sbt run)している時、コレクションを例えば以下のように更新すると、

class Persons extends PersonList{
  val persons = Map(
    1 -> Person("john"),
    2 -> Person("jane"),
    3 -> Person("石川五右衛門")

  )
}

更新がPersonRouterに伝えられ、Logger.debugが走る。
curlでアクセスしてみる:

curl -f http://localhost:9000/person
[1,2,3]
curl -f http://localhost:9000/person/3
{"name":"石川五右衛門"}

Personクラスの定義を変更すると、


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

@ImplementedBy(classOf[Persons])
trait PersonList {
  val persons: Map[Int, Person]
}

class Persons extends PersonList{
  val persons = Map(
    1 -> Person("john",10),
    2 -> Person("jane",22),
    3 -> Person("石川五右衛門",34)

  )
}

即反映される。

curl -f http://localhost:9000/person/3
{"name":"石川五右衛門","age":34}

##②playr-tutorial

こちらは少し複雑になっているので、チュートリアル文書を読みながら試すのが良さそう。

conf/routesは、以下の定義のみ。

# Routes
# This file defines all application routes (Higher priority routes first)
# ~~~~

->      /api                        controllers.Application

GET     /*file                      controllers.Assets.at(path="/public", file)

sbt runした後、ついつい/apiにアクセスしたくなるが、404となる。

curl -f http://localhost:9000/api
curl: (22) The requested URL returned error: 404 Not Found

Play'Rでは、上のroutesの定義は、
/api以下のアクセスは、controllers.Applicationがコントロールすると読むのが正しい。

参考 Tutorial project structure

app/controller/Application.scalaを見てみる。

Application.scala
class Application @Inject()(val cache: CacheApi, crmApi: CrmApi) extends PlayRRouter with PlayRInfo {

  implicit val colorContainer = ColorContainer(cache)

  val api = RootApiRouter()
    .add(new ColorController)
    .add(crmApi)
    .add(EnumValuesController(DaysEnum))
    .withFilter(LoggingFilter)

  val info = Map(
    "info" -> ApiInfo,
    "jquery.js" -> JQueryApi
  )
}

RESTインターフェースを

val api = RootApiRouter().add(new ColorController).add(crmApi)...

といった具合に追加していくものらしい。

いろいろとアクセスを試してみる。以下、わかりやすさからhttpieを用いる

参考 curlを捨ててhttpieを使おう #curlは捨てなくて良いが..

> http GET localhost:9000/api/color   
HTTP/1.1 200 OK
Content-Length: 9
Content-Type: application/json
Date: Sat, 30 Apr 2016 03:49:56 GMT

[
    1,
    2,
    3,
    4
]

POSTしてみる。

あれ? 
ヘッダーのパラメータに入れても :

http -v POST localhost:9000/api/color name:fakePurple rbg:#123456

JSONで送っても :

http -v POST localhost:9000/api/color name=fakePurple rbg=#123456

エラーになる。

DELETEはできた:

delete.PNG

このあたりはもう後で見直すこととしよう。。。

この例題では、会社-職種-従業員 <-> Person的な入れ子関係のRESTインターフェースも提供されている:

company.PNG

こちらはweb DB的なものを作る時に参考になりそう。

###jquery.scala.jsも
アクセス方法がわからなかったが、scala.jsも使われている模様。

#感想

今回は、ちら見しただけだが、Scala使いな人が、さくっとPlay scalaでRESTしたい時には良いのかも。

前回見たBaasBoxはPlay2.2でがっつり書かれたRESTなmBaaS。BaasBoxそのものの改造/改良は大変な感じ...、なので、このPlay'Rに、BaasBoxのRESTインターフェースを移してのは学習として良いかも!?

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?