Coder Social home page Coder Social logo

play-swagger's Introduction

Swagger API spec generator for Play

A library that generates swagger specs from route files and case class reflection, no code annotation needed.

This repository is no longer maintained. Please find the new repository here: https://github.com/play-swagger/play-swagger

About the Migration

This project has been migrated to a new repository in July 2023 due to a change in administration.

The development and maintenance of the project are being continued on the new repository.

While this repository is left for reference, please refer to the new repository for the most up-to-date code and information.

https://github.com/play-swagger/play-swagger

Get Started

For play 2.8, Scala 2.13.x and Scala 2.12.x please use

addSbtPlugin("io.github.play-swagger" % "sbt-play-swagger" % "1.2.3")

play-swagger's People

Contributors

aafa avatar asan avatar asdcdow avatar bpiper avatar canyaman avatar esplo avatar gabfssilva avatar guizmaii avatar javakky-pxv avatar joprice avatar kailuowang avatar kbedel avatar mihaisoloi avatar mosche avatar nezisi avatar paul-lysak avatar russwyte avatar sangeetagulia avatar sattailanfear avatar scala-steward avatar sergiuszkierat avatar starou avatar sullis avatar tculshaw avatar tilmanginzel avatar tudorv91 avatar voukka avatar williamho avatar wlk avatar wwbakker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

play-swagger's Issues

$ref generates -Xlint warnings

It is valid to have a build fail on warnings, especially those generated by -Xlint.

However, $ref generates a warning and we either then have to:

  • turn off missing-parameter, e.g. -Xlint:missing-parameter OR
  • remove -Xfatal-warnings

Can we move to a different mechanism of determining references to classes or model types? Happy to contribute if you agree.

Thanks

Issue with java.util.Date and scala Map

I am having issues with case classes that contain Date and scala Map. These show up as entities which are then not able to be read by Swagger CodeGen. How do I handle these types? Below is the model that is being created

metaData (collection.immutable.map[string,string]),
createdAt (java.util.date),

Wrong format for schema entity

Hello,

I have a basic form,

 case class SearchForm(name: Option[String], city: Option[String], limit: Option[Int], offset: Option[Int])

it's referenced in routes like that

### 
#  parameters:
#    - name: body
#      schema:
#        $ref: '#/definitions/models.entities.SearchForm'
###

the generated json is

"models.entities.SearchForm":{  
         "properties":{  
            "name":{  
               "type":"string",
               "required":false
            },
            "city":{  
               "type":"string",
               "required":false
            },
            "limit":{  
               "type":"integer",
               "format":"int32",
               "required":false
            },
            "offset":{  
               "type":"integer",
               "format":"int32",
               "required":false
            }
         },
         "required":[  ]
      }

The swagger validator (http://online.swagger.io/validator/debug?url=http://your-json-url) tell me that

  • the "required":false should not exist
  • "required":[ ] should not be empty.

Scala 2.10 support

Looks like this project was bootstrapped with Scala 2.11 (0d90b32#diff-fdc3abdfd754eeb24090dbd90aeec2ceR6). Has anyone been successful with Scala 2.10 and Play 2.3.9?

This is the exception I am currently facing:

ERROR application:147 - 

! @70pikjjf5 - Internal server error, for (GET) [/] ->

@70pikjjf5: Unexpected exception
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:170)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:130)
    at scala.Option.map(Option.scala:146)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:130)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:128)
    at scala.util.Success.flatMap(Try.scala:231)
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:128)
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:120)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.NoSuchMethodError: scala.collection.immutable.HashSet$.empty()Lscala/collection/immutable/HashSet;
    at akka.actor.ActorCell$.<init>(ActorCell.scala:336)
    at akka.actor.ActorCell$.<clinit>(ActorCell.scala)
    at akka.actor.RootActorPath.$div(ActorPath.scala:159)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:464)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:452)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$2.apply(DynamicAccess.scala:78)
    at scala.util.Try$.apply(Try.scala:192)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:73)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at scala.util.Success.flatMap(Try.scala:231)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:84)
    at akka.actor.ActorSystemImpl.liftedTree1$1(ActorSystem.scala:584)
    at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:577)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:141)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:125)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:20)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:19)
    at scala.Option.map(Option.scala:146)
    at play.core.Invoker$$anon$1.create(Invoker.scala:19)
    at play.core.ClosableLazy.get(ClosableLazy.scala:51)
    at play.core.Invoker$.system(Invoker.scala:40)
    at play.core.Invoker$.executionContext(Invoker.scala:41)
    at play.api.libs.concurrent.Execution$.defaultContext(Execution.scala:15)
    at play.api.libs.concurrent.Execution$Implicits$.defaultContext(Execution.scala:12)
    at util.Prefetch$.onStart(Prefetch.scala:15)
    at Global$.onStart(Global.scala:14)
    at play.api.GlobalPlugin.onStart(GlobalSettings.scala:220)
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:91)
    at play.api.Play$$anonfun$start$1.apply(Play.scala:91)
    at play.api.Play$$anonfun$start$1.apply(Play.scala:91)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
    at play.api.Play$.start(Play.scala:90)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:157)
    ... 14 more
2016-07-29 01:24:57 ERROR nettyException:147 - Exception caught in Netty
java.lang.NoClassDefFoundError: Could not initialize class akka.actor.ActorCell$
    at akka.actor.RootActorPath.$div(ActorPath.scala:159)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:464)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:452)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$2.apply(DynamicAccess.scala:78)
    at scala.util.Try$.apply(Try.scala:192)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:73)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at scala.util.Success.flatMap(Try.scala:231)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:84)
    at akka.actor.ActorSystemImpl.liftedTree1$1(ActorSystem.scala:584)
    at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:577)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:141)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:125)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:20)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:19)
    at scala.Option.map(Option.scala:146)
    at play.core.Invoker$$anon$1.create(Invoker.scala:19)
    at play.core.ClosableLazy.get(ClosableLazy.scala:51)
    at play.core.Invoker$.system(Invoker.scala:40)
    at play.core.Invoker$.executionContext(Invoker.scala:41)
    at play.api.libs.concurrent.Execution$.defaultContext(Execution.scala:15)
    at play.core.server.netty.PlayDefaultUpstreamHandler.play$core$server$netty$PlayDefaultUpstreamHandler$$handleAction$1(PlayDefaultUpstreamHandler.scala:253)
    at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:245)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at com.typesafe.netty.http.pipelining.HttpPipeliningHandler.messageReceived(HttpPipeliningHandler.java:62)
    at org.jboss.netty.channel.SimpleChannelHandler.handleUpstream(SimpleChannelHandler.java:88)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:108)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:485)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108)
    at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
    at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
    at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
2016-07-29 01:24:58 ERROR application:147 - 

! @70pikjjf5 - Internal server error, for (GET) [/] ->

@70pikjjf5: Unexpected exception
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:170)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:130)
    at scala.Option.map(Option.scala:146)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:130)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:128)
    at scala.util.Success.flatMap(Try.scala:231)
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:128)
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:120)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.NoSuchMethodError: scala.collection.immutable.HashSet$.empty()Lscala/collection/immutable/HashSet;
    at akka.actor.ActorCell$.<init>(ActorCell.scala:336)
    at akka.actor.ActorCell$.<clinit>(ActorCell.scala)
    at akka.actor.RootActorPath.$div(ActorPath.scala:159)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:464)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:452)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$2.apply(DynamicAccess.scala:78)
    at scala.util.Try$.apply(Try.scala:192)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:73)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at scala.util.Success.flatMap(Try.scala:231)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:84)
    at akka.actor.ActorSystemImpl.liftedTree1$1(ActorSystem.scala:584)
    at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:577)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:141)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:125)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:20)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:19)
    at scala.Option.map(Option.scala:146)
    at play.core.Invoker$$anon$1.create(Invoker.scala:19)
    at play.core.ClosableLazy.get(ClosableLazy.scala:51)
    at play.core.Invoker$.system(Invoker.scala:40)
    at play.core.Invoker$.executionContext(Invoker.scala:41)
    at play.api.libs.concurrent.Execution$.defaultContext(Execution.scala:15)
    at play.api.libs.concurrent.Execution$Implicits$.defaultContext(Execution.scala:12)
    at util.Prefetch$.onStart(Prefetch.scala:15)
    at Global$.onStart(Global.scala:14)
    at play.api.GlobalPlugin.onStart(GlobalSettings.scala:220)
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:91)
    at play.api.Play$$anonfun$start$1.apply(Play.scala:91)
    at play.api.Play$$anonfun$start$1.apply(Play.scala:91)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
    at play.api.Play$.start(Play.scala:90)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:157)
    ... 14 more
2016-07-29 01:24:58 ERROR nettyException:147 - Exception caught in Netty
java.lang.NoClassDefFoundError: Could not initialize class akka.actor.ActorCell$
    at akka.actor.RootActorPath.$div(ActorPath.scala:159)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:464)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:452)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$2.apply(DynamicAccess.scala:78)
    at scala.util.Try$.apply(Try.scala:192)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:73)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at scala.util.Success.flatMap(Try.scala:231)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:84)
    at akka.actor.ActorSystemImpl.liftedTree1$1(ActorSystem.scala:584)
    at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:577)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:141)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:125)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:20)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:19)
    at scala.Option.map(Option.scala:146)
    at play.core.Invoker$$anon$1.create(Invoker.scala:19)
    at play.core.ClosableLazy.get(ClosableLazy.scala:51)
    at play.core.Invoker$.system(Invoker.scala:40)
    at play.core.Invoker$.executionContext(Invoker.scala:41)
    at play.api.libs.concurrent.Execution$.defaultContext(Execution.scala:15)
    at play.core.server.netty.PlayDefaultUpstreamHandler.play$core$server$netty$PlayDefaultUpstreamHandler$$handleAction$1(PlayDefaultUpstreamHandler.scala:253)
    at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:245)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at com.typesafe.netty.http.pipelining.HttpPipeliningHandler.messageReceived(HttpPipeliningHandler.java:62)
    at org.jboss.netty.channel.SimpleChannelHandler.handleUpstream(SimpleChannelHandler.java:88)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:108)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:485)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108)
    at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
    at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
    at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
2016-07-29 01:24:58 ERROR application:147 - 

! @70pikjjf5 - Internal server error, for (GET) [/] ->

@70pikjjf5: Unexpected exception
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:170)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:130)
    at scala.Option.map(Option.scala:146)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:130)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1.apply(ApplicationProvider.scala:128)
    at scala.util.Success.flatMap(Try.scala:231)
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:128)
    at play.core.ReloadableApplication$$anonfun$get$1.apply(ApplicationProvider.scala:120)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.liftedTree1$1(Future.scala:24)
    at scala.concurrent.impl.Future$PromiseCompletingRunnable.run(Future.scala:24)
    at scala.concurrent.forkjoin.ForkJoinTask$AdaptedRunnableAction.exec(ForkJoinTask.java:1361)
    at scala.concurrent.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
    at scala.concurrent.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
    at scala.concurrent.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
    at scala.concurrent.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
Caused by: java.lang.NoSuchMethodError: scala.collection.immutable.HashSet$.empty()Lscala/collection/immutable/HashSet;
    at akka.actor.ActorCell$.<init>(ActorCell.scala:336)
    at akka.actor.ActorCell$.<clinit>(ActorCell.scala)
    at akka.actor.RootActorPath.$div(ActorPath.scala:159)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:464)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:452)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$2.apply(DynamicAccess.scala:78)
    at scala.util.Try$.apply(Try.scala:192)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:73)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at scala.util.Success.flatMap(Try.scala:231)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:84)
    at akka.actor.ActorSystemImpl.liftedTree1$1(ActorSystem.scala:584)
    at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:577)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:141)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:125)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:20)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:19)
    at scala.Option.map(Option.scala:146)
    at play.core.Invoker$$anon$1.create(Invoker.scala:19)
    at play.core.ClosableLazy.get(ClosableLazy.scala:51)
    at play.core.Invoker$.system(Invoker.scala:40)
    at play.core.Invoker$.executionContext(Invoker.scala:41)
    at play.api.libs.concurrent.Execution$.defaultContext(Execution.scala:15)
    at play.api.libs.concurrent.Execution$Implicits$.defaultContext(Execution.scala:12)
    at util.Prefetch$.onStart(Prefetch.scala:15)
    at Global$.onStart(Global.scala:14)
    at play.api.GlobalPlugin.onStart(GlobalSettings.scala:220)
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
    at play.api.Play$$anonfun$start$1$$anonfun$apply$mcV$sp$1.apply(Play.scala:91)
    at scala.collection.immutable.List.foreach(List.scala:381)
    at play.api.Play$$anonfun$start$1.apply$mcV$sp(Play.scala:91)
    at play.api.Play$$anonfun$start$1.apply(Play.scala:91)
    at play.api.Play$$anonfun$start$1.apply(Play.scala:91)
    at play.utils.Threads$.withContextClassLoader(Threads.scala:21)
    at play.api.Play$.start(Play.scala:90)
    at play.core.ReloadableApplication$$anonfun$get$1$$anonfun$apply$1$$anonfun$1.apply(ApplicationProvider.scala:157)
    ... 14 more
2016-07-29 01:24:58 ERROR nettyException:147 - Exception caught in Netty
java.lang.NoClassDefFoundError: Could not initialize class akka.actor.ActorCell$
    at akka.actor.RootActorPath.$div(ActorPath.scala:159)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:464)
    at akka.actor.LocalActorRefProvider.<init>(ActorRefProvider.scala:452)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:422)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$2.apply(DynamicAccess.scala:78)
    at scala.util.Try$.apply(Try.scala:192)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:73)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at akka.actor.ReflectiveDynamicAccess$$anonfun$createInstanceFor$3.apply(DynamicAccess.scala:84)
    at scala.util.Success.flatMap(Try.scala:231)
    at akka.actor.ReflectiveDynamicAccess.createInstanceFor(DynamicAccess.scala:84)
    at akka.actor.ActorSystemImpl.liftedTree1$1(ActorSystem.scala:584)
    at akka.actor.ActorSystemImpl.<init>(ActorSystem.scala:577)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:141)
    at akka.actor.ActorSystem$.apply(ActorSystem.scala:125)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:20)
    at play.core.Invoker$$anon$1$$anonfun$2.apply(Invoker.scala:19)
    at scala.Option.map(Option.scala:146)
    at play.core.Invoker$$anon$1.create(Invoker.scala:19)
    at play.core.ClosableLazy.get(ClosableLazy.scala:51)
    at play.core.Invoker$.system(Invoker.scala:40)
    at play.core.Invoker$.executionContext(Invoker.scala:41)
    at play.api.libs.concurrent.Execution$.defaultContext(Execution.scala:15)
    at play.core.server.netty.PlayDefaultUpstreamHandler.play$core$server$netty$PlayDefaultUpstreamHandler$$handleAction$1(PlayDefaultUpstreamHandler.scala:253)
    at play.core.server.netty.PlayDefaultUpstreamHandler.messageReceived(PlayDefaultUpstreamHandler.scala:245)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at com.typesafe.netty.http.pipelining.HttpPipeliningHandler.messageReceived(HttpPipeliningHandler.java:62)
    at org.jboss.netty.channel.SimpleChannelHandler.handleUpstream(SimpleChannelHandler.java:88)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:108)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline$DefaultChannelHandlerContext.sendUpstream(DefaultChannelPipeline.java:791)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:296)
    at org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:459)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:536)
    at org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:485)
    at org.jboss.netty.channel.SimpleChannelUpstreamHandler.handleUpstream(SimpleChannelUpstreamHandler.java:70)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:564)
    at org.jboss.netty.channel.DefaultChannelPipeline.sendUpstream(DefaultChannelPipeline.java:559)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:268)
    at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:255)
    at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:88)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.process(AbstractNioWorker.java:108)
    at org.jboss.netty.channel.socket.nio.AbstractNioSelector.run(AbstractNioSelector.java:337)
    at org.jboss.netty.channel.socket.nio.AbstractNioWorker.run(AbstractNioWorker.java:89)
    at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:178)
    at org.jboss.netty.util.ThreadRenamingRunnable.run(ThreadRenamingRunnable.java:108)
    at org.jboss.netty.util.internal.DeadLockProofWorker$1.run(DeadLockProofWorker.java:42)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)

Check `play.http.router` configuration value before assuming `routes` as a root file for routes

My configuration says:

play.http.router=api.Routes

Fetching swagger json file fails because routes file does not exist on path of my application. Relevant stacktrace:

java.lang.NullPointerException
    at java.io.Reader.<init>(Reader.java:78)
    at java.io.InputStreamReader.<init>(InputStreamReader.java:129)
    at scala.io.BufferedSource.reader(BufferedSource.scala:24)
    at scala.io.BufferedSource.bufferedReader(BufferedSource.scala:25)
    at scala.io.BufferedSource.scala$io$BufferedSource$$charReader$lzycompute(BufferedSource.scala:35)
    at scala.io.BufferedSource.scala$io$BufferedSource$$charReader(BufferedSource.scala:33)
    at scala.io.BufferedSource.scala$io$BufferedSource$$decachedReader(BufferedSource.scala:62)
    at scala.io.BufferedSource$BufferedLineIterator.<init>(BufferedSource.scala:67)
    at scala.io.BufferedSource.getLines(BufferedSource.scala:86)
    at com.iheart.playSwagger.ResourceReader$.read(ResourceReader.scala:11)
    at com.iheart.playSwagger.ResourceReader$.read(ResourceReader.scala:7)
    at com.iheart.playSwagger.RoutesFileReader.com$iheart$playSwagger$RoutesFileReader$$readRoutes(RoutesFileReader.scala:17)
    at com.iheart.playSwagger.RoutesFileReader.readAll(RoutesFileReader.scala:7)
    at com.iheart.playSwagger.SwaggerSpecGenerator.generate(SwaggerSpecGenerator.scala:62)

Workaround is to put routes file in the conf directory with:

-> / api.Routes

Getting "null" in response definition

First, great project, many thanks for your work!

In my routes I have comments as follows:

description: get the default module description
summary: default module
responses:
200:
description: success
schema:
$ref: '#/definitions/models.Protocol.ModuleDef'

