Last active
November 7, 2015 15:09
-
-
Save dakatsuka/36aa89291a4b00d8d09f to your computer and use it in GitHub Desktop.
http4sお試し
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name := "http4stest" | |
version := "0.1.0" | |
scalaVersion := "2.11.7" | |
resolvers += "Scalaz Bintray Repo" at "http://dl.bintray.com/scalaz/releases" | |
libraryDependencies ++= Seq( | |
"org.http4s" %% "http4s-dsl" % "0.10.1", | |
"org.http4s" %% "http4s-blaze-server" % "0.10.1", | |
"org.http4s" %% "http4s-blaze-client" % "0.10.1", | |
"org.http4s" %% "http4s-argonaut" % "0.10.1", | |
"com.github.mauricio" %% "mysql-async" % "0.2.18" | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package jp.dakatsuka.http4s | |
import argonaut.Argonaut._ | |
import argonaut.CodecJson | |
import com.github.mauricio.async.db.{RowData, Configuration} | |
import com.github.mauricio.async.db.mysql.MySQLConnection | |
import org.http4s.argonaut._ | |
import org.http4s.EntityEncoder | |
import org.http4s.dsl._ | |
import org.http4s.server.HttpService | |
import org.http4s.server.blaze.BlazeBuilder | |
import scala.concurrent.duration._ | |
import scala.concurrent.{Await, Future} | |
import scala.concurrent.ExecutionContext.Implicits.global | |
import scala.util.{Success, Failure} | |
import scalaz.concurrent.Task | |
import scalaz.syntax.either._ | |
case class User(id: Long, email: String, screen_name: String) | |
object User { | |
implicit val userCodec: CodecJson[User] = casecodec3(User.apply, User.unapply)("id", "email", "screen_name") | |
implicit val userEncoder: EntityEncoder[User] = jsonEncoderOf[User] | |
implicit val usersEncoder: EntityEncoder[Seq[User]] = jsonEncoderOf[Seq[User]] | |
val selectAll = "SELECT * FROM users" | |
val selectOne = "SELECT * FROM users WHERE id = ? LIMIT 1" | |
def all(implicit connection: MySQLConnection): Future[Seq[User]] = | |
connection.sendQuery(selectAll).map { _.rows.map(rs => | |
rs.map(toEntity).toSeq | |
).getOrElse(Seq.empty)} | |
def find(id: Long)(implicit connection: MySQLConnection): Future[Option[User]] = | |
connection.sendPreparedStatement(selectOne, Seq(id)).map { _.rows.flatMap(rs => rs.headOption.map(toEntity)) } | |
private def toEntity(row: RowData): User = User( | |
id = row("id").asInstanceOf[Int].toLong, | |
email = row("email").asInstanceOf[String], | |
screen_name = row("screen_name").asInstanceOf[String] | |
) | |
} | |
object MainService { | |
implicit class FutureToTaskTransformer[+A](future: Future[A]) { | |
def toTask: Task[A] = { | |
Task.async { register => | |
future.onComplete { | |
case Success(v) => register(v.right) | |
case Failure(e) => register(e.left) | |
} | |
} | |
} | |
} | |
val configuration = Configuration(username = "root", host = "127.0.0.1", database = Some("testdb"), port = 3306) | |
implicit val connection = new MySQLConnection(configuration) | |
val service = HttpService { | |
case GET -> Root => | |
Ok("Document Root") | |
case GET -> Root / "users" => | |
User.all.toTask.flatMap(users => Ok(users)) | |
case GET -> Root / "users" / LongVar(id) => | |
User.find(id).toTask.flatMap { | |
case Some(user) => Ok(user) | |
case _ => NotFound() | |
} | |
} | |
def main(args: Array[String]): Unit = { | |
Await.result(connection.connect, 5 seconds) | |
BlazeBuilder.bindHttp(8080) | |
.mountService(service) | |
.run | |
.awaitShutdown() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment