gettyimages / spray-swagger Goto Github PK
View Code? Open in Web Editor NEWLicense: Apache License 2.0
License: Apache License 2.0
Hi there,
I have the following model definition:
case class OfferQuery(
@(ApiModelProperty @field)
pricePerWeek: Int,
@(ApiModelProperty @field)(required = true)
resultNum: Int = 200)
Is there any annotation/override mechanism whereby I can have swagger generate the following JSON output?
{ "price_per_week": ...,
"result_num": ...}
Thanks a lot,
Andrea
It looks like the current code depends on swagger-core 1.3.8 which unfortunately was a botched release (see https://github.com/wordnik/swagger-core/wiki/Changelog#v138). You should actually refrain from using that and 1.3.9 as well.
Please consider upgrading to 1.3.10 but if you can't move forward, it's highly recommended to go back to 1.3.7.
Translate Scala enum types into swagger allowableValue types
Consider this REST resource:
find all products: GET /products
get product by ID: GET /products/{ID}
create product: POST /products
find by type: GET /products/type/{productType}
Looks like I can not have "find by type" operation declared in the same class with the rest.
It would be great to have the ability to customize @ApiOperation's path, may be with the @path annotation from JAX-RS or something like this.
It would be great to be able to get the raw json pretty printed using optional param. e.g.
/api-docs?pretty
currently I need to copy-paste the raw json to third party browser plugin to view it.
I'm aware of this is automatically translated as a setter and "is" is trimmed. What if I really need a property start with "is"?
If I'm understanding correctly what's going on in the definition of routes, it produces a concatenation of routes r0 ~ r1 ~ r2 ~ r3 ~ ... ~ rN for the N resources in the API (plus one at the beginning for the entire set), each with a matcher for a docsPath segment in the URL. That concatenation is wrapped in matchers for media type JSON and method GET.
In a JSON REST API, many incoming requests will be JSON GETs; such a GET will have to pass through N + 3 matchers in order to be rejected by this route tree. If these routes are placed at the end, then this hardly matters, but if someone were to put it earlier it could be an issue.
Alternatively the route tree could first match on the docsPath, thus causing non-Swagger requests to be rejected immediately. Then pathEnd (or pathEndOrSingleSlash, to be nicer) could be used to match the case where there was nothing following, like so:
final def routes: Route =
pathPrefix(docsPath) {
respondWithMediaType(`application/json`) {
get {
pathEndOrSingleSlash {
complete(toJsonString(api.getResourceListing()))
} ~ (
(for (
(subPath, apiListing) <- api.listings)
yield {
path(subPath.drop(1).split('/').map(
segmentStringToPathMatcher(_))
.reduceLeft(_ / _)) {
complete(toJsonString(apiListing))
}
}).reduceLeft(_ ~ _))
}
}
}
Spray 1.2.x does not publish artifacts with the Scala version suffix.
When trying to incorporate the spray-swagger artifact into a Spray 1.2.x service, the following resolution error occurs.
[error] Modules were resolved with conflicting cross-version suffixes in {file:/site/search/pip/}pip:
[error] io.spray:spray-httpx <none>, _2.10
[error] io.spray:spray-routing <none>, _2.10
[error] io.spray:spray-util <none>, _2.10
[error] io.spray:spray-http <none>, _2.10
I have configured swagger core 1.5 which produces swagger 2.0 definition files. I want to remove the definitions part from the swagger specification. Here is the swagger.json file.
{
"swagger": "2.0",
"info": { },
"paths": { },
"definitions": {
"type": "object"
}
}
Hi again,
We've encountered an issue when our @API serves paths of more than 1 level deep e.g. "/organisation/department", as unfortunately the SwaggerHttpService simply takes this as a string and appends it to the resource path as a documentation endpoint, whereas what Spray needs to happen is for this String to be split on its forward slash and turned into two PathMatchers.
We fixed this by doing what I mentioned above in a custom SwaggerHttpService implementation, as shown below by the finalApiPath in the routes function (please note I've also included logging to more clearly see what paths we're serving up documentation on, but you can ignore those):
final def routes: Route = get {
pathPrefix(specPath) {
info(s"""Building documentation on path "${specPath}/${resourcePath}" for Service ${getClass}""")
path(resourcePath) {
complete(resourceListing)
} ~ (for ((apiPath, apiListing) <- apiListingMap) yield {
info(s"""Building documentation path "${specPath}/${resourcePath}/${apiPath.drop(1)}" for Service ${getClass}""")
val finalApiPath = apiPath.drop(1).split("/").map(segmentStringToPathMatcher(_))
.reduceLeft(_ / _)
path(resourcePath / finalApiPath) { complete(apiListing) }
}).reduceLeft(_ ~ _)
}
}
Hope this is useful to you!
Thanks,
Duncan
Without working samples it's harder to start with.
I've found this one, but has only one URL: https://github.com/lloydmeta/spray-servlet-scratchpad
Hi!
I've tried to use @Api
annotation basePath
field for override value
field value as described in @Api
annotation documentation. But basePath
value providing has no effect on generated API documentation.
By the code SprayApiReader
doesn't take into account this annotation field.
I will be pleased to provide correspondent pull-request if it is bug.
I am getting an exception when I try to use spray-swagger.
I use the following directive to setup parameters:
parameters('topic.as[String], 'nim.as[Int], 'client.as[String]).as(PostParams)
With a defined case class:
case class PostParams(topic: String, nim: Int, client: String)
Unfortunately it throws the exception:
2014-04-10 14:10:03,375 [MessageBroker-akka.actor.default-dispatcher-39] ERROR akka.actor.OneForOneStrategy - class PostParams is not a term
akka.actor.ActorInitializationException: exception during creation
Any ideas on how to get around this?
The swagger spec allows for overriding primitive types with a "format" field for language specific data types. Unfortunately this is not supported with the swagger field annotation yet. Until this is fixed or an alternative is present, uses should just override the type parameter for the custom type they want.
See https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#523-operation-object, PR #9 and issue #13.
If I have an ApiImplicitParam
with dataType = "com.foo.in.Something"
and an ApiResponse
with response = classOf[com.foo.out.Something]
the generated docs will use out.Something
for both the parameter's data type as well as the response's data type. Renaming out.Something
to out.OutSomething
causes the docs to generate the expected types.
@ApiOperation(httpMethod = "PUT",
response = classOf[String],
value = "Copies the version constraints from one environment to another")
@ApiImplicitParams(Array(
new ApiImplicitParam(name = "src", required = true, dataType = "string", paramType = "form", value = "The source environment"),
new ApiImplicitParam(name = "dest", required = true, dataType = "string", paramType = "form", value = "The destination environment)")))
@ApiOperation(httpMethod = "PUT",
response = classOf[String],
value = "Freezes the version constraints of an environment to a given set (or, by default, to the latest)")
@ApiImplicitParams(Array(
new ApiImplicitParam(name = "systemName", required = true, dataType = "string", paramType = "path", value = "The name of the glue system (typically something like customerName-level)"),
new ApiImplicitParam(name = "versions", required = true, dataType = "Map[String, String]", paramType = "form", value = "A map of cookbook to version")))
In the swagger-ui, I do not see the paths correctly, the paths I see look like this:
/SystemBuilder | Copies the version constraints from one environment to another
and
/SystemBuilder/{systemName} | Freezes the version constraints of an environment to a given set (or, by default, to the latest)
So of course, the "try it out" button doesn't work either.
Is there something I'm missing in the documentation? maybe an additional ApiImplicitParam?
Thanks,
Roberto
I have sample project here that I'm using to try out your lib :)
Unfortunately, when I run it (just container:start
from sbt for now), it dies with the following trace caused by a java.lang.NullPointerException
. I've declared the modelTypes and also annotated the model; what could be missing ?
> [ERROR] [03/08/2014 23:30:46.830] [beachape-akka.actor.default-dispatcher-4] [akka://beachape/user/$a] null
akka.actor.ActorInitializationException: exception during creation
at akka.actor.ActorInitializationException$.apply(Actor.scala:164)
at akka.actor.ActorCell.create(ActorCell.scala:596)
at akka.actor.ActorCell.invokeAll$1(ActorCell.scala:456)
at akka.actor.ActorCell.systemInvoke(ActorCell.scala:478)
at akka.dispatch.Mailbox.processAllSystemMessages(Mailbox.scala:263)
at akka.dispatch.Mailbox.run(Mailbox.scala:219)
at akka.dispatch.ForkJoinExecutorConfigurator$AkkaForkJoinTask.exec(AbstractDispatcher.scala:393)
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.NullPointerException
at com.gettyimages.spray.swagger.SwaggerModelBuilder.<init>(SwaggerModelBuilder.scala:30)
at com.gettyimages.spray.swagger.SwaggerApiBuilder.<init>(SwaggerApiBuilder.scala:43)
at com.gettyimages.spray.swagger.SwaggerHttpService$class.$init$(SwaggerHttpService.scala:49)
at com.beachape.controllers.ApiServiceActor.<init>(ApiService.scala:16)
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:57)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.lang.reflect.Constructor.newInstance(Constructor.java:526)
at java.lang.Class.newInstance(Class.java:374)
at akka.util.Reflect$.instantiate(Reflect.scala:45)
at akka.actor.NoArgsReflectConstructor.produce(Props.scala:358)
at akka.actor.Props.newActor(Props.scala:249)
at akka.actor.ActorCell.newActor(ActorCell.scala:552)
at akka.actor.ActorCell.create(ActorCell.scala:578)
... 9 more
Boxed types are treated as Object
types when used as type parameters within Api Models.
For example, the following case class...
case class Foo(stringSeq: Seq[String], stringOpt: Option[String], intSeq: Seq[Int], intOpt: Option[Int])
... produces the following api-doc JSON snippet:
{
"models": {
"Foo": {
"id": "Foo",
"properties": {
"stringSeq": {
"type": "array",
"items": {
"type": "string"
}
},
"stringOpt": {
"type": "string"
},
"intSeq": {
"type": "array",
"items": {
"$ref": "Object"
}
},
"intOpt": {
"$ref": "Object"
}
}
}
}
}
Notice how the type information for Int
is lost but String
remains.
I'm pleased if I would hear or discuss how spray-swagger would support/migrate to swagger-core 1.5??
I understand swagger-core 1.5 did make many changes, e.g. package structures and more flexible module structures which separates each responsibilities clearly, etc. And moreover, swagger-core 1.5 ships many enhancements(better generics support, auto subtypes generation, etc.).
It also seems that scala support is now developing in swagger-scala-module .
The README says:
If the dataType value is not of the basic types, spray-swagger will try and find the type in the modelTypes sequence. Refer to swagger-core for other attribute information.
But I haven't found where to set those modelTypes, I presume would look like this:
modelTypes = Seq(typeOf[Meeting])
In my code I have an object like this:
package com.example
object Stuff {
@ApiModel(description = "A thing")
case class Thing(@(ApiModelProperty @field)(value = "ID of the thing") id: String)
}
And I want to do:
@ApiImplicitParams(Array(
new ApiImplicitParam(name="thing", required=true, dataType="com.example.Stuff.Thing", paramType="body", value="A thing to add.")
))
However, the type "Thing" never gets added to the models. Moving "Thing" outside of the object causes it to show up in the models.
in my code this is my docsPath def docsPath = "project-docs-api"
when i try to use def docsPath = "project/docs/api"
swagger cannot found the json
what i'm doing wrong?
I have a multimodule project, and one of the modules - model - has to have a swagger dependency, so that I can annotate those with appropriate annotations.
For me the configuration required by SwaggerHttpService and the need for explicitly specifying modelTypes is quite redundant to the required annotations.
I'd like to modify this behavior so that if a class is mentioned in modelTypes, than it is analyzed regardles of the fact it contains annotations or not.
Is this a desired behavior, or this would be just against spray-swagger idea?
It's this link:
https://github.com/gettyimages/spray-swagger/blob/master/wordnik/swagger-ui
in the main page https://github.com/gettyimages/spray-swagger
I have a case class InputParams
@ApiModel(description = "Input Parameters")
case class InputParams(
@(ApiModelProperty @field)(value = "User Identifier", required = true) userId: String,
@(ApiModelProperty @field)(value = "Another Attr") attrTwo: Option[String])
but when I run swagger I get
19:10:01.549 [on-spray-can-akka.actor.default-dispatcher-4] DEBUG c.w.swagger.core.SwaggerContext - Class InputParams not found in classLoader
so in the UI I don't see the structure for that JSON
@ApiOperation(value="Description", httpMethod = "POST", consumes = "application/json, application/vnd.custom.inputParams+json", produces = "text/plain", response = classOf[String])
@ApiImplicitParams(Array(
new ApiImplicitParam(name = "body", value = "balue", required = true, dataType = "InputParams", paramType = "body")
))
Everything works fine except that on the UI I just see InputParams but not the structure
Any idea of what I might be missing?
Hi all,
Please, may I know if spray-swagger is currently supporting the Swagger 2.0 specification [1]?. If not, any plans to support this in the near future?.
Thanks in advance,
Juanjo
[1] https://github.com/wordnik/swagger-spec/blob/master/versions/2.0.md
Hi there,
Spray is moving into maintenance mode. Will spray-swagger support Akka-HTTP going forward?
Kind regards,
Jacobus
The root cause of this issue: https://groups.google.com/forum/#!topic/swagger-swaggersocket/1GOrOOP6P64/discussion is an incorrect usage of the swagger spec.
Would you consider releasing a version against shapeless 2.0.0 similar to "io.spray" %% "spray-routing-shapeless2" % "1.3.2"
?
Hi once again!
This may be misconfiguration or incorrect annotating on my part, but currrently the SwaggerModelBuilder appears to be outputting Scala types e.g. "Long", "Int" rather than the equivalent "int64", "int32" etc.
As I say, this may be misconfiguration on my part, but if not is this possibly a feature that will be introduced at some point in the future?
Many thanks, and keep up the good work :)
Duncan
Hey,
I'm currently using spray-swagger and encountering the following issue:
I have three @Api
each containing a position
argument.
Each of these api contains multiple @ApiOperation
containing a position
argument as well.
The problem is that those position
arguments do not seem to be picked up by spray-swagger. Indeed, the @Api
and @ApiOperation
seem to be ordered alphabetically.
Any ideas why?
so we cant make response to be a list of something. Or can we?
Hi,
We've noticed that we're not getting any notes about model fields when looking at the API docs via swagger-ui. Is this something that is likely to be looked at in the future? Or maybe I've not configured something correctly?
Thanks for your help,
Duncan
Hey ,
Do you think that is possible to restrict somehow the supported methods for several Api's. For example i want to allow only get operations on a specific model/api is that even possible ? I found a parameter that specify that in index.html but it seems that is never being used in the swagger ui. (supportedSubmitMethods: ['get','put','post','delete'])
Thank you in advance,
Andreas
In SprayApiScanner, when an exception is thrown the logger generates another exception because of a missing argument :
logger.error("Problem loading class: %s. %s: %s".format(api.toString, ex.getMessage))
There are 3 %s but only 2 arguments given.
The @ApiOperation
and @ApiModelProperty
attributes both have a position
property to allow explicit ordering of the operations or properties in the docs (which is pretty useful for neat documentation given the order of these things returned by the reflection APIs isn't guaranteed to be in the declared order -- and frequently isn't).
spray-swagger should take the position
attribute into account when ordering the operations and model properties.
... and artifact "com.typesafe.sbt", "sbt-pgp_2.10", "0.8.3" cannot easily be found.
It should only be a build dependency, not runtime depedency.
Hey!
Thanks for making this tool, really useful!
I was wondering if there is any support for enabling CORS for the swagger route? At the company I work at we want to host the swagger-ui on a different server than the one serving the api-docs json, which does not work right now as CORS is not enabled for the api-docs resource. For my purposes it would be enough to simply set Access-Control-Allow-Origin=*
Thanks!
When adding spray-swagger as a dependency, it complains it cannot find sbt-pgp.
I've tried to add this to your project/plugins.sbt:
addSbtPlugin("com.typesafe.sbt" % "sbt-pgp" % "0.8.3")
but doesn't help.
This is my working solution:
libraryDependencies += "com.gettyimages" % "spray-swagger_2.10" % "0.3.1" exclude("com.typesafe.sbt", "sbt-pgp"),
Hi there,
We have a number of financial-based classes that make heavy use of BigDecimals. We'd like to expose these via Swagger if possible, and I see that the SwaggerModelBuilder supports Doubles but not yet BigDecimals.
Would this be a possible quick fix that you could introduce at all?
Many thanks,
Duncan
I need to expose some user-defined resources which are dynamically created at runtime.
It would be great to have some hook to append them to the static resources list which returns the SwaggerHttpService. Unfortunately everything there either final or private and there's no simple way to override the api without changing the library sources. I can override "toJsonString" and pattern match the param, but it is a bit hackish :)
Hey,
Thank you for providing as such a nice tool btw ๐ . The problem i have with swagger is that i use several calls with a 2 lvl depth url and it is not picking them up. For example i have few calls which returns a list of data like names and numbers which are like /data/names and /data/numbers . I want those calls to leave under the api annotation /data and then define each one of the with an api operation. The first issue i have is that swagger use /data as the title on all the operations under /data which makes it confusing. In addition it seems that it is getting confuse when you have multiple get request under the same api resource. I thought initially that the attribute value on the api operation would handle the extra path attribute but it is not. The ideal scenario was to use the description attribute as the description of the operation ( the description text btw now is the attribute "value" which i think that it is a bit odd ) and not the value. Value would be much more beneficial if it could be used as the extra path attribute like /data/{value}.
I am not sure if this is a bug with swagger or a possible improvement to the tool.
Thank you in advance,
Andreas
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.