(#'s removed to keep formatting sort of normal)

In the resultant swagger.json I get:

"/":{ "get":{ "tags":[ "routes" ], "summary":"default module", "description":"get the default module description", "responses":null, "200":{ "description":"Modules definition", "schema":{ "$ref":"#/definitions/models.Protocol.ModuleDef" } },....

Note the "null" instead of the JSON object start for the response. The object that is being referenced is included in the definitions so it's not a case of a broken reference.

I'm running Play 2.5 but get the same result with 2.4.6. Build is using 0.2.0 not the 0.2.1 Play 2.5 specific version since that is currently throwing JSLookup errors when I try to use it instead.

Parse definitions in route files

It would be nice to parse definitions in route files in the form like below:

###
# definitions:
# LoginRequest:
# type: object
# required:
# - certificate
# properties:
# certificate:
# $ref: '#/definitions/Certificate'
# LoginResponse:
# type: object
# required:
# - token
# properties:
# token:
# $ref: '#/definitions/Token'
play-swagger is being used also in Java projects where we don't have case classes so it'd be nice to allow definitions parsing.

Do you plan to support it? If yes when?

Paths ordering

Generated JSON paths is in reverse order compared to ones defined in routes file

Stuck at fetching resource list: http://localhost:9000/docs/swagger.json; Please wait.

I am a newbie to swagger and i am stuck after doing the following things on an error:
I am using the following dependencies:

"com.iheart" %% "play-swagger" % "0.2.1-PLAY2.5",
"org.webjars" % "swagger-ui" % "2.1.4"

Following are the routes:
image

Following is the expected response type:
case class Output(response: JsValue)

This is the screenshot of where i am getting struck:

image

This is what i get in the auto generated json file(where it gets struck with error : fetching resource list):

{"paths":{"/assets/{file}":{"get":{"tags":["routes"],"parameters":[{"name":"path","type":"string","required":true,"in":"query"},{"name":"file","type":"asset","required":true,"in":"path"}]}},"/docs/swagger.json":{"get":{"tags":["routes"],"summary":"swagger definition","description":"for swagger UI to consume"}},"/client/view":{"get":{"tags":["routes"],"responses":{"200":{"description":"success","schema":{"$ref":"#/definitions/models.Output"}}}}}},"definitions":{"models.Output":{"properties":{"response":{"type":"play.api.libs.json.jsvalue","required":true}},"required":["response"]}},"tags":[{"name":"routes"}]}

and this is my default swagger.json file(which i have created) :
{
"swagger": "2.0",
"info": {
"version": "1.0.0",
"title": "Weather API",
"description": "A sample API that uses a Mashape weather API as an example to demonstrate features in the swagger-2.0 specification",
"termsOfService": "http://helloreverb.com/terms/",
"contact": {
"name": "Tom Johnson",
"email": "[email protected]",
"url": "localhost:9000"
},
"license": {
"name": "MIT",
"url": "http://opensource.org/licenses/MIT"
}
},
"host": "localhost:9000",
"basePath" : "localhost:9000",
"schemes": [
"https"
],
"consumes": [
"application/json"
],
"produces": [
"application/text"
]
}

default tag "routes" is confusing

if there is no include, all the endpoints got a tag "routes" and will be collapsed when swagger UI loads. This is a bit confusing.

Array "items" gets "type" even if "items" contains a manual $ref

I have

###
#   summary: Retrieves the public data from multiple user id's at once.
#   parameters:
#     - name: id
#       type: array
#       in: query
#       items:
#         $ref: '#/definitions/bsonObjectId'
#       collectionFormat: multi
#   responses:
#     200:
#       description: A list of all the locatable users that were requested, up to once per unique id.
###
GET     /multi            controllers.UserController.getMultiple(id: Seq[BSONObjectID])

The output:

{
  "/user/multi": {
    "get": {
      "tags": [
        "user"
      ],
      "summary": "Retrieves the public data from multiple user id's at once.",
      "parameters": [
        {
          "name": "id",
          "type": "array",
          "required": true,
          "items": {
            "type": "bsonobjectid",
            "$ref": "#/definitions/bsonObjectId"
          },
          "in": "query",
          "description": "The User ID's to look up.",
          "collectionFormat": "multi"
        }
      ],
      "responses": {
        "200": {
          "description": "A list of all the locatable users that were requested, up to once per unique id."
        }
      }
    }
  }
}

"/user/multi"/get/parameters/0/items should not contain "type"

Can it use the defined Reads and Writes for Json generation

  1. The json that is emitted out is actually not matching the custom Writes that has been defined. I'm not sure if the play Formats are being used for Json generation
  2. The Json generation fails for the class Consumer below as it uses the trait.

sealed trait ValueType
object Mobile extends ValueType

case class Consumer(root: String, users: Map[String, User], valueType: ValueType = Mobile)

Automatic body parameters

I'm fairly sure this isn't supported since it doesn't seem to happen automatically and I didn't see anything in the code that would handle it, but before working on a pull request I wanted to confirm that play-swagger should not automatically generate documentation for body parameters.

For example:

def test = Action(parse.json[TestResource]) { implicit request => Ok }

with no extra documentation in the routes file:

POST /test controllers.ApplicationController.test

Does not generate the body parameter automatically:

"/test":{"post":{"tags":["routes"],"parameters":[{"name":"body","schema":{"$ref":"#/definitions/org.example.project.TestResource"},"in":"body"}],"consumes":["application/json"]}}

I feel like that would be possible to do automatically with reflection - would that fit the vision of the project?

It'd also be nice if we could do this with return parameters, although i'm not sure how feasible that would be at runtime.

Routes with multiple regexes

Given a route with regex syntax like:

GET   /dice/$count<\d+>d$sides<\d+>   controllers.Example.getDice(sides: Int, count: Int)

when I make a request through the swagger UI, it makes the GET request to a URL like: /dice/{count}d6?count=3 (with the literal {count} string)

expected: /dice/3d6

Interestingly, the 6 (for $sides) was passed correctly.

List[Int] property causes error.

[ERROR] [10/02/2015 14:40:39.519] [application-akka.actor.default-dispatcher-17] [akka.actor.ActorSystemImpl(application)] Error when handling GET:/inter
nal/docs/swagger.json:  class Int not found. - scala.ScalaReflectionException: class Int not found.
        at scala.reflect.internal.Mirrors$RootsBase.staticClass(Mirrors.scala:123)
        at scala.reflect.internal.Mirrors$RootsBase.staticClass(Mirrors.scala:22)
        at com.iheart.playSwagger.DefinitionGenerator.definition(DefinitionGenerator.scala:31)
        at com.iheart.playSwagger.DefinitionGenerator.com$iheart$playSwagger$DefinitionGenerator$$allRefferdDefs$1(DefinitionGenerator.scala:42)
        at com.iheart.playSwagger.DefinitionGenerator$$anonfun$com$iheart$playSwagger$DefinitionGenerator$$allRefferdDefs$1$1.apply(DefinitionGenerator.scala:48)                                             
        at com.iheart.playSwagger.DefinitionGenerator$$anonfun$com$iheart$playSwagger$DefinitionGenerator$$allRefferdDefs$1$1.apply(DefinitionGenerator.scala:47)
        at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:124)
        at scala.collection.immutable.List.foldLeft(List.scala:84)
        at com.iheart.playSwagger.DefinitionGenerator.com$iheart$playSwagger$DefinitionGenerator$$allRefferdDefs$1(DefinitionGenerator.scala:47)
        at com.iheart.playSwagger.DefinitionGenerator$$anonfun$allDefinitions$1.apply(DefinitionGenerator.scala:54)
        at com.iheart.playSwagger.DefinitionGenerator$$anonfun$allDefinitions$1.apply(DefinitionGenerator.scala:53)
        at scala.collection.LinearSeqOptimized$class.foldLeft(LinearSeqOptimized.scala:124)
        at scala.collection.immutable.List.foldLeft(List.scala:84)

Play 2.5 support

Things seems to break with Play 2.5 at runtime:

java.lang.NoSuchMethodError: play.api.libs.json.JsLookup$.$bslash$extension(Lplay/api/libs/json/JsLookupResult;Ljava/lang/String;)Lplay/api/libs/json/JsLookupResult;
com.iheart.playSwagger.SwaggerSpecGenerator$$anonfun$32.apply(SwaggerSpecGenerator.scala:292)
com.iheart.playSwagger.SwaggerSpecGenerator$$anonfun$32.apply(SwaggerSpecGenerator.scala:292)
scala.Option.flatMap(Option.scala:171)
com.iheart.playSwagger.SwaggerSpecGenerator.endPointSpec(SwaggerSpecGenerator.scala:292)

Play-Swagger integrations

Awesome to see a Play-Swagger integration. It's something I'm really interested in at the moment and I've been trying to figure out the best way to do it.

I just added your project on the swagger-api/swagger-play README, so that others can find your project. We've been working on fixing up swagger-api/swagger-play so that it runs with Swagger 2.0 and Play 2.4, but I wasn't aware of your effort.

A few thoughts I had...

  • We do routes file parsing in our PR. We just copied the Play routes parser into our code, but the Play guys created a PR to make it into a library we can use. Thought you'd be interested: playframework/playframework#5291
  • Is there a reason you chose adding comments to the routes file instead of generating the routes from the Swagger spec? There's another project that has code for that. I'm thinking that might make it easy to run the spec though a validator if it's a stand-alone spec vs mixed in the routes syntax. Thinking about different possible approaches here...
  • Does this only work with Scala case classes? I use Java and I'm wondering if it'll work with POJOs

Thanks for open sourcing this guys!

Enhancement: Allow defining path/query-bound datatypes

Several of my endpoints take nontrivial datatypes in from the route file, for example BSONObjectID.

I know that type is a string with a particular pattern and length, and could define it, but when swagger-generator encounters it it uses the illegal type value "bsonobjectid".

As a first-step, assuming string for unknown types may be better than an illegal value.

Does it work with play-java?

Hello,

This is very good work. Does this work with Play-Java?

I ask because I notice the use of case classes for the definitions...

Thank you.

Custom model schema definition

When generating model schema for third-party types like org.joda.time.Datetime play-swagger generates the data-type correctly but it won't show up in Model Schema (JSON preview) in Swagger-UI.

Is it possible to define these types in somewhere like swagger.yml.

There are other situation which we need to define our type description manually. For example suppose the following object:

object ProgressStatus {
  type Type = String

  val Done = "done"
  val InPorgress = "inProgress"
}

Which we used like an Enumeration:

case class MyModel(status: ProgressStatus.Type)

I want to define ProgressStatus.Type manually and describe about it's valid values.

sbt / build support to generate static swagger json

Hey,
thanks a lot for this project! Absolutely the approach I like best so far as it reduces the coupling between swagger and the actual play app :)

I looked a bit into the open PR using macros at compile time and was wondering if you are still looking into compile time generation? Generating a static swagger doc without having any runtime dependency would be great to have.

An easier way could be to include a small runnable main class in the artifact and leverage that from sbt. Below is a quick & dirty example how to get it it integrated. However, going that way, it may make sense to turn the project into a multi-project build and build an sbt-plugin with it. I'm happy to work on a PR, but was wondering what your thoughts / preferences are?

Regards, Moritz

object Swagger extends App {
  implicit def cl = getClass.getClassLoader

  private def fileArg = Paths.get(args.head)
  private def domainNameSpaceArgs = args.tail
  private def swaggerJson = SwaggerSpecGenerator(domainNameSpaceArgs: _*).generate().get.toString

  Files.write(fileArg, swaggerJson.getBytes, StandardOpenOption.CREATE, StandardOpenOption.WRITE)
}

And finally generating the swagger.json from sbt and packaging it using a Plugin:

object SwaggerPlugin extends AutoPlugin {
  private[this] val swaggerConfig = config("play-swagger").hide

  object autoImport extends SwaggerKeys

  override def requires = PlayScala

  override def trigger = noTrigger

  import autoImport._

  override def projectSettings: Seq[Setting[_]] = Seq(
    ivyConfigurations += swaggerConfig,
    libraryDependencies += "com.iheart" %% "play-swagger" % "0.3.3-SNAPSHOT" % swaggerConfig,
    swaggerDomainNameSpaces := Seq(),
    swaggerTarget := "public/swagger.json",
    swagger <<= Def.task[File] {
      (target.value / "swagger").mkdirs()
      val file = target.value / "swagger" / "swagger.json"
      val args = file.absolutePath +: swaggerDomainNameSpaces.value
      val swaggerClasspath = data((fullClasspath in Runtime).value) ++ update.value.select(configurationFilter(swaggerConfig.name))
      runner.value.run("swagger.Swagger", swaggerClasspath, args, streams.value.log)
      file
    },
    mappings in (Compile, packageBin) += (target.value / "swagger" / "swagger.json") -> swaggerTarget.value,
    packageBin in Universal <<= (packageBin in Universal).dependsOn(swagger)
  )
}

trait SwaggerKeys {
  val swagger = TaskKey[File]("swagger", "generate the swagger API documentation")
  val swaggerDomainNameSpaces = SettingKey[Seq[String]]("swaggerDomainNameSpaces", "swagger domain namespaces for model classes")
  val swaggerTarget = SettingKey[String]("swaggerTarget", "the location of the swagger documentation")
}

how to define a list schema using case class

I want to define a schema $ref using case class like this

[
  {"key": "value"},
  ...
]

where I defined a case class for the key-value pair like

case class keyVal(key: String)

but I cannot figure out how to define a case class to generate the above definitions, because it will end up with something like this

{
  "whateverFieldName": [
    {"key": "value"},
    ...
  ]
}

because it seems i can only define it like

case class ListOfKeyVal(whateverFieldName: List[KeyVal])

using argonaut serialisation?

If we use argonaut as our json library are we out of luck with automatic schema generation or is there a way to make the plugin aware of that?

Model schema doesn't display some fields of unknown type

if I have a case class like one of the following:

case class MyClass(a: String, b: Any)
case class MyOtherClass[T](a: String, b: T)

and use it as the schema's $ref, the Model Schema generated by the docs will look like:

{
  "a": "string"
}

and b doesn't show up at all, presumably because it doesn't know about the type.

Generate YAML

Is it possible to generate YAML instead of JSON ?

Unable To Reference Custom Parameter Definitions

I have a base "swagger.yml" defined as:

swagger: 2.0
info:
  title: V API
  description: MyServer
  version: 0.7.5
host: "XXX"
schemes:
  - "http"
  - "https"
consumes:
  - "application/json"
produces:
  - "application/json"
parameters:
  domain:
    name: "X-VirtualDomain"
    in: header
    description: The domain (account) you're attempting to interact with.
    required: true
    type: string

When I try to reference the parameter, I get JSON errors.

###
#   summary: does initial signup for credentials
#   produces:
#     - application/json
#   parameters:
#     - $ref: "#/parameters/domain"
#     - name: email
#       in: body
#       description: The email address to associate with the new account.
#       required: true
#       type: string
#       format: email
#     - name: password
#       in: body
#       description: The password for the new account.
#       required: true
#       type: password
#   responses:
#     200:
#       description: User Created
#       schema:
#         headers:
#           X-Auth-Token:
#             description: An auth token issued to this user
#             type: string
#
#
###
POST    /signup                                    controllers.rest.CredentialsController.signUp


play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[JsResultException: JsResultException(errors:List((,List(ValidationError(List('name' is undefined on object: {"$ref":"#/parameters/domain"}),WrappedArray())))))]]
        at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:280)
        at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:206)
        at play.api.GlobalSettings$class.onError(GlobalSettings.scala:160)
        at play.api.DefaultGlobal$.onError(GlobalSettings.scala:188)
        at play.api.http.GlobalSettingsHttpErrorHandler.onServerError(HttpErrorHandler.scala:98)
        at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:100)
        at play.core.server.netty.PlayRequestHandler$$anonfun$2$$anonfun$apply$1.applyOrElse(PlayRequestHandler.scala:99)
        at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:344)
        at scala.concurrent.Future$$anonfun$recoverWith$1.apply(Future.scala:343)
        at scala.concurrent.impl.CallbackRunnable.run(Promise.scala:32)
