Last active
December 19, 2017 21:02
-
-
Save ayushmishra2005/7f159b57f14a14afe6a34f1ffee20383 to your computer and use it in GitHub Desktop.
Akka Http: High-Level Server-Side API iimplementation of *spray-json*
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 com.tutorial.sample | |
import akka.actor.ActorSystem | |
import akka.event.Logging | |
import akka.http.scaladsl.marshallers.sprayjson.SprayJsonSupport | |
import akka.http.scaladsl.model.{ContentTypeRange, MediaTypes, StatusCodes} | |
import akka.http.scaladsl.server.Directives._ | |
import akka.http.scaladsl.server.{Route, UnsupportedRequestContentTypeRejection} | |
import akka.http.scaladsl.server.directives.MethodDirectives.{get, post} | |
import akka.http.scaladsl.server.directives.RouteDirectives.complete | |
import akka.http.scaladsl.testkit.ScalatestRouteTest | |
import akka.util.Timeout | |
import org.scalatest.{Matchers, WordSpec} | |
import spray.json.DefaultJsonProtocol | |
import scala.concurrent.duration._ | |
case class Employee(id: String, name: String) | |
case class Employees(employees: Seq[Employee]) | |
trait JsonSupport extends SprayJsonSupport { | |
import DefaultJsonProtocol._ | |
implicit val employeeJsonFormat = jsonFormat2(Employee) | |
implicit val employeessJsonFormat = jsonFormat1(Employees) | |
} | |
trait EmployeeRoutes extends JsonSupport { | |
implicit def system: ActorSystem | |
lazy val log = Logging(system, classOf[EmployeeRoutes]) | |
var list: Employees = Employees(Nil) | |
implicit lazy val timeout = Timeout(5.seconds) | |
lazy val employeeRoutes: Route = | |
pathPrefix("employees") { | |
pathEnd { | |
get { | |
complete(list) | |
} ~ | |
post { | |
entity(as[Employee]) { employee => | |
list = list.copy(employees = list.employees ++ Seq(employee)) | |
log.info("Created employee :", employee.name) | |
complete((StatusCodes.Created, employee)) | |
} | |
} | |
} | |
} | |
} | |
class EmployeeRoutesSpec extends WordSpec with Matchers with ScalatestRouteTest | |
with EmployeeRoutes { | |
import org.scalatest.prop.TableDrivenPropertyChecks._ | |
lazy val routes = employeeRoutes | |
"EmployeeRoutes" should { | |
val testData = | |
Table( | |
("clue", "path", "expectedStatus", "expectedEntity"), | |
("return employee list", Get("/employees"), StatusCodes.OK, """{"employees":[]}"""), | |
("add an employee", Post("/employees", Employee("1", "John")), StatusCodes.Created, """{"id":"1","name":"John"}""") | |
) | |
forAll(testData) { case (clue, path, expectedStatus, expectedEntity) => | |
s"$clue" in { | |
path ~> routes ~> check { | |
status should ===(expectedStatus) | |
entityAs[String] should ===(expectedEntity) | |
} | |
} | |
} | |
val rejectData = | |
Table( | |
("clue", "path", "expected"), | |
("reject the request, if respective resource is not found", Get("/emp"), Nil), | |
("reject the request, if the requests content-type is unsupported", Post("/employees", ""), List(UnsupportedRequestContentTypeRejection(Set(ContentTypeRange(MediaTypes.`application/json`))))) | |
) | |
forAll(rejectData) { case (clue, path, expected) => | |
s"$clue" in { | |
path ~> routes ~> check { | |
rejections shouldBe expected | |
handled shouldBe false | |
} | |
} | |
} | |
} | |
} |
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 com.tutorial.sample | |
import akka.actor.ActorSystem | |
import akka.http.scaladsl.Http | |
import akka.http.scaladsl.Http.ServerBinding | |
import akka.stream.ActorMaterializer | |
import scala.concurrent.Future | |
object ServerStarter extends App with EmployeeRoutes { | |
implicit val system = ActorSystem("my-system") | |
implicit val materializer = ActorMaterializer() | |
implicit val executionContext = system.dispatcher | |
val (host, port) = ("localhost", 8080) | |
val bindingFuture: Future[ServerBinding] = | |
Http().bindAndHandle(employeeRoutes, host, port) | |
log.info(s"Server online at http://localhost:8080/\nPress RETURN to stop...") | |
bindingFuture.failed.foreach { ex => | |
log.error(ex, "Failed to bind to {}:{}!", host, port) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment