SlideShare a Scribd company logo
API First
with Play and Swagger
THEN
Java Developer
LATER
Enterprise
Architect
NOW
Scala Consultant
TWITTER
@slavaschmidt
MAIL
slavaschmidt@gmx.de
THEN
Java Developer
LATER
Enterprise
Architect
NOW
Scala Consultant
TWITTER
@ZALANDO
MAIL
slavaschmidt@gmx.de
NOW
Scala Consultant
@ZALANDO
@ZALANDO
@ZALANDO
@ZALANDO
•Autonomy
•Small in size
•Full responsibility
•One or more components
•Autonomy
•Full responsibility
•One system boundary
API First
Document and
peer review API
before writing a
single line of code
Ideally, generate either
your server interfaces
or your test data (or
both) from the spec
Specification
Server Implementation
Review
Client Implementation
MisinterpretationMisrepresentation
+ API First
REST
???
What is REST’s central distinguishing feature?
… its emphasis on a uniform interface between
components
Roy Thomas Fielding
remaining the same in all cases and at all
times
British Dictionary
uniform
How do we combine “same” and “changing” ?
???
REST
• Client-Server
• Stateless
• Cacheable
• Layered System
• Uniform Interface
• Identification of resources
• Manipulation of resources through these representations
• Self-descriptive messages
• Hypermedia as the engine of application state
implementation details
Server
Client/Server
Protocol
Architecture
Hexagonal Architecture
The 1968/69 NATO

Software Engineering
Conference
aka Ports and Adapters
Chris Fidao
https://www.youtube.com/watch?v=6SBjKOwVq0o
Hexagonal Architecture
Hexagonal Architecture
Hexagonal Architecture
Transport
Transport
Validations
Validations
Model
Model
DRY
DRY
Most people take DRY to mean you shouldn't duplicate code.
That's not its intention. The idea behind DRY is far grander
than that. DRY says that every piece of system knowledge
should have one authoritative, unambiguous representation.
Dave Thomas
Getting real…
• Easy to use
• Human readable
• Widest adoption
• Open Source
• Scala and Java
• Dynamic recompilation / Hot reload
• Asynchronous IO
• Easy to use
• URI path definitions (supports parameterisation and templating)
• URI parameter definitions
• Response definitions
• Scheme definitions
• MIME type definitions
• Primitive datatypes
• Complex datatypes
• Structural constraints
• Value constraints
• Security constraints
• Tags
• Vendor extensions
Specification
URLs
Verbs
Parameters
Security
Definitions
Specification
URLs
Verbs
Parameters
Security
Definitions Validations
Model
Test Data
Validations
Play Routes
Marshallers
Tests
Controllers
DEMO
Architecture
AST
Play
Akka HTTP
Swagger
RAML
Apiary
Blueprint
…
…
…
Generated code
Metadata
swagger: "2.0"

info:

version: 1.0.0

title: Swagger Petstore

description: A sample API that uses a petstore as an example to
demonstrate features in the swagger-2.0 specification

termsOfService: http://swagger.io/terms/

contact:

name: Swagger API Team

email: foo@example.com

url: http://madskristensen.net

license:

name: MIT

url: http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT

host: petstore.swagger.io

basePath: /api

schemes:

- http

consumes:

- application/json

produces:

- application/json
URL Prefix
Definitions
definitions:

Pet:

allOf:

- $ref: '#/definitions/NewPet'

- required:

- id

properties:

id:

type: integer

format: int64

NewPet:

required:

- name 

properties:

name:

type: string

tag:

type: string 

Error:

required:

- code

- message

properties:

code:

type: integer

format: int32

message:

type: string
object definitions {

trait NewPetDef {

def name: String

def tag: Option[String]

}

case class Pet(

id: Option[Long],

name: String,

tag: Option[String]

) extends NewPetDef

case class NewPet(

name: String,

tag: Option[String]

) extends NewPetDef

case class Error(

code: Int,

message: String

)

}
Test data
definitions:

Pet:

allOf:

- $ref: '#/definitions/NewPet'

- required:

- id

properties:

id:

type: integer

format: int64

NewPet:

required:

- name 

properties:

name:

type: string

tag:

type: string 

Error:

required:

- code

- message

properties:

code:

type: integer

format: int32

message:

type: string
object generatorDefinitions {



def createPet = _generate(PetGenerator)

def createNewPet = _generate(NewPetGenerator)

def createError = _generate(ErrorGenerator)

// test data generator for /definitions/Pet

val PetGenerator =

for {

id <- Gen.option(arbitrary[Long])

name <- arbitrary[String]

tag <- Gen.option(arbitrary[String])

} yield Pet(id, name, tag)

// test data generator for /definitions/NewPet

val NewPetGenerator =

for {

name <- arbitrary[String]

tag <- Gen.option(arbitrary[String])

} yield NewPet(name, tag)

// test data generator for /definitions/Error

val ErrorGenerator =

for {

code <- arbitrary[Int]

message <- arbitrary[String]

} yield Error(code, message)

def _generate[T](gen: Gen[T]) = (count: Int) =>
for (i <- 1 to count) yield gen.sample

}
Validations'#/definitions/NewPet'