Caused by: play.api.libs.json.JsResultException: JsResultException(errors:List((,List(ValidationError(List('name' is undefined on object: {"$ref":"#/parameters/domain"}),WrappedArray())))))
        at play.api.libs.json.JsReadable$$anonfun$2.apply(JsReadable.scala:23)
        at play.api.libs.json.JsReadable$$anonfun$2.apply(JsReadable.scala:23)
        at play.api.libs.json.JsResult$class.fold(JsResult.scala:73)
        at play.api.libs.json.JsError.fold(JsResult.scala:13)
        at play.api.libs.json.JsReadable$class.as(JsReadable.scala:21)
        at play.api.libs.json.JsUndefined.as(JsLookup.scala:137)
        at com.iheart.playSwagger.SwaggerSpecGenerator$$anonfun$mergeByName$2.apply(SwaggerSpecGenerator.scala:203)
        at com.iheart.playSwagger.SwaggerSpecGenerator$$anonfun$mergeByName$2.apply(SwaggerSpecGenerator.scala:202)
        at scala.collection.TraversableLike$$anonfun$filterImpl$1.apply(TraversableLike.scala:259)
        at scala.collection.immutable.List.foreach(List.scala:381)

Schema type generator

There is a problem with parsing custom types and used them as input or output definition. When trying use such class

