/swagger-play-boostrap

Primary LanguageScalaApache License 2.0Apache-2.0

swagger-play-boostrap

The Wrong way to use Swagger within Play.

(hence the intentional typo in project name)

A very simple (rough, incomplete, etc.) tool to bootstrap some useful files for a Play application from a swagger.yaml file.

This is most likely the wrong way to integrate API-first (using Swagger) design into Play.

Usage

Service bootstrapping

Generation of code routes, controllers, case classes for all Definitions, with supporting Play-json Reads and Writes implicits, for a provided swagger API definition (in either JSON or YAML).

This code is generated for Play 2.4

$ sbt assembly
$ scala ~/code/github/swagger-play-boostrap/target/scala-2.11/swagger-play-boostrap-assembly-0.1-SNAPSHOT.jar
Error: Missing option --api
Error: Missing option --output-directory
Error: Swagger API must be specified as real/readable file
Usage: SwaggerCodeGenerator [options]

  --api <value>
        Swagger API specification (JSON or YAML)
  -o <value> | --output-directory <value>
        output directory
  --client
        specify that the client code should be generated (server code is generated by default)
  --replace
        specifies to replace existing sources - note currently ONLY AVAILABLE with -client
  --play23
        requests the generated code to be generated for play2.3  - note, this is currently ONLY AVAILABLE with -client, and is completely experimental
  --withdelegates
        request the generated server code use experimental 'delegate' workflow, where service author must implement 'logic.*' classes, etc.
  --fullplaystub
        generate a stub for a full play app, including SBT, configuration, etc.
  --healthcheck
        Include simple healthcheck support (server only)

Client Generation

This tool can also generate client code, which includes Clients to interact with resources, case classes for all Definitions, with supporting Play-json Reads and Writes implicits.

This generated code is built for, and tested with, Play 2.4. Unfortunately, this includes when using this generated client separately to a Play app (see below), due to various API signature changes in 2.4. That said, an experimental -play23 mode can be used to generate Play 2.3 client code - this is experimental and may be less tested than normal (2.4) generated code.

Use a trailing -client flag to generate client code instead:

$ scala target/scala-2.11/swagger-play-boostrap-assembly-0.1-SNAPSHOT.jar /path/to/swagger.yaml /path/to/generate/output -client

use a trailing -replace flag to generate code in-place over existing generated code - this will remove existing directory for the API being generated for, and recreate new code in its place (this is only supported for client code generation):

$ scala target/scala-2.11/swagger-play-boostrap-assembly-0.1-SNAPSHOT.jar /path/to/swagger.yaml /path/to/generate/output -client -replace

This generates client code similar to:

/path/to/generate/output/
└── clients
    └── lower_case_service_name
        ├── Client.scala
        ├── JsonOps.scala
        └── Models.scala
  • Models.scala contains generated case class instances for Swagger definitions.
  • JsonOps.scala contains implicit Play-Json (2.4) Reads and Writes (i.e. JSON marshalling/unmarshalling implicits)
  • Client.scala contains generated client abstractions. These clients use Play-WS (2.4) to interact with the remote REST service in a non-blocking manner. Note, this generated code also has a dependency on Scalaz, e.g.
libraryDendenencies += "org.scalaz" %% "scalaz-core" % "7.1.3"

Using this client external to a Play application

While this client uses Play-WS to do REST calls, and it is configured by default to use the existing/running application for these WS interactions, it is possible to use this client in a non-Play application.

This can be done by creating, and providing, a separate play.api.libs.ws.WSClient when constructing the instance of the Client.

for example,

val wsClient = {
	val builder = new com.ning.http.client.AsyncHttpClientConfig.Builder()
	new play.api.libs.ws.ning.NingWSClient(builder.build())
}

val client = new ClientImpl("http://localhost:9000", wsClient = wsClient)

Notes

  • path for generated output is created, and must not already exist (support for merging into existing code is not supported)
  • there is limited support for types of parameters, etc. (incomplete code in this tool currently)
  • (Very) Incomplete support for Swagger specification - tool still WIP, (mostly) works for some simple test APIs run through it)