red:

rties:

ype: integer

ormat: int64



s:

string

string 

ge

s:

integer

t: int32

:

string
class PetValidation(instance: Pet) {

import de.zalando.play.controllers.PlayValidations._

val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]

val result = {

val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)

if (errors.nonEmpty) Left(errors) else Right(instance)

}

}





class NewPetValidation(instance: NewPet) {

import de.zalando.play.controllers.PlayValidations._

val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]

val result = {

val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)

if (errors.nonEmpty) Left(errors) else Right(instance)

}

}





class ErrorValidation(instance: Error) {

import de.zalando.play.controllers.PlayValidations._

val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]

val result = {

val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)

if (errors.nonEmpty) Left(errors) else Right(instance)

}

}
Validations
/pets/{id}:

get:

description: Returns a user based
on a single ID, if the user does not
have access to the pet

operationId: find pet by id

parameters:

- name: id

in: path

description: ID of pet to fetch

required: true

type: integer

format: int64

responses:

200:

description: pet response

schema:

$ref: '#/definitions/Pet'

default:

description: unexpected error

schema:

$ref: '#/definitions/Error'
class ValidationForPetexpandedYamlfindPetById(in: (Long)) {

val (id) = in



val idConstraints = new ValidationBase[Long] {

override def constraints: Seq[Constraint[Long]] = Seq()

}



val normalValidations =
Seq(idConstraints.applyConstraints(id))



val containerValidations =
Seq.empty[scala.Either[scala.Seq[ParsingError], String]]



val rightResult = Right((id))



val allValidations = normalValidations ++
containerValidations



val result = {

val errors =
allValidations.filter(_.isLeft).flatMap(_.left.get)

if (errors.nonEmpty) Left(errors) else rightResult

}

}
Tests
"discard invalid data" in new WithApplication {

val genInputs =

for {

id <- arbitrary[Long]

} yield (id)

val inputs = genInputs suchThat { i => new ValidationForPetexpandedYamlfindPetById(i).result !=
Right(i) }

val props = forAll(inputs) { i => testInvalidInput(i) }

checkResult(props)

}
Tests
def testInvalidInput(in: (Long)) = {

val (id) = in

val url = s"""/api/pets/${id}"""

val path = route(FakeRequest(GET, url)).get

val validation = new ValidationForPetexpandedYamlfindPetById(id).result

lazy val validations = validation.left.get flatMap {

_.messages map { m => contentAsString(path).contains(m) ?= true }

}

("given an URL: [" + url + "]") |: all(

status(path) ?= BAD_REQUEST,

contentType(path) ?= Some("application/json"),

validation.isLeft ?= true,

all(validations:_*)

)

}
Controllers
private val findPetByIdResponseMimeType = "application/json"

private val findPetByIdActionSuccessStatus = Status(200)



private type findPetByIdActionRequestType = (Long)

private type findPetByIdActionResultType = Pet

private type findPetByIdActionType = findPetByIdActionRequestType => Either[Throwable, findPetByIdActionResultType]



private def errorToStatusfindPetById: PartialFunction[Throwable, Status] = PartialFunction.empty[Throwable, Status]



def findPetByIdAction = (f: findPetByIdActionType) => (id: Long) => Action {

val result = new ValidationForPetexpandedYamlfindPetById(id).result.right.map {

processValidfindPetByIdRequest(f)

}

implicit val marshaller = parsingErrors2Writable(findPetByIdResponseMimeType)

val response = result.left.map { BadRequest(_) }

response.fold(a => a, c => c)

}



private def processValidfindPetByIdRequest(f: findPetByIdActionType)(request: findPetByIdActionRequestType) = {

val callerResult = f(request)

val status = callerResult match {

case Left(error) => (errorToStatusfindPetById orElse defaultErrorMapping)(error)

case Right(result) => findPetByIdActionSuccessStatus

}

implicit val findPetByIdWritableJson = anyToWritable[findPetByIdActionResultType](findPetByIdResponseMimeType)

status(callerResult)

}
Skeletons
class PetexpandedYaml extends PetexpandedYamlBase {



// handler for GET /pets

def findPets = findPetsAction { in : (Option[Seq[String]], Option[Int]) =>

val (tags, limit) = in

???

}



// handler for POST /pets

def addPet = addPetAction { in : (NewPet) =>

val (pet) = in

???

}



// handler for GET /pets/{id}

def findPetById = findPetByIdAction { in : (Long) =>

val (id) = in

???

}



// handler for DELETE /pets/{id}

def deletePet = deletePetAction { in : (Long) =>

val (id) = in

???

}

}
http://github.com/zalando/play-swagger
Questions?

More Related Content

What's hot

Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017
Mike Nakhimovich
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
John De Goes
 
RESTful API using scalaz (3)
RESTful API using scalaz (3)RESTful API using scalaz (3)
RESTful API using scalaz (3)
Yeshwanth Kumar
 
