Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Building APIs in Scala with Playframework2

Building APIs in Scala with Playframework2

My talk from Silicon Valley Code Camp 2013.

Two years ago I gave a talk on PlayFramework with Java at SVCC. As with everything, PlayFramework has evolved into a far mature ecosystem with native Scala support, and Typesafe backing. PlayFramework 2 is a simple, MVC-based, convention over configuration web application framework for Java and Scala. It is rapidly gaining popularity as more and more companies are adopting it for building scalable, performant, share-nothing architectures. In this talk I'll cover the fundamentals of Play! Framework2, a brief overview of Scala, and demonstrate building a simple, RESTful API. This will be a very interactive, and hands-on session. It'd be awesome if you have played around with Scala, but if you have not, the scope of this talk does not require you to be a Scala expert. It will however be very useful if you've worked with other Web Application Frameworks like Jersey, CXF, etc. so you can cross-relate the concepts.

Manish Pandit

October 05, 2013
Tweet

More Decks by Manish Pandit

Other Decks in Programming

Transcript

  1. Building APIs in Scala with Play! Framework 2 Silicon Valley

    Code Camp Oct 5th, 2013 Manish Pandit @lobster1234
  2. Scala Concise, yet expressive Statically Typed via Type Inference Rich

    Constructs Functions as First Class Citizens Power of DSL Interoperability with the Java Ecosystem
  3. Typesafe Activator A very simple way to start with Scala

    and Play! Applications Browser-based Interactive Comes with a good number of templates
  4. Typesafe Activator Use if you do not have an IDE

    Use it to play with various templates it comes with Yet to mature but a (very) good start
  5. Play! Framework Simple Convention over Configuration Focus on Developer Productivity

    Asynchronous Processing Model Makes testing easy JSON support for RESTFul Applications
  6. Gotchas! Start with a fresh installation of ScalaIDE Go to

    Install New Software – Select ScalaIDE – Check Play2 Plugin
  7. Play! Core Concepts Uses sbt as the build system (In

    a special way to support always-on builds)
  8. Play! Actions In simple terms, an Action takes function, that

    takes a request Request, and returns a Response.
  9. The almighty Action A simple, no-request that returns a result.

    A function that makes the Request available to the block You can pass a BodyParser to the Action as an argument Default BodyParsers are available for common content types
  10. Play! Console Demo run vs. ~run With ~ run or

    run, change the app with syntax error Fix the app and retry Use the app with ~ test in Play! Console Change the code and watch the tests fail Change the tests and watch them pass
  11. The Routes file Type-safe way to define mappings from URLs

    to Actions Rich support for basic data types Handling of defaults
  12. RESTFul APIs Not JSON over HTTP Not JSON representation of

    your Database No Spec or official standard
  13. RESTFul APIs Envision the entities as HTTP resources Envision the

    interactions as HTTP methods Read RFC 2616
  14. Play! Hands-on API Model – A Person APIs – Get

    all, Get by First/Last/Zip, Add a person JSON Request and Response
  15. Model object PersonModel { val persons = ArrayBuffer(Person("Manish", "Pandit", 94568),

    Person("John", "Doe", 95051), Person("My", "Neighbor", 94568)) def add(p: Person) = persons += p def getAll = persons def getByFirstName(first: String) = persons.filter(_.first == first) def getByLastName(last: String) = persons.filter(_.last == last) def getByZip(zip: Int) = persons.filter(_.zip == zip) } case class Person(first: String, last: String, zip: Int)
  16. Controller object SimpleAPI extends Controller { implicit val personWrites =

    Json.writes[Person] implicit val personReads = Json.reads[Person] def getAll = Action { Ok(Json.toJson(PersonModel.getAll)) } def add = Action(parse.json) { request => Logger.info(s"Body is $request.body") request.body.validate(personReads) match { case x: JsError => BadRequest case x: JsSuccess[Person] => PersonModel.add(x.get) Created } } def getByFirstName(first: String) = Action { val list = PersonModel.getByFirstName(first) if (list.isEmpty) NotFound else Ok(Json.toJson(PersonModel.getByFirstName(first))) } }
  17. Routes #  ~~~~   # Routes # This file defines

    all application routes (Higher priority routes first) # ~~~~ # Home page GET /persons controllers.SimpleAPI.getAll GET /persons/first/:first controllers.SimpleAPI.getByFirstName(first) GET /persons/last/:last controllers.SimpleAPI.getByLastName(last) GET /persons/zip/:zip controllers.SimpleAPI.getbyZip(zip:Int) GET /persons/default controllers.SimpleAPI.getByFirstName(first="Manish") POST /persons controllers.SimpleAPI.add
  18. Play! Packaging Use play dist to package the app as

    a zip file Run using the start script