package test

import org.joda.time.DateTime

final case class TestInput(
  value: Either[Unit, String],
  property: Either[Unit, Option[String]],
  dateTime: Either[Unit, Option[DateTime]],
  test: Either[Unit, Option[Test2Input]]
)

final case class Test2Input(
  propertyValue: Either[Unit, String]
)

on some route

###
# parameters:
#   - name: payload
#     in: body
#     schema:
#       $ref: '#/definitions/com.ticketfly.promotersuite.test.TestInput'
###
PATCH           /test @test.testAction()

i got exception

play.api.http.HttpErrorHandlerExceptions$$anon$1: Execution exception[[ScalaReflectionException: class test
.Test2Input] in JavaMirror with ReloadableClassLoader(v13){file:/C:/workspace/src/api/target/scala-2.11/classes/} of 
type class play.runsupport.DelegatedResourcesClassLoader with classpath [...] not found.]]
    at play.api.http.HttpErrorHandlerExceptions$.throwableToUsefulException(HttpErrorHandler.scala:265) ~[play_2.11-2.4.6.jar:2.4.6]
    at play.api.http.DefaultHttpErrorHandler.onServerError(HttpErrorHandler.scala:191) ~[play_2.11-2.4.6.jar:2.4.6]
    at test.play.ErrorHandler.onServerError(ErrorHandler.scala:36) [classes/:na]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$9$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:151) [play-netty-server_2.11-2.4.6.jar:2.4.6]
    at play.core.server.netty.PlayDefaultUpstreamHandler$$anonfun$9$$anonfun$apply$1.applyOrElse(PlayDefaultUpstreamHandler.scala:148) [play-netty-server_2.11-2.4.6.jar:2.4.6]