Testing Java Code Effectively - BaselOne17
Testing Java Code Effectively - BaselOne17Testing Java Code Effectively - BaselOne17
Testing Java Code Effectively - BaselOne17
Andres Almiray
 
RIAs Done Right: Grails, Flex, and EXT GWT
RIAs Done Right: Grails, Flex, and EXT GWTRIAs Done Right: Grails, Flex, and EXT GWT
RIAs Done Right: Grails, Flex, and EXT GWT
Michael Galpin
 
Refactoring
RefactoringRefactoring
Refactoring
Amir Barylko
 
RESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkRESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkBo-Yi Wu
 
How Testability Inspires AngularJS Design / Ran Mizrahi
How Testability Inspires AngularJS Design / Ran MizrahiHow Testability Inspires AngularJS Design / Ran Mizrahi
How Testability Inspires AngularJS Design / Ran Mizrahi
Ran Mizrahi
 
Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2
Ahmed Moawad
 
Moderne backends mit dem aktor programmiermodell
Moderne backends mit dem aktor programmiermodellModerne backends mit dem aktor programmiermodell
Moderne backends mit dem aktor programmiermodell
Damir Dobric
 
2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack
Codifly
 
Second Level Cache in JPA Explained
Second Level Cache in JPA ExplainedSecond Level Cache in JPA Explained
Second Level Cache in JPA Explained
Patrycja Wegrzynowicz
 
Arrays &amp; functions in php
Arrays &amp; functions in phpArrays &amp; functions in php
Arrays &amp; functions in php
Ashish Chamoli
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
James Titcumb
 
What you need to know about Lambdas - Jamie Allen
What you need to know about Lambdas - Jamie AllenWhat you need to know about Lambdas - Jamie Allen
What you need to know about Lambdas - Jamie Allen
jaxconf
 
Thinking Beyond ORM in JPA
Thinking Beyond ORM in JPAThinking Beyond ORM in JPA
Thinking Beyond ORM in JPA
Patrycja Wegrzynowicz
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
JAX London
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development Experiences
Peter Pilgrim
 
Clean up your code with C#6
Clean up your code with C#6Clean up your code with C#6
Clean up your code with C#6
Rui Carvalho
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
José Paumard
 

What's hot (20)

Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017Intro to GraphQL on Android with Apollo DroidconNYC 2017
Intro to GraphQL on Android with Apollo DroidconNYC 2017
 
Scalaz Stream: Rebirth
Scalaz Stream: RebirthScalaz Stream: Rebirth
Scalaz Stream: Rebirth
 
RESTful API using scalaz (3)
RESTful API using scalaz (3)RESTful API using scalaz (3)
RESTful API using scalaz (3)
 
Testing Java Code Effectively - BaselOne17
Testing Java Code Effectively - BaselOne17Testing Java Code Effectively - BaselOne17
Testing Java Code Effectively - BaselOne17
 
RIAs Done Right: Grails, Flex, and EXT GWT
RIAs Done Right: Grails, Flex, and EXT GWTRIAs Done Right: Grails, Flex, and EXT GWT
RIAs Done Right: Grails, Flex, and EXT GWT
 
Refactoring
RefactoringRefactoring
Refactoring
 
RESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP FrameworkRESTful API Design & Implementation with CodeIgniter PHP Framework
RESTful API Design & Implementation with CodeIgniter PHP Framework
 
How Testability Inspires AngularJS Design / Ran Mizrahi
How Testability Inspires AngularJS Design / Ran MizrahiHow Testability Inspires AngularJS Design / Ran Mizrahi
How Testability Inspires AngularJS Design / Ran Mizrahi
 
Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2Exploring Angular 2 - Episode 2
Exploring Angular 2 - Episode 2
 
Moderne backends mit dem aktor programmiermodell
Moderne backends mit dem aktor programmiermodellModerne backends mit dem aktor programmiermodell
Moderne backends mit dem aktor programmiermodell
 
2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack2018 05-16 Evolving Technologies: React, Babel & Webpack
2018 05-16 Evolving Technologies: React, Babel & Webpack
 
Second Level Cache in JPA Explained
Second Level Cache in JPA ExplainedSecond Level Cache in JPA Explained
Second Level Cache in JPA Explained
 
Arrays &amp; functions in php
Arrays &amp; functions in phpArrays &amp; functions in php
Arrays &amp; functions in php
 
Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)Diving into HHVM Extensions (PHPNW Conference 2015)
Diving into HHVM Extensions (PHPNW Conference 2015)
 
What you need to know about Lambdas - Jamie Allen
What you need to know about Lambdas - Jamie AllenWhat you need to know about Lambdas - Jamie Allen
What you need to know about Lambdas - Jamie Allen
 
Thinking Beyond ORM in JPA
Thinking Beyond ORM in JPAThinking Beyond ORM in JPA
Thinking Beyond ORM in JPA
 
