swagger-akka-http / swagger-akka-http Goto Github PK
View Code? Open in Web Editor NEWSupport for generating Swagger REST API documentation for Akka-Http based services.
License: Apache License 2.0
Support for generating Swagger REST API documentation for Akka-Http based services.
License: Apache License 2.0
A few people asked recently about Java support. As part of 1.0 release, we could consider introducing a scaladsl and javadsl split.
There is a standalone sample at https://github.com/pjfanning/swagger-akka-http-java
I am currently An error occurred.
java.util.ServiceConfigurationError: io.swagger.converter.ModelConverter: Provider io.swagger.scala.converter.SwaggerScalaModelConverter could not be instantiated
as you know, this error related on Jackson version.
My project uses jackson 2.9.2, is there a way to fix this error without lowering the version?
I see current implementation:
trait HasActorSystem {
implicit val actorSystem: ActorSystem
implicit val materializer: ActorMaterializer
}
But ActorMaterializer is implementation of Materializer and akka-http actually needs just Materializer
I am using version 0.11.0.
In my case the server is behind a https vip. The vip redirect a https request to the server's 8080 port.
My SwaggerDoc class code is simple, like below:
class SwaggerDoc extends SwaggerHttpService {
override val apiClasses = Set(
classOf[service1],
classOf[service2],
classOf[service3],
classOf[service4]
)
val contact = new Contact()
contact.setName("contact1")
override val info = Info(version = "0.1", title = "Demo", description = "", contact = contact)
}
The problem is if I used the url https://viphost/swagger-ui/index.html?url=/api-docs/swagger.json to visit my swagger UI. The swagger UI can be loaded. But any http request generated from the UI is having the vip hostname with http instead of https. Certainly the result is no response.
Anything I did wrong or I missed for configure the SwaggerDoc?
Swagger serving was crashing on my server with the following java version:
java -version
java version "9.0.1"
Java(TM) SE Runtime Environment (build 9.0.1+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.1+11, mixed mode)
The log is here: https://pastebin.com/raw/xDM2w2Gm
The fix was to add a dependency:
"javax.xml.bind" % "jaxb-api" % "2.3.0",
as indicated by this thread.
I guess this should be fixed here or upstream.
Hi
I'm currently using
"com.github.swagger-akka-http" %% "swagger-akka-http" % "0.8.2-SNAPSHOT"
And starting to get java.lang.NoSuchMethodError
when trying to access swagger.json this morning.
2016-12-21 13:38:56,732 ERROR - com.github.swagger.akka.SwaggerHttpService - Issue with creating swagger.json
java.lang.NoSuchMethodError: io.swagger.annotations.ApiImplicitParam.type()Ljava/lang/String;
at io.swagger.util.ParameterProcessor$ApiImplicitParamWrapper.getType(ParameterProcessor.java:698)
at io.swagger.util.ParameterProcessor$AnnotationsHelper.<init>(ParameterProcessor.java:423)
at io.swagger.util.ParameterProcessor.applyAnnotations(ParameterProcessor.java:42)
at io.swagger.jaxrs.Reader.readImplicitParam(Reader.java:478)
at io.swagger.jaxrs.Reader.processImplicitParams(Reader.java:446)
at io.swagger.jaxrs.Reader.readImplicitParameters(Reader.java:439)
at io.swagger.jaxrs.Reader.read(Reader.java:427)
at io.swagger.jaxrs.Reader.read(Reader.java:174)
at com.github.swagger.akka.SwaggerHttpService$class.generateSwaggerDocs(SwaggerHttpService.scala:84)
at spatialinsights.tilecomparator.service.rest.swagger.SwaggerDocService.generateSwaggerDocs(SwaggerDocService.scala:13)
at com.github.swagger.akka.SwaggerHttpService$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(SwaggerHttpService.scala:97)
at com.github.swagger.akka.SwaggerHttpService$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(SwaggerHttpService.scala:97)
at akka.http.scaladsl.server.directives.RouteDirectives$$anonfun$complete$1.apply(RouteDirectives.scala:47)
at akka.http.scaladsl.server.directives.RouteDirectives$$anonfun$complete$1.apply(RouteDirectives.scala:47)
at akka.http.scaladsl.server.StandardRoute$$anon$1.apply(StandardRoute.scala:19)
at akka.http.scaladsl.server.StandardRoute$$anon$1.apply(StandardRoute.scala:19)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResult$1$$anonfun$apply$3.apply(BasicDirectives.scala:60)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResult$1$$anonfun$apply$3.apply(BasicDirectives.scala:60)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:42)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:42)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation$$anonfun$$tilde$1$$anonfun$apply$1.apply(RouteConcatenation.scala:47)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation$$anonfun$$tilde$1$$anonfun$apply$1.apply(RouteConcatenation.scala:44)
at akka.http.scaladsl.util.FastFuture$.akka$http$scaladsl$util$FastFuture$$strictTransform$1(FastFuture.scala:41)
at akka.http.scaladsl.util.FastFuture$.transformWith$extension1(FastFuture.scala:45)
at akka.http.scaladsl.util.FastFuture$.flatMap$extension(FastFuture.scala:26)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:44)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:42)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResultWith$1$$anonfun$apply$4.apply(BasicDirectives.scala:66)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResultWith$1$$anonfun$apply$4.apply(BasicDirectives.scala:66)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResultWith$1$$anonfun$apply$4.apply(BasicDirectives.scala:66)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResultWith$1$$anonfun$apply$4.apply(BasicDirectives.scala:66)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$anonfun$apply$1.apply(ExecutionDirectives.scala:32)
at akka.http.scaladsl.server.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$anonfun$apply$1.apply(ExecutionDirectives.scala:28)
at akka.http.scaladsl.server.Route$$anonfun$asyncHandler$1.apply(Route.scala:73)
at akka.http.scaladsl.server.Route$$anonfun$asyncHandler$1.apply(Route.scala:72)
at akka.stream.impl.fusing.MapAsync$$anon$21.onPush(Ops.scala:1008)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:747)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:649)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:471)
at akka.stream.impl.fusing.GraphInterpreterShell.receive(ActorGraphInterpreter.scala:423)
at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:603)
at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:618)
at akka.actor.Actor$class.aroundReceive(Actor.scala:484)
at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:529)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526)
at akka.actor.ActorCell.invoke(ActorCell.scala:495)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
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)
2016-12-21 13:38:56,737 ERROR - akka.actor.ActorSystemImpl - Uncaught error from thread [tilecomparator-system-akka.actor.default-dispatcher-2] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled
java.lang.NoSuchMethodError: io.swagger.annotations.ApiImplicitParam.type()Ljava/lang/String;
at io.swagger.util.ParameterProcessor$ApiImplicitParamWrapper.getType(ParameterProcessor.java:698)
at io.swagger.util.ParameterProcessor$AnnotationsHelper.<init>(ParameterProcessor.java:423)
at io.swagger.util.ParameterProcessor.applyAnnotations(ParameterProcessor.java:42)
at io.swagger.jaxrs.Reader.readImplicitParam(Reader.java:478)
at io.swagger.jaxrs.Reader.processImplicitParams(Reader.java:446)
at io.swagger.jaxrs.Reader.readImplicitParameters(Reader.java:439)
at io.swagger.jaxrs.Reader.read(Reader.java:427)
at io.swagger.jaxrs.Reader.read(Reader.java:174)
at com.github.swagger.akka.SwaggerHttpService$class.generateSwaggerDocs(SwaggerHttpService.scala:84)
at spatialinsights.tilecomparator.service.rest.swagger.SwaggerDocService.generateSwaggerDocs(SwaggerDocService.scala:13)
at com.github.swagger.akka.SwaggerHttpService$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(SwaggerHttpService.scala:97)
at com.github.swagger.akka.SwaggerHttpService$$anonfun$routes$1$$anonfun$apply$1$$anonfun$apply$2.apply(SwaggerHttpService.scala:97)
at akka.http.scaladsl.server.directives.RouteDirectives$$anonfun$complete$1.apply(RouteDirectives.scala:47)
at akka.http.scaladsl.server.directives.RouteDirectives$$anonfun$complete$1.apply(RouteDirectives.scala:47)
at akka.http.scaladsl.server.StandardRoute$$anon$1.apply(StandardRoute.scala:19)
at akka.http.scaladsl.server.StandardRoute$$anon$1.apply(StandardRoute.scala:19)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResult$1$$anonfun$apply$3.apply(BasicDirectives.scala:60)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResult$1$$anonfun$apply$3.apply(BasicDirectives.scala:60)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:42)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRequestContext$1$$anonfun$apply$1.apply(BasicDirectives.scala:42)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation$$anonfun$$tilde$1$$anonfun$apply$1.apply(RouteConcatenation.scala:47)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation$$anonfun$$tilde$1$$anonfun$apply$1.apply(RouteConcatenation.scala:44)
at akka.http.scaladsl.util.FastFuture$.akka$http$scaladsl$util$FastFuture$$strictTransform$1(FastFuture.scala:41)
at akka.http.scaladsl.util.FastFuture$.transformWith$extension1(FastFuture.scala:45)
at akka.http.scaladsl.util.FastFuture$.flatMap$extension(FastFuture.scala:26)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:44)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation$$anonfun$$tilde$1.apply(RouteConcatenation.scala:42)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResultWith$1$$anonfun$apply$4.apply(BasicDirectives.scala:66)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResultWith$1$$anonfun$apply$4.apply(BasicDirectives.scala:66)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResultWith$1$$anonfun$apply$4.apply(BasicDirectives.scala:66)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$mapRouteResultWith$1$$anonfun$apply$4.apply(BasicDirectives.scala:66)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.BasicDirectives$$anonfun$textract$1$$anonfun$apply$5.apply(BasicDirectives.scala:153)
at akka.http.scaladsl.server.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$anonfun$apply$1.apply(ExecutionDirectives.scala:32)
at akka.http.scaladsl.server.directives.ExecutionDirectives$$anonfun$handleExceptions$1$$anonfun$apply$1.apply(ExecutionDirectives.scala:28)
at akka.http.scaladsl.server.Route$$anonfun$asyncHandler$1.apply(Route.scala:73)
at akka.http.scaladsl.server.Route$$anonfun$asyncHandler$1.apply(Route.scala:72)
at akka.stream.impl.fusing.MapAsync$$anon$21.onPush(Ops.scala:1008)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:747)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:649)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:471)
at akka.stream.impl.fusing.GraphInterpreterShell.receive(ActorGraphInterpreter.scala:423)
at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:603)
at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:618)
at akka.actor.Actor$class.aroundReceive(Actor.scala:484)
at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:529)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:526)
at akka.actor.ActorCell.invoke(ActorCell.scala:495)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
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)
@ApiOperation(
value = "Create new user record",
notes = "",
httpMethod = "POST",
consumes = "application/json",
produces = "application/json"
)
@ApiImplicitParams(Array(
new ApiImplicitParam(
name = "payload",
value = "Json data for create new user",
dataType = "User",
required = true,
paramType = "body"
)
))
@ApiResponse(code = 201, message = "Return created user", response = classOf[User])
@ApiResponses(Array(
new ApiResponse(code = 201, message = "Return created user", response = classOf[User]),
new ApiResponse(code = 500, message = "Internal server error")
))
The generated response auto populated 200, which is not the expected response from the api.
Is there anyway we can disable the auto populate of 200 status? Thanks in ad!
"/user" : {
"post" : {
"tags" : [ " Jobs" ],
"summary" : "Create new user record",
"description" : "",
"operationId" : "createuser",
"consumes" : [ "application/json" ],
"produces" : [ "application/json" ],
"parameters" : [ {
"in" : "body",
"name" : "payload",
"description" : "Json data for create new user",
"required" : true,
"schema" : {
"$ref" : "#/definitions/user"
}
} ],
"responses" : {
"200" : {
"description" : "successful operation",
"schema" : {
"$ref" : "#/definitions/Function1RequestContextFutureRouteResult"
}
},
"201" : {
"description" : "Return created user",
"schema" : {
"$ref" : "#/definitions/user"
}
},
"500" : {
"description" : "Internal server error"
}
}
}
}
Does SwaggerHttpService really use any of the members of HasActorSystem? At first glance I don't see any so why HasActorSystem must be self type of it? I my case it is redundant because I already have trait like HasActorSystem and I want to extend my trait, so reimplementing its fields is redundant for me.
Some of the routes in the API I'm documenting end with a forward slash.
When swagger-akka-http generates the documentation, this backslash is missing from the path.
Am I missing something? Unsure of why this is happening or how to fix it. Thanks!
@Path("/User({user_id})/Report/")
@ApiOperation(
httpMethod = "GET",
response = classOf[UserReport],
responseContainer = "List",
notes = "Example Request: /User(1)/Report/",
value = "Get a list of reports for a user")
@ApiImplicitParams(Array(
new ApiImplicitParam(name = "user_id", value = "User ID", required =
true, example = "1", paramType = "path", dataType = "integer")
))
@ApiResponses(Array(
new ApiResponse(code = 200, message = "Successful response",
responseContainer = "Array", response = classOf[ReportList]),
new ApiResponse(code = 404, message = "Requested resource not found",
response = classOf[ErrorDetails])
))
def getReportList(@ApiParam(hidden = true) completeRouteMetadata:
CompleteRouteMetadata): Route = {
(path("Report" /) & get) {
pathEndOrSingleSlash {
complete(ToResponseMarshallable(
getReports(completeRouteMetadata.resourceOwner, List())))
}
}
}
The generated json removes this:
/User({user_id})/Report:
get:
tags:
- Report
summary: Get a list of reports for the specified user
description: 'Example Request: /User(1)/Report/'
operationId: getReportList
produces:
- application/json
parameters:
- name: user_id
in: path
description: User ID
required: true
type: integer
x-example: 1
responses:
'200':
description: Successful response
schema:
type: array
items:
$ref: '#/definitions/ReportList'
'404':
description: Requested resource not found
schema:
$ref: '#/definitions/error'
I am trying to use swagger for 2 purposes :
Using swagger-akk-http, I am able to generate the documentation and view in the Swagger-UI. But for my 2nd requirement, I need to transform the swagger.json file. I need multiple types of filter for the api's. For doing that, I was trying to find out the location of the swagger json file, but I am not able to find it. Is it not generated and saved in the workspace ? Or is it read every time using reflection on annotations ?
The README examples seem to be out of date with the samples in the code.
Usually, a post on a resource doesn't have an id, while a get does.
For example (Scala code)
trait UserT(def name: String, def age: Int)
case class User(name: String, age: Int) extends UserT // Used for Post requests
case class UserWithid(name: String, age: Int) extends UserT // Used for Post requests
Is it possible to add annotations to the trait, and have the classes reuse it?
I think the corresponding feature in swagger is: https://swagger.io/docs/specification/data-models/inheritance-and-polymorphism/
filteredSchemas is immutable map, which will cause the same issue as #60
After we upgraded to 0.13.0 Option[Int]
is no more converted correctly.
This test passes with 0.12.0 but not after:
it should "process Model with Scala Option Int" in {
val converter = ModelConverters.getInstance()
val schemas = converter.readAll(classOf[ModelWOptionInt]).asScala.toMap
val model = schemas.get("ModelWOptionInt")
model should be('defined)
val optInt = model.get.getProperties.get("optInt")
optInt should not be null
optInt shouldBe a[properties.BaseIntegerProperty]
optInt.getRequired should be(false)
}
case class ModelWOptionInt(optInt: Option[Int])
io.swagger.models.properties.ObjectProperty@d9eac59d was not an instance of io.swagger.models.properties.BaseIntegerProperty, but an instance of io.swagger.models.properties.ObjectProperty
The @API annotation shows properly in tags. However the swagger.json only contains basePath
@Api(value = "/Hello")
@Path("/")
class Hello extends Directives
@Path("/hello")
@ApiOperation(value = "Return Hello greeting", notes = "", nickname = "anonymousHello", httpMethod = "GET")
@ApiResponses(Array(
new ApiResponse(code = 200, message = "Return Hello Greeting", response = classOf[Greeting]),
new ApiResponse(code = 500, message = "Internal server error")
))
def hello
I'm using aka 2.4.11
"com.github.swagger-akka-http" %% "swagger-akka-http" % "0.8.0"
"io.swagger" %% "swagger-scala-module" % "1.0.0"
swagger.json
{
"basePath": "/",
"host": "localhost:12345",
"info": {
"description": "description",
"termsOfService": "",
"title": "Hello",
"version": ""
},
"schemes": [
"http"
],
"securityDefinitions": {},
"swagger": "2.0",
"tags": [
{
"name": "hello"
}
]
}
Hi,
from http://swagger.io/specification/
"""
The host (name or ip) serving the API. This MUST be the host only and does not include the scheme nor sub-paths. It MAY include a port. If the host is not included, the host serving the documentation is to be used (including the port). The host does not support path templating.
"""
Is it possible to have same with swagger-akka-http ?
currently if I would not overwrite url from SwaggerHttpService, it will set its value to localhost by default. The issue that my service can run on different environments, and I cannot always know what would be the url domain name and port.
Thanks,
Hi,
i have created this simple annotated class in scala and used used swagger-akka-http 0.14.0 version
@Path("/testApiOperation") @Api(value = "/testApiOperation", description = "Operations about get.") class Prova { @ApiOperation(value = "testiOperation", httpMethod = "GET") @ApiResponses(Array( new ApiResponse(code = 404, message = "Pong not found"), new ApiResponse(code = 200, message = "Pong found"), new ApiResponse(code = 400, message = "Invalid Ping supplied"))) def testOperation (@ApiParam(name="page", value="start page") @QueryParam("page") page:String) ={} }
when i run the code , and launch http://localhost:8080/api-docs/swagger.json i have this error :
java.util.ServiceConfigurationError: io.swagger.converter.ModelConverter: Provider com.github.swagger.akka.SwaggerScalaModelConverter could not be instantiated
at java.util.ServiceLoader.fail(ServiceLoader.java:232)
at java.util.ServiceLoader.access$100(ServiceLoader.java:185)
...........
Caused by: java.lang.VerifyError: Cannot inherit from final class
If i write the procedure testOperation without annotated parameters (@ApiParam) all it's ok: the documentation is generated.
I have the same problem when try to generate doc for this simply route:
@ApiOperation(value = "Find a ping", notes = "Returns a pong", httpMethod = "GET", response = classOf[String]) @ApiResponses(Array( new ApiResponse(code = 404, message = "Pong not found"), new ApiResponse(code = 200, message = "Pong found"), new ApiResponse(code = 400, message = "Invalid Ping supplied"))) def readRoute = path("ping") { complete("pong") }
Can you help me please?
Many thanks
I don't know how to use the Scala API in Java. Could you please provide a java example?
https://www.openapis.org/blog/2017/07/26/the-oai-announces-the-openapi-specification-3-0-0
Swagger 2.0 is still under development. Its annotations are changing quite a lot. When it becomes clearer how to migrate the existing sample to use the 2.0 snapshots, it would be useful to try to get a fork of the sample to output OpenAPI 3.0 docs.
Hi,
I have a response which looks like that:
case class Foo(x: String, y: Int)
response -> Map[String, Foo]
example: Map("key1" -> Foo("v1", 1), "key2" -> Foo("v2", 2))
I am using circe, so eventually the JSON response looks like:
{"key1": {"x": "v1", "y": 1}, "key2": {"x": "v2", "y": 2})
how can I define the schema of the response with swagger ?
If I use responseContainer="Map" I get in swagger
exmple: {}
model: inline_model {}
Thanks,
Expected behavior: Option[Boolean]
to be mapped to boolean
Current behavior: Option[Boolean]
mapped to number
I reproduced using https://github.com/pjfanning/swagger-akka-http-sample.
Changed Greeting
to case class Greeting(greeting: String, foo: Option[Boolean] = None)
Definition that is produced:
Greeting: {
type: "object",
required: [
"greeting"
],
properties: {
greeting: {
type: "string"
},
foo: {
type: "number"
}
}
}
Hi devs!
After migration from spray to akka-http we have lot of problems with swagger - our docs not usable anymore, because scala model converter is so "hungry", it converts all implicits and convert them to body parameters, do not understand Enumerations.
I've tried add classes to ignore, but no luck. Model converter skip this configuration...
So my question is - how to downgrade to model converter used in swagger-spray?
Can you help me?
I have a resource where a POST should return a 202 Accepted, since it is a long-running operation. So I have
@ApiOperation(value = "Create scenario", httpMethod = "POST")
@ApiResponses(Array(
new ApiResponse(code = 202, message = "Scenario creation in progress"),
new ApiResponse(code = 500, message = "Internal server error")
))
However responses generated includes a 200, which I do not want:
"responses" : {
"200" : {
"description" : "successful operation",
"schema" : {
"$ref" : "#/definitions/Function1RequestContextFutureRouteResult"
}
},
"202" : {
"description" : "Scenario creation in progress"
},
"500" : {
"description" : "Internal server error"
}
Not sure why im getting this error. I cant find any example where a case class extends a sealed trait. Might this be the cause of the error?
@Api(value = "/", produces = "application/json")
@Path("/session")
class AuthenticationRoute(handler: AuthenticationHandler) extends PartialRoute with FailFastCirceSupport {
override val route: Route = authenticationStatus ~ authenticationStatus2
@Path("/authStatus")
@ApiOperation(value = "Return session status", notes = "", nickname = "anonymousHello", httpMethod = "GET")
@ApiResponses(Array(
new ApiResponse(code = 200, message = "Return Hello Greeting", response = classOf[SessionCreated]),
new ApiResponse(code = 500, message = "Internal server error")
))
def authenticationStatus =
path("session" / "authStatus") {
get {
complete(handler.authenticationStatus.mapTo[SessionCreated])
}
}
}
sealed trait SessionEvent
object SessionEvent {
@ApiModel(description = "The session token")
case class SessionCreated(
@(ApiModelProperty @field)("Token!")
val sessionToken: String
) extends SessionEvent
}
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG io.swagger.jaxrs.Reader - picking up response class from method public scala.Function1 com.bfg.infrastructure.server.routes.AuthenticationRoute.authenticationStatus()
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG io.swagger.converter.ModelConverters - adding ModelConverter: io.swagger.scala.converter.SwaggerScalaModelConverter@451baad9
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - resolveProperty scala.Function1<akka.http.scaladsl.server.RequestContext, scala.concurrent.Future<akka.http.scaladsl.server.RouteResult>>
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG io.swagger.jackson.ModelResolver - resolveProperty [simple type, class scala.Function1<akka.http.scaladsl.server.RequestContext,scala.concurrent.Future<akka.http.scaladsl.server.RouteResult>>]
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - resolve [simple type, class scala.Function1<akka.http.scaladsl.server.RequestContext,scala.concurrent.Future<akka.http.scaladsl.server.RouteResult>>]
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - trying extension io.swagger.scala.converter.SwaggerScalaModelConverter@451baad9
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG io.swagger.jackson.ModelResolver - Can't check class [simple type, class scala.Function1<akka.http.scaladsl.server.RequestContext,scala.concurrent.Future<akka.http.scaladsl.server.RouteResult>>], scala.Function1
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - resolve interface scala.Function1
11:31:22 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - trying extension io.swagger.scala.converter.SwaggerScalaModelConverter@451baad9
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - defineModel Function1 io.swagger.models.ModelImpl@5925ab17
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - defineModel Function1 io.swagger.models.ModelImpl@5925ab17
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - defineModel Function1RequestContextFutureRouteResult io.swagger.models.ModelImpl@7ae6d168
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - defineModel Function1RequestContextFutureRouteResult io.swagger.models.ModelImpl@7ae6d168
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG io.swagger.converter.ModelConverters - ModelConverters readAll from scala.Function1<akka.http.scaladsl.server.RequestContext, scala.concurrent.Future<akka.http.scaladsl.server.RouteResult>>
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - resolve scala.Function1<akka.http.scaladsl.server.RequestContext, scala.concurrent.Future<akka.http.scaladsl.server.RouteResult>>
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - trying extension io.swagger.scala.converter.SwaggerScalaModelConverter@451baad9
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - resolve interface scala.Function1
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - trying extension io.swagger.scala.converter.SwaggerScalaModelConverter@451baad9
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - defineModel Function1 io.swagger.models.ModelImpl@5925ab17
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - defineModel Function1 io.swagger.models.ModelImpl@5925ab17
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - defineModel Function1RequestContextFutureRouteResult io.swagger.models.ModelImpl@7ae6d168
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - defineModel Function1RequestContextFutureRouteResult io.swagger.models.ModelImpl@7ae6d168
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG i.s.c.ModelConverterContextImpl - resolveProperty class com.bfg.domain.model.DomainEvents$SessionEvent$SessionCreated
11:31:23 [default-akka.actor.default-dispatcher-19] DEBUG io.swagger.jackson.ModelResolver - resolveProperty [simple type, class com.bfg.domain.model.DomainEvents$SessionEvent$SessionCreated]
Uncaught error from thread [default-akka.actor.default-dispatcher-19] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled for ActorSystem[default]
java.lang.InternalError: Malformed class name
at java.lang.Class.getSimpleName(Class.java:1330)
at java.lang.Class.getCanonicalName(Class.java:1399)
at io.swagger.jackson.ModelResolver._isOptionalType(ModelResolver.java:173)
at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:155)
at io.swagger.jackson.ModelResolver.resolveProperty(ModelResolver.java:110)
at io.swagger.scala.converter.SwaggerScalaModelConverter.resolveProperty(SwaggerScalaModelConverter.scala:55)
at io.swagger.converter.ModelConverterContextImpl.resolveProperty(ModelConverterContextImpl.java:80)
at io.swagger.converter.ModelConverters.readAsProperty(ModelConverters.java:58)
at io.swagger.jaxrs.Reader.addResponse(Reader.java:1017)
at io.swagger.jaxrs.Reader.parseMethod(Reader.java:939)
at io.swagger.jaxrs.Reader.read(Reader.java:322)
at io.swagger.jaxrs.Reader.read(Reader.java:172)
at com.github.swagger.akka.SwaggerHttpService.generateSwaggerJson(SwaggerHttpService.scala:93)
at com.github.swagger.akka.SwaggerHttpService.generateSwaggerJson$(SwaggerHttpService.scala:91)
at com.bfg.infrastructure.server.routes.SwaggerRoute$$anon$1.generateSwaggerJson(SwaggerRoute.scala:21)
at com.github.swagger.akka.SwaggerHttpService.$anonfun$routes$3(SwaggerHttpService.scala:120)
at akka.http.scaladsl.server.directives.RouteDirectives.$anonfun$complete$1(RouteDirectives.scala:47)
at akka.http.scaladsl.server.StandardRoute$$anon$1.apply(StandardRoute.scala:19)
at akka.http.scaladsl.server.StandardRoute$$anon$1.apply(StandardRoute.scala:19)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$mapRouteResult$2(BasicDirectives.scala:61)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$textract$2(BasicDirectives.scala:154)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$mapRequestContext$2(BasicDirectives.scala:43)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$textract$2(BasicDirectives.scala:154)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation.$anonfun$$tilde$1(RouteConcatenation.scala:44)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation.$anonfun$$tilde$1(RouteConcatenation.scala:44)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation.$anonfun$$tilde$1(RouteConcatenation.scala:44)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation.$anonfun$$tilde$2(RouteConcatenation.scala:47)
at akka.http.scaladsl.util.FastFuture$.strictTransform$1(FastFuture.scala:41)
at akka.http.scaladsl.util.FastFuture$.transformWith$extension1(FastFuture.scala:45)
at akka.http.scaladsl.util.FastFuture$.flatMap$extension(FastFuture.scala:26)
at akka.http.scaladsl.server.RouteConcatenation$RouteWithConcatenation.$anonfun$$tilde$1(RouteConcatenation.scala:44)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$textract$2(BasicDirectives.scala:154)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$mapRouteResultWith$2(BasicDirectives.scala:67)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$textract$2(BasicDirectives.scala:154)
at akka.http.scaladsl.server.directives.ExecutionDirectives.$anonfun$handleExceptions$2(ExecutionDirectives.scala:32)
at akka.http.scaladsl.server.Route$.$anonfun$asyncHandler$1(Route.scala:81)
at akka.stream.impl.fusing.MapAsync$$anon$23.onPush(Ops.scala:1172)
at akka.stream.impl.fusing.GraphInterpreter.processPush(GraphInterpreter.scala:499)
at akka.stream.impl.fusing.GraphInterpreter.processEvent(GraphInterpreter.scala:462)
at akka.stream.impl.fusing.GraphInterpreter.execute(GraphInterpreter.scala:368)
at akka.stream.impl.fusing.GraphInterpreterShell.runBatch(ActorGraphInterpreter.scala:571)
at akka.stream.impl.fusing.GraphInterpreterShell$AsyncInput.execute(ActorGraphInterpreter.scala:457)
at akka.stream.impl.fusing.GraphInterpreterShell.processEvent(ActorGraphInterpreter.scala:546)
at akka.stream.impl.fusing.ActorGraphInterpreter.akka$stream$impl$fusing$ActorGraphInterpreter$$processEvent(ActorGraphInterpreter.scala:725)
at akka.stream.impl.fusing.ActorGraphInterpreter$$anonfun$receive$1.applyOrElse(ActorGraphInterpreter.scala:740)
at akka.actor.Actor.aroundReceive(Actor.scala:513)
at akka.actor.Actor.aroundReceive$(Actor.scala:511)
at akka.stream.impl.fusing.ActorGraphInterpreter.aroundReceive(ActorGraphInterpreter.scala:650)
at akka.actor.ActorCell.receiveMessage(ActorCell.scala:519)
at akka.actor.ActorCell.invoke(ActorCell.scala:488)
at akka.dispatch.Mailbox.processMailbox(Mailbox.scala:257)
at akka.dispatch.Mailbox.run(Mailbox.scala:224)
at akka.dispatch.Mailbox.exec(Mailbox.scala:234)
at akka.dispatch.forkjoin.ForkJoinTask.doExec(ForkJoinTask.java:260)
at akka.dispatch.forkjoin.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:1339)
at akka.dispatch.forkjoin.ForkJoinPool.runWorker(ForkJoinPool.java:1979)
at akka.dispatch.forkjoin.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:107)
[ERROR] [SECURITY][05/25/2017 11:31:23.243] [default-akka.actor.default-dispatcher-19] [akka.actor.ActorSystemImpl(default)] Uncaught error from thread [default-akka.actor.default-dispatcher-19] shutting down JVM since 'akka.jvm-exit-on-fatal-error' is enabled
[INFO] [05/25/2017 11:31:23.248] [Thread-0] [CoordinatedShutdown(akka://default)] Starting coordinated shutdown from JVM shutdown hook
11:31:23 [default-akka.actor.default-dispatcher-2] INFO com.bfg.infrastructure.server.Server - Shutting down
[ERROR] [05/25/2017 11:31:23.265] [default-akka.actor.default-dispatcher-2] [akka.actor.ActorSystemImpl(default)] Outgoing request stream error (akka.stream.AbruptTerminationException)
Process finished with exit code 255
Hi,
nice project, do you have any hints on how to use this with Java?
Regards
Dominik
Hi,
Need an help here :
override protected def routes = authenticated { uc => concat(assignRole(uc), getUserInfo(uc))}
and signature of a function looks like
def assignRole(uc: UserContext): Route = path(JavaUUID)
Now when i try to add a
@ApiImplicitParams(Array(
new ApiImplicitParam(name = "userId", required = true, dataType = "string", paramType = "body")
))
and generate doc the doc contains
"parameters" : [ {
"in" : "body",
"name" : "body",
"required" : false,
"schema" : {
"$ref" : "#/definitions/UserContext"
}
}, {
"name" : "userId",
"in" : "body",
"required" : true,
"type" : "string"
},
Since there are 2 params of type body the validation of doc fails has more than 1 body param
Any suggestions how we can override the default body tag
Hi! Like the title said: Authorization
is going to be treated as header
, but the generated swagger code cannot find the reference model as below
- name: "authorization"
in: "header"
description: "Bearer authorization token"
required: true
type: "models.Authorization" // <-----
However, when changing paramType
to body
, it can find the model Authorization:
- in: "body"
name: "authorization"
description: "Bearer authorization token"
required: true
schema:
$ref: "#/definitions/Authorization"
Unfortunatly this doesn't meet the requirement to make Authorization as header
.
Env:
Scala - 2.12.2
swagger-akka-http - 0.9.1
akka-http - 10.0.5
Besides, the following is the way to apply parameter information:
@ApiOperation(value = "Get brand family", httpMethod = "GET", response = classOf[BrandFamily])
@ApiImplicitParams(Array(new ApiImplicitParam(name = "Authorization", value = "Bearer authorization token", dataType = "models.Authorization", paramType = "header", required = true)))
@ApiResponses(Array(
new ApiResponse(code = 400, message = "Bad Request"),
new ApiResponse(code = 401, message = "Unauthorized"),
new ApiResponse(code = 403, message = "Forbidden")
))
Hi,
i have my model classes annotate with @XmlRootElement, @xmlelement... This classes are annotated as @QueryParam in the service class.
It's possible with swagger-akka-http to recognize these jaxb annotations and to visualize the model classes into definitions section of swagger.json? If yes, how?
I have tried, and in the parameters section i find the param with in="query" and type="string" (even if it's a complex object) but nothing is in definitions section.
Many thx
When upgrading to akka-http 10 and using swagger-akka-http (version 0.7.1 and 0.8.1) I am getting a runtime error when calling the swagger.json route with:
Exception thrown io.swagger.converter.ModelConverter: Provider io.swagger.scala.converter.SwaggerScalaModelConverter could not be instantiated
I am using the latest swagger stuff (3.x) and for the SwaggerDocService
the basePath
no longer exists (which makes this portion of the README slightly outdated)
is it expected now to explicitly define the base path (like ours always start with /rest/v1
) in the @Path
annotations (where applicable)? it's a slight inconvenience but maybe there is a change the way base path is set and i'm just unaware of it.
thanks!
10x
Hello,
If I understand correctly, each path segments needs to be in a variable and we will annotate the variable with swagger.
Thank you
It would be great to support Swagger 1.5.11 so "format" can be set for ApiImplicitParams.
This would allow automatic tools like https://bitbucket.org/atlassian/swagger-request-validator to check the format of the type (int32/int64 for int types), as it is defined in the standard
Hi
I am new to swagger and http-akka. When I annotate my GET method I get this,
"/questions/{id}" : {
"get" : {
"tags" : [ "questions" ],
"summary" : "Retrives a question",
"description" : "",
"operationId" : "GetQuestion",
"produces" : [ "application/json" ],
"parameters" : [ {
"in" : "body",
"name" : "body",
"required" : false,
"schema" : {
"type" : "string"
}
}, {
"name" : "id",
"in" : "path",
"description" : "The unique id of the question",
"required" : true,
"type" : "string",
"default" : "test"
} ],
"responses" : {
"200" : {
"description" : "Returns the info if found",
"schema" : {
"$ref" : "#/definitions/Question"
}
},
"404" : {
"description" : "Resource not found"
},
"500" : {
"description" : "Internal server error"
}
}
}
}
},
But I have not specified any body. Seems it just turns up automatically.
What do I do wrong, here is the anotation on the method.
@path("/{id}")
@ApiOperation(value = "Retrives a question", nickname = "GetQuestion", httpMethod = "GET", response = classOf[Question])
@ApiImplicitParams(Array(
new ApiImplicitParam(name = "id", value = "The unique id of the question", defaultValue="test", required = true, dataType = "string", paramType = "path")
))
@ApiResponses(Array(
new ApiResponse(code = 200, message = "Returns the info if found", response = classOf[Question]),
new ApiResponse(code = 404, message = "Resource not found"),
new ApiResponse(code = 500, message = "Internal server error")
))
def getById(id: String): Future[Option[Question]] = Future {
questions.find(_.id == id)
}
If you do not set nickName
, the operationId
defaults to the method name. I can't figure out where this behaviour comes from. Shouldn't this remain empty if not provided ?
If anyone could shed some light on this would be greatly appreciated.
Hello everybody!
I've got something like this in my code
@GET
@Path("/{id}")
@ApiOperation(
value = "Return item with given id",
response = classOf[BaseResponse],
responseContainer = "List")
@ApiResponses(value = Array(new ApiResponse(code = 200, message = "Item response", response = classOf[BaseResponse])))
def getItemByIdR: Route = (id & get) { key =>
getItemById(key).okJson()
}
Where BaseResponse
is also annotated with @ApiModel
, but when I request swagger.json, it has following return type of an operation:
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Function1RequestContextFutureRouteResult"
}
}
For this code:
val advertiserRoute: Route = pathPrefix("advertiser") {
post(
concat(
(path("register") & entity(as[Advertiser])) { advertiser =>
register(advertiser)
}
)
)
}
@Path("/register")
@ApiOperation(
httpMethod = "POST",
value = "Register new advertiser",
nickname = "RegisterNewAdvertiser"
)
@ApiImplicitParams(Array(
new ApiImplicitParam(dataTypeClass = classOf[Advertiser], value = "New advertiser", paramType = "body", name = "body", required = true)
))
@ApiResponses(Array(
new ApiResponse(code = 400, message = "User with this email already exists")
))
def register(advertiser: Advertiser): Route = {
complete(StatusCodes.OK)
}
generated Json contains two body parameters:
swagger: '2.0'
info:
description: ''
version: ''
title: ''
termsOfService: ''
host: '0.0.0.0:6792'
basePath: /
tags:
- name: advertiser
schemes:
- http
paths:
/advertiser/register:
post:
tags:
- advertiser
summary: Register new advertiser
description: ''
operationId: register
consumes:
- application/json
produces:
- application/json
parameters:
- in: body
name: body
required: false
schema:
$ref: '#/definitions/Advertiser'
- in: body
name: body
description: New advertiser
required: true
schema:
$ref: '#/definitions/Advertiser'
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/Function1RequestContextFutureRouteResult'
'400':
description: User with this email already exists
securityDefinitions: {}
definitions:
Function1:
type: object
Function1RequestContextFutureRouteResult:
type: object
Advertiser:
type: object
required:
- company
- email
- name
- website
properties:
name:
type: string
company:
type: string
website:
type: string
email:
type: string
but if I change this code to:
val advertiserRoute: Route = pathPrefix("advertiser") {
post(
concat(
register
)
)
}
@Path("/register")
@ApiOperation(
httpMethod = "POST",
value = "Register new advertiser"
)
@ApiImplicitParams(Array(
new ApiImplicitParam(dataTypeClass = classOf[Advertiser], value = "New advertiser", paramType = "body", name = "body", required = true)
))
@ApiResponses(Array(
new ApiResponse(code = 400, message = "User with this email already exists"),
new ApiResponse(code = 403, message = "already authenticated")
))
def register: Route = {
(path("register") & entity(as[Advertiser])) { advertiser =>
complete(StatusCodes.OK)
}
}
just removing parameter json is generated fine:
swagger: '2.0'
info:
description: ''
version: ''
title: ''
termsOfService: ''
host: '0.0.0.0:6792'
basePath: /
tags:
- name: advertiser
schemes:
- http
paths:
/advertiser/register:
post:
tags:
- advertiser
summary: Register new advertiser
description: ''
operationId: RegisterNewAdvertiser
produces:
- application/json
parameters:
- in: body
name: body
description: New advertiser
required: true
schema:
$ref: '#/definitions/Advertiser'
responses:
'200':
description: successful operation
schema:
$ref: '#/definitions/Function1RequestContextFutureRouteResult'
'400':
description: User with this email already exists
securityDefinitions: {}
definitions:
Function1:
type: object
Function1RequestContextFutureRouteResult:
type: object
Advertiser:
type: object
required:
- company
- email
- name
- website
properties:
name:
type: string
company:
type: string
website:
type: string
email:
type: string
Hey,
Unless I somehow failed in my search it seems that it is not possible to specify no response at least i seems to insist that I have an status 200 with example return looking like "{}", however, my return is blank and status is 201.
@ApiOperation(httpMethod = "POST", value = "Create a new thing") @ApiImplicitParams(Array( new ApiImplicitParam(value = "The thing to create", paramType = "body", required = true, dataTypeClass = classOf[Thing]) )) @ApiResponses(Array(new ApiResponse(code = 201, message = "Thing created"))) def createThing() = { entity(as[Thing]) { thing => { complete(StatusCodes.Created) } } }
I'd very must like for it to actually reflect what's happening, basically no output :) so no bogus status 200 and no examples that are simply not correct
I have 3 services like shown below :
I have one class DepartmentRest which has all these 3 services and have annotated with swagger annotations. But when I check the swagger generated documentation, it only has 2 of the 3 services. I am not able to understand how to do for nested urls' with multiple params. I have scenarios where I have 9-10 separate url's under a single base url (eg: department )
I have added the code in a GIST here.
Can anyone please give a sample usage for my case ?
basically the endpoint is generating the swagger JSON/yaml but when I try to plug it into the editor, I get semantic errors about "Multiple body parameters are not allowed".
Any idea?
Hi! I'd like a place to ask simple questions like, say, where is the sequence of modelTypes mentioned in the README defined?
Might you be willing to take 5 minutes and add a gitter channel for swagger-akka-http?
I am using this tool on a large Akka HTTP project and I am very pleased with it. Keep up the good work!
I need a bit of help with one issue though. I would like to enrich all model types with an x-nullable vendor extension for property types of Option. This seems to be the most common workaround to support nullable types in Swagger 2.
I cannot decorate the models directly with annotations (because they are generated by protoc) and I am looking for a way to enrich the model types with nullable hints.
I see that there is a io.swagger.jaxrs.config.ReaderListener I can use to change the swagger document but I am not sure where I could register it and how to add the extension values on Option type. If you give me some direction, I could create a PR for this if code changes are needed.
Thank you for your help in advance.
I got an OPTIONS method that does not return a body. If I don't set the response and leave it to default to response = classOf[Void]
a new object definition appears in the swagger json:
"definitions": { "Function1": { "type": "object" } }
I also tried to set it to response = classOf[Unit]
with no effect.
@ApiOperation(httpMethod = "OPTIONS", response = classOf[String], value = "Some summary")
would fix this but it's not correct.
Am I doing something wrong or is there a bug in the way this is automatically-derived?
Hi, using the latest release, I get this exception. Please let me know how can I help with more information to track the cause of this and what I could be doing wrong. Thank you
java.lang.UnsupportedOperationException
at java.util.AbstractList.add(AbstractList.java:148)
at java.util.AbstractList.add(AbstractList.java:108)
at io.swagger.models.Swagger.addScheme(Swagger.java:193)
at io.swagger.jaxrs.Reader.readSwaggerConfig(Reader.java:583)
at io.swagger.jaxrs.Reader.read(Reader.java:167)
at com.github.swagger.akka.SwaggerGenerator.filteredSwagger(SwaggerHttpService.scala:93)
at com.github.swagger.akka.SwaggerGenerator.filteredSwagger$(SwaggerHttpService.scala:92)
at mcc.movie.common.swagger.SwaggerDoc.filteredSwagger(SwaggerDoc.scala:17)
at com.github.swagger.akka.SwaggerGenerator.generateSwaggerJson(SwaggerHttpService.scala:72)
at com.github.swagger.akka.SwaggerGenerator.generateSwaggerJson$(SwaggerHttpService.scala:70)
at mcc.movie.common.swagger.SwaggerDoc.generateSwaggerJson(SwaggerDoc.scala:17)
at com.github.swagger.akka.SwaggerHttpService.$anonfun$routes$3(SwaggerHttpService.scala:107)
at akka.http.scaladsl.server.directives.RouteDirectives.$anonfun$complete$1(RouteDirectives.scala:47)
at akka.http.scaladsl.server.StandardRoute$$anon$1.apply(StandardRoute.scala:19)
at akka.http.scaladsl.server.StandardRoute$$anon$1.apply(StandardRoute.scala:19)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$mapRouteResult$2(BasicDirectives.scala:61)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$textract$2(BasicDirectives.scala:154)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$mapRequestContext$2(BasicDirectives.scala:43)
at akka.http.scaladsl.server.directives.BasicDirectives.$anonfun$textract$2(BasicDirectives.scala:154)
Hi,
is it possible to create the swagger docs from a provided swagger yaml file instead of using annotations in the code it self and let swagger-akka-http to generate all automatically ?
Thanks,
As we can see from the code the Type eventually is converted to the Class.
def getClassForType(t: Type): Class[_] = {
mirror.runtimeClass(t.typeSymbol.asClass)
}
So why cant we must have apiTypes of type Type instead of Class?
In my case specific case I have class, not Type and have to make redundant and very simple conversions to Type.
The reason for Class is that it is simply available in runtime from object reference, whereas Type is not, which forces you to do unnecessary complicated conversions even though eventually Class is needed.
I want to provide example JSON for the body of an HTTP POST request. If I provide a
new ApiImplicitParam(
name = "body",
required = false,
dataType = "string",
paramType = "body"
example = "{foo: bar}"
)
I end up with two "body" parameters in the swagger.json and in the rendered UI. How do I REPLACE the default "body" parameter so that I can provide an example?
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.