Caused by: scala.ScalaReflectionException: class test.Test2Input] in JavaMirror with 
ReloadableClassLoader(v13){file:/C:/workspace/src/api/target/scala-2.11/classes/} of type class play.runsupport.DelegatedResourcesClassLoader with classpath [...] not found.
    at scala.reflect.internal.Mirrors$RootsBase.staticClass(Mirrors.scala:123) ~[scala-reflect-2.11.7.jar:na]
    at scala.reflect.internal.Mirrors$RootsBase.staticClass(Mirrors.scala:22) ~[scala-reflect-2.11.7.jar:na]
    at com.iheart.playSwagger.DefinitionGenerator.definition(DefinitionGenerator.scala:41) ~[play-swagger_2.11-0.2.0.jar:0.2.0]
    at com.iheart.playSwagger.DefinitionGenerator.com$iheart$playSwagger$DefinitionGenerator$$allReferredDefs$1(DefinitionGenerator.scala:52) ~[play-swagger_2.11-0.2.0.jar:0.2.0]
    at com.iheart.playSwagger.DefinitionGenerator$$anonfun$com$iheart$playSwagger$DefinitionGenerator$$allReferredDefs$1$1.apply(DefinitionGenerator.scala:60) ~[play-swagger_2.11-0.2.0.jar:0.2.0]

it's only apear when add field
test: Either[Unit, Option[Test2Input]]

currentyl using Play 2.4.6 and

  "com.iheart" %% "play-swagger" % "0.2.0",
  "org.webjars" % "swagger-ui" % "2.1.4"

propably there will be problem with parsing types in

com.iheart.playSwagger.SwaggerParameterMapper

reading from body, and recognizing the inputs?

I've marked my actions like this, so I can read the input variables from the JSON body of the request:

  private case class SignUpData(firstName: String, lastName: String, email: String, password: String)

  def signUp = Action.async(parse.json) { implicit request =>
    request.body.validate[SignUpData].map { data =>
        // ... Code of the action is here.
      }
    }.recoverTotal {
      case error =>
        Future.successful(BadRequest(Json.obj("error" -> Messages("invalid.data"))))
    }
  }

Naturally the automatic system within play-swagger can't understand anything about e.g. SignUpData. But how should I do this so that I can read the input variables from the body, and have play-swagger automatically recognize them?

It maybe that I'm using Play incorrectly also.

$ref: Type is not defined

I'm struggling to understand what a proper path should be for the following File type:

Project structure

image

routes

###
#  summary: get files by FC hash
#  responses:
#    200:
#      description: success
#      schema:
#        $ref: '#/definitions/models.File'
###
GET /get/:hash                controllers.HashStore.getFiles(hash: Long)

Error

image

Problem with package name that do not incluse 'controllers' word

Problem with package name that do not incluse 'controllers' word.
This mean if I have in my routes route like this, it will not work

POST /calculation/order/calculate com.marks.calculation.controller.CalculationController.calculate()

becouse you have strickly regexp in
com/iheart/playSwagger/SwaggerSpecGenerator.scala (198:42)
"""(controllers[^(]+)((.*))?$"""
Please fix.

Need to specify `required: false` even if route has a default value

###
#  parameters:
#    - name: myParam
#      type: boolean
#      default: true
#      required: false
###
GET    /      controllers.MyController.get(myParam: Boolean ?= true)

If I exclude required: false, it assumes it's required, even though there's a default value.

if I exclude default: true, it doesn't autofill the default value to "true"

if I exclude type: boolean, it shows the data type as "undefined"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.