Spring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard WolffSpring Day | Spring and Scala | Eberhard Wolff
Spring Day | Spring and Scala | Eberhard Wolff
 
JavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development ExperiencesJavaCro 2014 Scala and Java EE 7 Development Experiences
JavaCro 2014 Scala and Java EE 7 Development Experiences
 
Clean up your code with C#6
Clean up your code with C#6Clean up your code with C#6
Clean up your code with C#6
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 

Similar to API first with Swagger and Scala by Slava Schmidt

Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"
Fwdays
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
Nikita Popov
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe TestingGetting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe Testing
Mark Rickerby
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Michelangelo van Dam
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
Shinya Ohyanagi
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
Michelangelo van Dam
 
Structure on a freeform world
Structure on a freeform worldStructure on a freeform world
Structure on a freeform world
Ikai (藍奕凱) Lan
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
Michelangelo van Dam
 
Einführung in TypeScript
Einführung in TypeScriptEinführung in TypeScript
Einführung in TypeScript
Demian Holderegger
 
Improving Correctness with Types
Improving Correctness with TypesImproving Correctness with Types
Improving Correctness with Types
Iain Hull
 
"Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin "Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin
Vasil Remeniuk
 
Test driven development with behat and silex
Test driven development with behat and silexTest driven development with behat and silex
Test driven development with behat and silex
Dionyshs Tsoumas
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
Maarten Balliauw
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
Eric Pederson
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side Javascript
Julie Iskander
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
Amal Khailtash
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
Ian Robertson
 
Enrique Amodeo | Graphql + Microservices = Win! | Codemotion Madrid 2018
Enrique Amodeo | Graphql + Microservices = Win! | Codemotion Madrid 2018 Enrique Amodeo | Graphql + Microservices = Win! | Codemotion Madrid 2018
Enrique Amodeo | Graphql + Microservices = Win! | Codemotion Madrid 2018
Codemotion
 

Similar to API first with Swagger and Scala by Slava Schmidt (20)

Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"Nikita Popov "What’s new in PHP 8.0?"
Nikita Popov "What’s new in PHP 8.0?"
 
What's new in PHP 8.0?
What's new in PHP 8.0?What's new in PHP 8.0?
What's new in PHP 8.0?
 
ppopoff
ppopoffppopoff
ppopoff
 
Getting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe TestingGetting to Grips with SilverStripe Testing
Getting to Grips with SilverStripe Testing
 
Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012Quality Assurance for PHP projects - ZendCon 2012
Quality Assurance for PHP projects - ZendCon 2012
 
Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2Zend Framework Study@Tokyo #2
Zend Framework Study@Tokyo #2
 
Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12Workshop quality assurance for php projects tek12
Workshop quality assurance for php projects tek12
 
Structure on a freeform world
Structure on a freeform worldStructure on a freeform world
Structure on a freeform world
 
Unit testing zend framework apps
Unit testing zend framework appsUnit testing zend framework apps
Unit testing zend framework apps
 
Einführung in TypeScript
Einführung in TypeScriptEinführung in TypeScript
Einführung in TypeScript
 
Improving Correctness with Types
Improving Correctness with TypesImproving Correctness with Types
Improving Correctness with Types
 
"Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin "Scala in Goozy", Alexey Zlobin
"Scala in Goozy", Alexey Zlobin
 
Test driven development with behat and silex
Test driven development with behat and silexTest driven development with behat and silex
Test driven development with behat and silex
 
behat
behatbehat
behat
 
Building a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to SpaceBuilding a friendly .NET SDK to connect to Space
Building a friendly .NET SDK to connect to Space
 
Scala for Java Programmers
Scala for Java ProgrammersScala for Java Programmers
Scala for Java Programmers
 
Introduction to Client-Side Javascript
Introduction to Client-Side JavascriptIntroduction to Client-Side Javascript
Introduction to Client-Side Javascript
 
SystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features SummarySystemVerilog OOP Ovm Features Summary
SystemVerilog OOP Ovm Features Summary
 
Lambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive CodeLambda Chops - Recipes for Simpler, More Expressive Code
Lambda Chops - Recipes for Simpler, More Expressive Code
 
Enrique Amodeo | Graphql + Microservices = Win! | Codemotion Madrid 2018
Enrique Amodeo | Graphql + Microservices = Win! | Codemotion Madrid 2018 Enrique Amodeo | Graphql + Microservices = Win! | Codemotion Madrid 2018
Enrique Amodeo | Graphql + Microservices = Win! | Codemotion Madrid 2018
 

More from JavaDayUA

STEMing Kids: One workshop at a time
STEMing Kids: One workshop at a timeSTEMing Kids: One workshop at a time
STEMing Kids: One workshop at a time
JavaDayUA
 
Flavors of Concurrency in Java
Flavors of Concurrency in JavaFlavors of Concurrency in Java
Flavors of Concurrency in Java
JavaDayUA
 
What to expect from Java 9
What to expect from Java 9What to expect from Java 9
What to expect from Java 9
JavaDayUA
 
Continuously building, releasing and deploying software: The Revenge of the M...
Continuously building, releasing and deploying software: The Revenge of the M...Continuously building, releasing and deploying software: The Revenge of the M...
Continuously building, releasing and deploying software: The Revenge of the M...
JavaDayUA
 
The Epic Groovy Puzzlers S02: The Revenge of the Parentheses
The Epic Groovy Puzzlers S02: The Revenge of the ParenthesesThe Epic Groovy Puzzlers S02: The Revenge of the Parentheses
The Epic Groovy Puzzlers S02: The Revenge of the Parentheses
JavaDayUA
 
20 Years of Java
20 Years of Java20 Years of Java
20 Years of Java
JavaDayUA
 
How to get the most out of code reviews
How to get the most out of code reviewsHow to get the most out of code reviews
How to get the most out of code reviews
JavaDayUA
 
Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8
JavaDayUA
 
Virtual Private Cloud with container technologies for DevOps
Virtual Private Cloud with container technologies for DevOpsVirtual Private Cloud with container technologies for DevOps
Virtual Private Cloud with container technologies for DevOps
JavaDayUA
 
JShell: An Interactive Shell for the Java Platform
JShell: An Interactive Shell for the Java PlatformJShell: An Interactive Shell for the Java Platform
JShell: An Interactive Shell for the Java Platform
JavaDayUA
 
Interactive Java Support to your tool -- The JShell API and Architecture
Interactive Java Support to your tool -- The JShell API and ArchitectureInteractive Java Support to your tool -- The JShell API and Architecture
Interactive Java Support to your tool -- The JShell API and Architecture
JavaDayUA
 
MapDB - taking Java collections to the next level
MapDB - taking Java collections to the next levelMapDB - taking Java collections to the next level
MapDB - taking Java collections to the next level
JavaDayUA
 
Save Java memory
Save Java memorySave Java memory
Save Java memory
JavaDayUA
 
Design rationales in the JRockit JVM
Design rationales in the JRockit JVMDesign rationales in the JRockit JVM
Design rationales in the JRockit JVM
JavaDayUA
 
Next-gen DevOps engineering with Docker and Kubernetes by Antons Kranga
Next-gen DevOps engineering with Docker and Kubernetes by Antons KrangaNext-gen DevOps engineering with Docker and Kubernetes by Antons Kranga
Next-gen DevOps engineering with Docker and Kubernetes by Antons Kranga
JavaDayUA
 
Apache Cassandra. Inception - all you need to know by Mikhail Dubkov
Apache Cassandra. Inception - all you need to know by Mikhail DubkovApache Cassandra. Inception - all you need to know by Mikhail Dubkov
Apache Cassandra. Inception - all you need to know by Mikhail Dubkov
JavaDayUA
 
Solution Architecture tips & tricks by Roman Shramkov
Solution Architecture tips & tricks by Roman ShramkovSolution Architecture tips & tricks by Roman Shramkov
Solution Architecture tips & tricks by Roman Shramkov
JavaDayUA
 
Testing in Legacy: from Rags to Riches by Taras Slipets
Testing in Legacy: from Rags to Riches by Taras SlipetsTesting in Legacy: from Rags to Riches by Taras Slipets
Testing in Legacy: from Rags to Riches by Taras Slipets
JavaDayUA
 
Reactive programming and Hystrix fault tolerance by Max Myslyvtsev
Reactive programming and Hystrix fault tolerance by Max MyslyvtsevReactive programming and Hystrix fault tolerance by Max Myslyvtsev
Reactive programming and Hystrix fault tolerance by Max Myslyvtsev
JavaDayUA
 
Spark-driven audience counting by Boris Trofimov
Spark-driven audience counting by Boris TrofimovSpark-driven audience counting by Boris Trofimov
Spark-driven audience counting by Boris Trofimov
JavaDayUA
 

More from JavaDayUA (20)

STEMing Kids: One workshop at a time
STEMing Kids: One workshop at a timeSTEMing Kids: One workshop at a time
STEMing Kids: One workshop at a time
 
Flavors of Concurrency in Java
Flavors of Concurrency in JavaFlavors of Concurrency in Java
Flavors of Concurrency in Java
 
What to expect from Java 9
What to expect from Java 9What to expect from Java 9
What to expect from Java 9
 
Continuously building, releasing and deploying software: The Revenge of the M...
Continuously building, releasing and deploying software: The Revenge of the M...Continuously building, releasing and deploying software: The Revenge of the M...
Continuously building, releasing and deploying software: The Revenge of the M...
 
The Epic Groovy Puzzlers S02: The Revenge of the Parentheses
The Epic Groovy Puzzlers S02: The Revenge of the ParenthesesThe Epic Groovy Puzzlers S02: The Revenge of the Parentheses
The Epic Groovy Puzzlers S02: The Revenge of the Parentheses
 
20 Years of Java
20 Years of Java20 Years of Java
20 Years of Java
 
How to get the most out of code reviews
How to get the most out of code reviewsHow to get the most out of code reviews
How to get the most out of code reviews
 
Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8Unlocking the Magic of Monads with Java 8
Unlocking the Magic of Monads with Java 8
 
Virtual Private Cloud with container technologies for DevOps
Virtual Private Cloud with container technologies for DevOpsVirtual Private Cloud with container technologies for DevOps
Virtual Private Cloud with container technologies for DevOps
 
JShell: An Interactive Shell for the Java Platform
JShell: An Interactive Shell for the Java PlatformJShell: An Interactive Shell for the Java Platform
JShell: An Interactive Shell for the Java Platform
 
Interactive Java Support to your tool -- The JShell API and Architecture
Interactive Java Support to your tool -- The JShell API and ArchitectureInteractive Java Support to your tool -- The JShell API and Architecture
Interactive Java Support to your tool -- The JShell API and Architecture
 
MapDB - taking Java collections to the next level
MapDB - taking Java collections to the next levelMapDB - taking Java collections to the next level
MapDB - taking Java collections to the next level
 
Save Java memory
Save Java memorySave Java memory
Save Java memory
 
Design rationales in the JRockit JVM
Design rationales in the JRockit JVMDesign rationales in the JRockit JVM
Design rationales in the JRockit JVM
 
Next-gen DevOps engineering with Docker and Kubernetes by Antons Kranga
Next-gen DevOps engineering with Docker and Kubernetes by Antons KrangaNext-gen DevOps engineering with Docker and Kubernetes by Antons Kranga
Next-gen DevOps engineering with Docker and Kubernetes by Antons Kranga
 
Apache Cassandra. Inception - all you need to know by Mikhail Dubkov
Apache Cassandra. Inception - all you need to know by Mikhail DubkovApache Cassandra. Inception - all you need to know by Mikhail Dubkov
Apache Cassandra. Inception - all you need to know by Mikhail Dubkov
 
Solution Architecture tips & tricks by Roman Shramkov
Solution Architecture tips & tricks by Roman ShramkovSolution Architecture tips & tricks by Roman Shramkov
Solution Architecture tips & tricks by Roman Shramkov
 
Testing in Legacy: from Rags to Riches by Taras Slipets
Testing in Legacy: from Rags to Riches by Taras SlipetsTesting in Legacy: from Rags to Riches by Taras Slipets
Testing in Legacy: from Rags to Riches by Taras Slipets
 
Reactive programming and Hystrix fault tolerance by Max Myslyvtsev
Reactive programming and Hystrix fault tolerance by Max MyslyvtsevReactive programming and Hystrix fault tolerance by Max Myslyvtsev
Reactive programming and Hystrix fault tolerance by Max Myslyvtsev
 
Spark-driven audience counting by Boris Trofimov
Spark-driven audience counting by Boris TrofimovSpark-driven audience counting by Boris Trofimov
Spark-driven audience counting by Boris Trofimov
 

Recently uploaded

FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
DianaGray10
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
Kari Kakkonen
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Product School
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
Sri Ambati
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
Fwdays
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Ramesh Iyer
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
Elena Simperl
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
Jemma Hussein Allen
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
Alison B. Lowndes
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
Abida Shariff
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
Product School
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Inflectra
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Thierry Lestable
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
Thijs Feryn
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
Bhaskar Mitra
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
Product School
 

Recently uploaded (20)

FIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdfFIDO Alliance Osaka Seminar: Overview.pdf
FIDO Alliance Osaka Seminar: Overview.pdf
 
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdfFIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
FIDO Alliance Osaka Seminar: Passkeys and the Road Ahead.pdf
 
UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3UiPath Test Automation using UiPath Test Suite series, part 3
UiPath Test Automation using UiPath Test Suite series, part 3
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 
DevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA ConnectDevOps and Testing slides at DASA Connect
DevOps and Testing slides at DASA Connect
 
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
Unsubscribed: Combat Subscription Fatigue With a Membership Mentality by Head...
 
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
GenAISummit 2024 May 28 Sri Ambati Keynote: AGI Belongs to The Community in O...
 
"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi"Impact of front-end architecture on development cost", Viktor Turskyi
"Impact of front-end architecture on development cost", Viktor Turskyi
 
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
Builder.ai Founder Sachin Dev Duggal's Strategic Approach to Create an Innova...
 
Knowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and backKnowledge engineering: from people to machines and back
Knowledge engineering: from people to machines and back
 
The Future of Platform Engineering
The Future of Platform EngineeringThe Future of Platform Engineering
The Future of Platform Engineering
 
Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........Bits & Pixels using AI for Good.........
Bits & Pixels using AI for Good.........
 
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptxIOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
IOS-PENTESTING-BEGINNERS-PRACTICAL-GUIDE-.pptx
 
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
From Daily Decisions to Bottom Line: Connecting Product Work to Revenue by VP...
 
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered QualitySoftware Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
Software Delivery At the Speed of AI: Inflectra Invests In AI-Powered Quality
 
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
Empowering NextGen Mobility via Large Action Model Infrastructure (LAMI): pav...
 
Accelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish CachingAccelerate your Kubernetes clusters with Varnish Caching
Accelerate your Kubernetes clusters with Varnish Caching
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
Search and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical FuturesSearch and Society: Reimagining Information Access for Radical Futures
Search and Society: Reimagining Information Access for Radical Futures
 
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
De-mystifying Zero to One: Design Informed Techniques for Greenfield Innovati...
 

API first with Swagger and Scala by Slava Schmidt

  • 1. API First with Play and Swagger
  • 8.
  • 9. •Autonomy •Small in size •Full responsibility •One or more components
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 22. API First Document and peer review API before writing a single line of code Ideally, generate either your server interfaces or your test data (or both) from the spec
  • 23.
  • 26. What is REST’s central distinguishing feature? … its emphasis on a uniform interface between components Roy Thomas Fielding remaining the same in all cases and at all times British Dictionary uniform
  • 27. How do we combine “same” and “changing” ?
  • 28. ???
  • 29. REST • Client-Server • Stateless • Cacheable • Layered System • Uniform Interface • Identification of resources • Manipulation of resources through these representations • Self-descriptive messages • Hypermedia as the engine of application state implementation details Server Client/Server Protocol
  • 31. Hexagonal Architecture The 1968/69 NATO Software Engineering Conference
  • 32. aka Ports and Adapters Chris Fidao https://www.youtube.com/watch?v=6SBjKOwVq0o
  • 36.
  • 38. DRY
  • 39. DRY Most people take DRY to mean you shouldn't duplicate code. That's not its intention. The idea behind DRY is far grander than that. DRY says that every piece of system knowledge should have one authoritative, unambiguous representation. Dave Thomas
  • 41. • Easy to use • Human readable • Widest adoption • Open Source • Scala and Java • Dynamic recompilation / Hot reload • Asynchronous IO • Easy to use
  • 42. • URI path definitions (supports parameterisation and templating) • URI parameter definitions • Response definitions • Scheme definitions • MIME type definitions • Primitive datatypes • Complex datatypes • Structural constraints • Value constraints • Security constraints • Tags • Vendor extensions
  • 43.
  • 46. DEMO
  • 50. Metadata swagger: "2.0"
 info:
 version: 1.0.0
 title: Swagger Petstore
 description: A sample API that uses a petstore as an example to demonstrate features in the swagger-2.0 specification
 termsOfService: http://swagger.io/terms/
 contact:
 name: Swagger API Team
 email: foo@example.com
 url: http://madskristensen.net
 license:
 name: MIT
 url: http://github.com/gruntjs/grunt/blob/master/LICENSE-MIT
 host: petstore.swagger.io
 basePath: /api
 schemes:
 - http
 consumes:
 - application/json
 produces:
 - application/json URL Prefix
  • 51. Definitions definitions:
 Pet:
 allOf:
 - $ref: '#/definitions/NewPet'
 - required:
 - id
 properties:
 id:
 type: integer
 format: int64
 NewPet:
 required:
 - name 
 properties:
 name:
 type: string
 tag:
 type: string 
 Error:
 required:
 - code
 - message
 properties:
 code:
 type: integer
 format: int32
 message:
 type: string object definitions {
 trait NewPetDef {
 def name: String
 def tag: Option[String]
 }
 case class Pet(
 id: Option[Long],
 name: String,
 tag: Option[String]
 ) extends NewPetDef
 case class NewPet(
 name: String,
 tag: Option[String]
 ) extends NewPetDef
 case class Error(
 code: Int,
 message: String
 )
 }
  • 52. Test data definitions:
 Pet:
 allOf:
 - $ref: '#/definitions/NewPet'
 - required:
 - id
 properties:
 id:
 type: integer
 format: int64
 NewPet:
 required:
 - name 
 properties:
 name:
 type: string
 tag:
 type: string 
 Error:
 required:
 - code
 - message
 properties:
 code:
 type: integer
 format: int32
 message:
 type: string object generatorDefinitions {
 
 def createPet = _generate(PetGenerator)
 def createNewPet = _generate(NewPetGenerator)
 def createError = _generate(ErrorGenerator)
 // test data generator for /definitions/Pet
 val PetGenerator =
 for {
 id <- Gen.option(arbitrary[Long])
 name <- arbitrary[String]
 tag <- Gen.option(arbitrary[String])
 } yield Pet(id, name, tag)
 // test data generator for /definitions/NewPet
 val NewPetGenerator =
 for {
 name <- arbitrary[String]
 tag <- Gen.option(arbitrary[String])
 } yield NewPet(name, tag)
 // test data generator for /definitions/Error
 val ErrorGenerator =
 for {
 code <- arbitrary[Int]
 message <- arbitrary[String]
 } yield Error(code, message)
 def _generate[T](gen: Gen[T]) = (count: Int) => for (i <- 1 to count) yield gen.sample
 }
  • 53. Validations'#/definitions/NewPet'
 red:
 rties:
 ype: integer
 ormat: int64
 
 s:
 string
 string 
 ge
 s:
 integer
 t: int32
 :
 string class PetValidation(instance: Pet) {
 import de.zalando.play.controllers.PlayValidations._
 val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]
 val result = {
 val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)
 if (errors.nonEmpty) Left(errors) else Right(instance)
 }
 }
 
 
 class NewPetValidation(instance: NewPet) {
 import de.zalando.play.controllers.PlayValidations._
 val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]
 val result = {
 val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)
 if (errors.nonEmpty) Left(errors) else Right(instance)
 }
 }
 
 
 class ErrorValidation(instance: Error) {
 import de.zalando.play.controllers.PlayValidations._
 val allValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]
 val result = {
 val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)
 if (errors.nonEmpty) Left(errors) else Right(instance)
 }
 }
  • 54. Validations /pets/{id}:
 get:
 description: Returns a user based on a single ID, if the user does not have access to the pet
 operationId: find pet by id
 parameters:
 - name: id
 in: path
 description: ID of pet to fetch
 required: true
 type: integer
 format: int64
 responses:
 200:
 description: pet response
 schema:
 $ref: '#/definitions/Pet'
 default:
 description: unexpected error
 schema:
 $ref: '#/definitions/Error' class ValidationForPetexpandedYamlfindPetById(in: (Long)) {
 val (id) = in
 
 val idConstraints = new ValidationBase[Long] {
 override def constraints: Seq[Constraint[Long]] = Seq()
 }
 
 val normalValidations = Seq(idConstraints.applyConstraints(id))
 
 val containerValidations = Seq.empty[scala.Either[scala.Seq[ParsingError], String]]
 
 val rightResult = Right((id))
 
 val allValidations = normalValidations ++ containerValidations
 
 val result = {
 val errors = allValidations.filter(_.isLeft).flatMap(_.left.get)
 if (errors.nonEmpty) Left(errors) else rightResult
 }
 }
  • 55. Tests "discard invalid data" in new WithApplication {
 val genInputs =
 for {
 id <- arbitrary[Long]
 } yield (id)
 val inputs = genInputs suchThat { i => new ValidationForPetexpandedYamlfindPetById(i).result != Right(i) }
 val props = forAll(inputs) { i => testInvalidInput(i) }
 checkResult(props)
 }
  • 56. Tests def testInvalidInput(in: (Long)) = {
 val (id) = in
 val url = s"""/api/pets/${id}"""
 val path = route(FakeRequest(GET, url)).get
 val validation = new ValidationForPetexpandedYamlfindPetById(id).result
 lazy val validations = validation.left.get flatMap {
 _.messages map { m => contentAsString(path).contains(m) ?= true }
 }
 ("given an URL: [" + url + "]") |: all(
 status(path) ?= BAD_REQUEST,
 contentType(path) ?= Some("application/json"),
 validation.isLeft ?= true,
 all(validations:_*)
 )
 }
  • 57. Controllers private val findPetByIdResponseMimeType = "application/json"
 private val findPetByIdActionSuccessStatus = Status(200)
 
 private type findPetByIdActionRequestType = (Long)
 private type findPetByIdActionResultType = Pet
 private type findPetByIdActionType = findPetByIdActionRequestType => Either[Throwable, findPetByIdActionResultType]
 
 private def errorToStatusfindPetById: PartialFunction[Throwable, Status] = PartialFunction.empty[Throwable, Status]
 
 def findPetByIdAction = (f: findPetByIdActionType) => (id: Long) => Action {
 val result = new ValidationForPetexpandedYamlfindPetById(id).result.right.map {
 processValidfindPetByIdRequest(f)
 }
 implicit val marshaller = parsingErrors2Writable(findPetByIdResponseMimeType)
 val response = result.left.map { BadRequest(_) }
 response.fold(a => a, c => c)
 }
 
 private def processValidfindPetByIdRequest(f: findPetByIdActionType)(request: findPetByIdActionRequestType) = {
 val callerResult = f(request)
 val status = callerResult match {
 case Left(error) => (errorToStatusfindPetById orElse defaultErrorMapping)(error)
 case Right(result) => findPetByIdActionSuccessStatus
 }
 implicit val findPetByIdWritableJson = anyToWritable[findPetByIdActionResultType](findPetByIdResponseMimeType)
 status(callerResult)
 }
  • 58. Skeletons class PetexpandedYaml extends PetexpandedYamlBase {
 
 // handler for GET /pets
 def findPets = findPetsAction { in : (Option[Seq[String]], Option[Int]) =>
 val (tags, limit) = in
 ???
 }
 
 // handler for POST /pets
 def addPet = addPetAction { in : (NewPet) =>
 val (pet) = in
 ???
 }
 
 // handler for GET /pets/{id}
 def findPetById = findPetByIdAction { in : (Long) =>
 val (id) = in
 ???
 }
 
 // handler for DELETE /pets/{id}
 def deletePet = deletePetAction { in : (Long) =>
 val (id) = in
 ???
 }
 }