Code Monkey home page Code Monkey logo

vertx-swagger's People

Contributors

bignacio avatar gokhanakgul avatar inikolaev avatar loeti avatar lopesmcc avatar petebuletza avatar philippkumar avatar phiz71 avatar viiinc 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

Watchers

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

vertx-swagger's Issues

Enum Model generation is broken

Hi,

I have problem generating model files which contains enums.
I used swagger-codegen 2.2.3 via gradle plugin.

It is currently also reproducible at http://editor.swagger.io/

Steps to reproduce:

  1. Add enum model definition to API, e.g.:
  ErrorCode:
    type: string
    enum:
      - "REQUIRED_RESOURCE_ID_NOT_SET"
      - "REQUIRED_RESOURCE_NOT_FOUND"
      - "ALREADY_EXISTS"
      - "SOMETHING_ELSE"
  1. Generate Server -> java-vertx.
  2. Observer generated file for ErrorCode enum:
package io.swagger.server.api.model;

import java.util.Objects;

public enum ErrorCode {
    {values=[REQUIRED_RESOURCE_ID_NOT_SET, REQUIRED_RESOURCE_NOT_FOUND, ALREADY_EXISTS, SOMETHING_ELSE], enumVars=[{name=REQUIRED_RESOURCE_ID_NOT_SET, value="REQUIRED_RESOURCE_ID_NOT_SET"}, {name=REQUIRED_RESOURCE_NOT_FOUND, value="REQUIRED_RESOURCE_NOT_FOUND"}, {name=ALREADY_EXISTS, value="ALREADY_EXISTS"}, {name=SOMETHING_ELSE, value="SOMETHING_ELSE"}]}, 
}

Kind regards,
Alex

The generated MainVerticle's start mehtod always listens on port 8080

It would be very useful to all passing port number as a parameter along pom, or better to read the port from a config file.
The generator can have a switch to read the port from a parameter, a config file, or the default.
Also, it can copy the config file to a generated directory so that the start the app can load it not only for the port but also for other configurations items.
The Swagger cod-gen command line allows for such a config file, the -c config.json in this command:

java -cp swagger-codegen-cli-2.2.3.jar;vertx-swagger-codegen-1.0.0.jar io.swagger.codegen.SwaggerCodegen generate -l java-vertx -o gen -i swagger.json -c config.json

Swagger-Codegen module fails to generate operation that consumes a list in the body parameter

Fails to generate operations that consume lists in the body parameter
i.e.: if the spec has something like:

  /operation:
    put:
      parameters:
        - name: updateModel
          in: body
          schema:
            type: array
            items:
              type: string
...

This is because Swagger Codegen, for some reason, is not populating the "baseType" variable for body type parameters.

A quick fix is add the following code to the JavaVertXServerGenerator.postProcessOperations() method:

            (...)
            for (CodegenOperation operation : ops) {
                (...)
                if (operation.getHasBodyParam() && operation.bodyParam.isListContainer) {
                    operation.bodyParam.baseType = operation.bodyParam.items.items.datatype;
                }
            }
            (...)

Not pretty, but it works.

Unfortunately, as the code is right now, nested lists are not supported, but that is another issue...

Support operationId as event name

Swagger API specification supports operationId property which allows to specify custom ID of an operation.

What I would like is if operationId is specified, then use its value, else auto-generate event name like you do now.

If you check Swagger file which you use in tests you can notice that every operation there has an operationId.

Runtime compatibility to swagger codegen 2.2.2 broken

With swagger-api/swagger-codegen#4326 the CodegenModel class of swagger-codgen has changed. (Boolean object properties have been replaced by the primitive counterpart boolean)

<swagger-codegen.version>2.2.1</swagger-codegen.version> => ok
<swagger-codegen.version>2.2.2</swagger-codegen.version> => Runtime Error NoSuchFieldError: isEnum does not exist.

[INFO] ------------------------------------------------------------------------
[INFO] BUILD FAILURE
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.296 s
[INFO] Finished at: 2017-03-07T17:37:47+01:00
[INFO] Final Memory: 16M/307M
[INFO] ------------------------------------------------------------------------
[ERROR] Failed to execute goal io.swagger:swagger-codegen-maven-plugin:2.2.2:generate (vertx.server.stub) on project ebanking: Execution vertx.server.stub of goal io.swagger:swagger-codegen-maven-plugin:2.2.2:generate failed: An API incompatibility was encountered while executing io.swagger:swagger-codegen-maven-plugin:2.2.2:generate: java.lang.NoSuchFieldError: isEnum

Make generated API classes asynchronous?

Hi there,

I am just starting using vert.x, and I was very happy to see that you guys implemented a swagger code generator! This is very helpful.

This is more a question than an issue, so feel free to close. I am wondering why the generated APIs are synchronous. A generated verticle calls the API object's method and blocks until it completes, then replies to the eventbus message. Wouldn't it be much better and more the vert.x way to do that asynchronously? Aren't you otherwise blocking one of the event loops? Or did I miss something here?

In my use case, I want to contact a keycloak server from the API interface implementation to validate a token, using the vert.x OAuth2 API, which is of course also asynchronous. So blocking seems unacceptable here.

I have a fork of this project where I generate void-only methods in generated API classes and have Handler<AsyncResult<ResultType>> as last argument. Feel free to check it out.

It conflicts with what has been recently done in this repo regarding exception handling and error codes, but it should be easy to add something similar to the async approach, I might do that in the near future.

Cheers
Philipp

Add validation of path parameter names

Vert.X has a limitation on the names of path parameters placeholders:

The placeholders consist of : followed by the parameter name. Parameter names consist of any alphabetic character, numeric character or underscore.

Need to add validation for parameters names which would report an error if parameter doesn't conform to the Vert.X requirements.

I had an issue with parameters which contain dash, e.g.: path-with-dash
When we try to pass this parameter to Vert.X it's converted to :path-with-dash and framework converts it to regular expression which looks like this: (?<path>[^/]+)-with-dash

Generated code for query parameters throws exception when parameter is not prodived

Assuming a get method using optional query parameters, the generated code in the corresponding Verticle always expects a value (except for strings). Hence if a parameter is not present or its value is not provided (e.g., for integer) it throws an error, which eventually causes the server to return a "server internal error 500" error.
Here is a sample of my Swagger:

        "/loans": {
            "get": {
                "summary": "List of loans",
                "description": "All the loans of a single user",
                "tags": [
                    "Loans"
                ],
                "operationId": "listLoans",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "type": "string",
                        "description": "loan status"
                    },
                    {
                        "name": "page",
                        "in": "query",
                        "required": false,
                        "type": "number",
                        "format": "int32",
                        "description": "The page number of the slice that should be returned.",
                        "default": 0,
                        "minimum": 0,
                        "x-example": 1
                    },
                    {
                        "name": "size",
                        "description": "The size of the slice that should be returned.",
                        "in": "query",
                        "required": false,
                        "type": "number",
                        "format": "int16",
                        "default": 10,
                        "minimum": 1,
                        "maximum": 1000
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A paged array of loans",
                        "headers": {
                            "x-next": {
                                "type": "string",
                                "description": "A link to the next page of responses"
                            }
                        },
                        "schema": {
                          "type": "array",
                          "items": {
                            "$ref": "#/definitions/Loan"
                          }                           
                        }
                    }
                }
            },

The generated Java code for the page parameter is BigDecimal page = Json.mapper.readValue(message.body().getString("page"), BigDecimal.class);, which obviously fails when parameter is not provided. The expected behavior is to set it to default when not provided, and because it is optional, even if no default value is defined, it should the generated code should simply not set the variable, leaving it to the language's variable initialization.
Is there anything that I can configure to achieve the expected behavior?

CORS filter configuration

Hi,

I am trying to host the swagger.json through the swagger ui.
I have hosted an api which would return the swagger.json and I am trying to use in the swagger ui
But I am running into CORS issue

I tried setting this in the MainVerticle class
swaggerRouter.route().handler(CorsHandler.create("*")
.allowedMethod(io.vertx.core.http.HttpMethod.GET)
.allowedMethod(io.vertx.core.http.HttpMethod.POST)
.allowedMethod(io.vertx.core.http.HttpMethod.OPTIONS)
.allowCredentials(true)
.allowedHeader("Access-Control-Allow-Method")
.allowedHeader("Access-Control-Allow-Origin")
.allowedHeader("Access-Control-Allow-Credentials")
.allowedHeader("Content-Type"));

But still no luck, I am running into the same issue. Any help around this is much appreciated. Thanks

Problems using RX version of SwaggerRouter

Hi,

I am using the SwaggerRouter and really like the way it is working. I am interested in using the RX version of SwaggerRouter io.vertx.rxjava.ext.swagger.router.SwaggerRouter

I could get things working with the core version, but for the RX version I get an empty response. I think I am missing something very basic. Any help in this regard is much appreciated

I am pasting the sample code

vertxFileSystem.readFile("swagger.json", readFile -> {
      if (readFile.succeeded()) {
        Swagger swagger = new SwaggerParser().parse(readFile.result().toString());
        Router swaggerRouter = SwaggerRouter.swaggerRouter(Router.router(vertx), swagger, vertx.eventBus(), new OperationIdServiceIdResolver());
        deployVerticles();
      vertx.createHttpServer().requestHandler(swaggerRouter::accept).rxListen(9004).subscribe(server -> {

          LOGGER.info("API started at: {}", ZonedDateTime.now().format(DateTimeFormatter.BASIC_ISO_DATE.ISO_INSTANT));
          future.complete();
        }, error -> {
          LOGGER.error("Server unable to start: {}", error.getMessage());
          future.fail("Server unable to start");
        });

      } else {
        future.fail(readFile.cause());
      }
    });

I have implemented the Verticle by extending the RX version of AbstractVerticle
The server starts up correctly and the request is routed correctly but the response JSON is not rendered

This is my verticle implementation

vertx.eventBus().<JsonObject> consumer("getProductList").handler(message -> { try { message.reply(new JsonObject().put("message", "Hello World").encodePrettily()); } catch (Exception e) { message.fail(101,"unexpected Error"); } });

If you can provide a sample example on how to use the RX version of Swagger Router that would be good. Please feel free to move this if you think it is not an issue. Just need some pointers to see if I am missing anything.

On SwaggerRouter, request headers should be added to DeliveryOptions and not replace existing ones

On SwaggerRouter, request headers are at the moment replacing any existing headers within the DeliveryOptions.
We should instead be adding the request headers to the DeliveryOptions.

As it is:

DeliveryOptions deliveryOptions = configureMessage != null?(DeliveryOptions)configureMessage.apply(context):new DeliveryOptions();
deliveryOptions.setHeaders(context.request().headers());
eventBus.send(serviceId, message, deliveryOptions, (operationResponse) -> {
    (...)
} 

As it should be:

DeliveryOptions deliveryOptions = configureMessage != null?(DeliveryOptions)configureMessage.apply(context):new DeliveryOptions();
context.request().headers().forEach(entry -> deliveryOptions.addHeader(entry.getKey(), entry.getValue()));
eventBus.send(serviceId, message, deliveryOptions, (operationResponse) -> {
    (...)
} 

Access to swagger spec object from all verticles

In the generated code, the Swagger spec object is created as a member of the start method of the MainApiVarticle class. As done here:
Swagger swagger = new SwaggerParser().parse(readFile.result().toString(Charset.forName("utf-8")));
In many places, it is needed to access this object. For example, I have a SystemApiVerticle that exposes information about the running system. One of the endpoints needs to get API name, version, and the tags to report them to the user.
Currently, I must to either repeat the above code in other places or override the start method to have the Swagger object and keep it for further use.
It would be good to make this object available to all other Verticles as well as service implementations.
A similar argument may go to the SwaggerRouter, but currently, I don't have a scenario that touches the router.

Enable CORS

Hey @phiz71, Can you please tell me how to enable Cross Origin Resource Sharing (CORS) with your vertx Server generator? Looks the current routes wont support that.

Please explain what do you mean by "/path/to/swagger-codegen-distribution"

In the command "java -cp /path/to/swagger-codegen-distribution:/path/to/vertx-swagger-codegen-1.0.0-SNAPSHOT.jar io.swagger.codegen.SwaggerCodegen -l java-vertx -o ./test -i path/toSwagger/definition --group-id your.group.id --artifact-id my.api.vertx", Please explain what do you mean by "/path/to/swagger-codegen-distribution"

Problem with the data type of parameters' default values

In xApiVerticle, a handler that needs to extract the values of a parameter does it by accessing message.body(). It has a problem with not-provided parameters.
For example, in this URL www.example.com/api/loans?status=x&page=1&size=10 the LoansApiVerticle has a listLoansHandler method that tries to extract and check the page parameter like this: if(message.body().getString("page") != null). Now, if the page parameter is not provided (it is optional), the getString method throws an exception and causes the request to fail!
The problem is that when a parameter is not provided via the request, it is set to its default (by the router). In the above-mentioned case, the page parameter is an integer, hence its value is stored as an integer in message.body() but the if checks for a string!
Assuming the Swagger spec is correct, the router should convert the default values to string and then pass them to the handlers. OR to respect the types set in the spec from the beginning (when constructing the message and its body).
I would also suggest, for optional parameters, to first check whether the message.body() contains the parameter and if so, then try to get its value. Something like if(message.body().containsKey("page") && message.body().getString("page") != null). If the key is available, then JsonObject itself has a getInteger which can be used; it does the type checks/casting required. It also provides get operators for many other types, which I would recommand to use.

content-type information in response

Is there a way to set the content-type for the response in the vertx-swagger-router? The swagger UI needs this information otherwise the response is not displayed, only "Unknown response type".

Required schema properties not returning http error code

I'm new enough to Swagger, so this may not be part of the spec so correct me if im wrong.
But i'm trying to force that schema properties are required through the swagger-router module, and if required properties are not found then some 4xx http error code is returned.

For example:

/test
  post:
    summary: x
      operationId: test
      required: true
      parameters:
        schema:
          type: object
          required:
            - lat
            - long
          properties:
            lat:
              type: number
            long:
              type: number

When I send an empty {} body without the required field properties lat or lng, the message is still sent to my event bus consumer for that endpoint, instead of returning a http error code. Is this an issue or is this the expected behaviour?

MainApiException extend RuntimeException instead

Can we have MainApiException extend RuntimeException instead of Exception?
This would make them RxJava friendly, as we wouldn't need to wrap them into a unchecked exception before throwing.

Thanks.

Ability to manage errors in a custom way

I was trying work out a way of getting customizable errors from the SwaggerRouter when something fails. Right now it seems that it is only possible to get 400 Bad Request from any Runtime Exception, and any error on the handling of the request is automatically managed as well, from com.github.phiz71.vertx.swagger.router.SwaggerRouter:

 private static void configureRoute(Route route, String serviceId, Operation operation, EventBus eventBus, Function<RoutingContext, DeliveryOptions> configureMessage) {
...
        route.handler(context -> {
            try {
                JsonObject message = new JsonObject();
                operation.getParameters().forEach(parameter -> {
                    String name = parameter.getName();
                    Object value = PARAMETER_EXTRACTORS.get(parameter.getIn()).extract(name, parameter, context);
                    message.put(name, value);
                });

                // callback to configure message e.g. provide message header values
                DeliveryOptions deliveryOptions = configureMessage != null ? configureMessage.apply(context) : new DeliveryOptions();

                eventBus.<String> send(serviceId, message, deliveryOptions, operationResponse -> {
                    if (operationResponse.succeeded()) {
                        if (operationResponse.result().body() != null) {
                            vertxLogger.debug(operationResponse.result().body());
                            manageHeaders(context.response(), operationResponse.result().headers());
                            context.response().end(operationResponse.result().body());
                        } else {
                            context.response().end();
                        }
                    } else {
                        vertxLogger.debug("Internal Server Error", operationResponse.cause());
                        manageError((ReplyException)operationResponse.cause(), context.response());
                    }
                });
            } catch (RuntimeException e) {
                vertxLogger.debug("sending Bad Request", e);
                badRequestEnd(context.response());
            }

        });

I'd like to extend the catch bits and the else part (when the operation does not succeed). What do you advise? This is a static method, the operations aren't abstract, I am guessing the only way is customizing it in a fork. Thanks.

Swagger pattern validation

Hi,

Swagger contract allows Patterned fields, which declare a regex pattern for the field name
It would be really elegant if SwaggerRouter could implement this validation. Currently we are doing this regex validation in the code, but doing it as part of the swagger contract is more elegant.

Generated XXXApiVerticle does not support primitive types

In the SwaggerRouter class the path parameters are extracted and put on the vertx eventbus packed in a JsonObject.
`...

JsonObject e = new JsonObject();
operation.getParameters().forEach((parameter) -> {
String name = parameter.getName();
Object value = ((ParameterExtractor)PARAMETER_EXTRACTORS.get(parameter.getIn())).extract(name, parameter, context);
e.put(name, value);
});`

If the value is not a JsonObject but a e.g. Long or String, the generated code fails with a ClassCastException. It expects a JsonObject. See:

{{{dataType}}} {{paramName}} = Json.mapper.readValue(message.body().getJsonObject("{{paramName}}").encode(), {{{dataType}}}.class);

The code-gen to have an option to generate JsonObjects for the Swagger definitions, instead of POJOs

I have a set of services that work with MongoDB backend and receive native JSON data.
I want to send this data to the client, but because the Swagger definitions are generated as POJOs, I have to materialize the received JSON objects to Java classes. Later, in the Verticles, these Java objects are once more serialized as JSON and sent to the requesting client. I suggest these two transformations are just waste of CPU and Memory! It would be good to have a switch to tell the code-gen to generate JsonObjects from the Swagger definitions. In this case, instead of e.g., User, Product, and Store, only JsonObject is used and passed between layers. Also, the Verticles do not need to convert POJOs to JSON and make them pretty before sending them to clients.
The same concept should apply to lists and arrays of objects.

A string with format uuid generates code that doesn't compile

a route with a parameter like this

  uuidParam:
    name: some_uuid
    description: a uuid
    in: path
    required: true
    type: string
    format: uuid

generates this code in the DefaultApiVerticle

UUID someUuid = message.body().getString("some_uuid");

which obviously doesn't compile. For now I have a not great workaround here inve1@58e0ea0
but this is the first time I've looked at swagger-codegen or mustache, so perhaps there's a nicer way (and I haven't looked into other string/format combinations that might generate other types in java).

Seems like mustache doesn't support conditionals so the only other way to do it would be a runtime detection which kinda sounds worse (you'd end up doing that detection for real strings as well on each call? meh)

Anyway, it's broken.. thought I'd report it

Implementing a custom Auth provider is not considered

When a path in a Swagger API spec declares secuirty, e.g., BASIC, the code gen creates a calls for User user = SwaggerRouter.extractAuthUserFromMessage(message); from the corresponding Verticle. This call retrieves the user form the headers (which the reason is not obvious to me!), and assigns an AuthProvider to the user. I would like to see how and where to do the followings:

  1. The above-mentioned procedure does not do the authentication. It should call the authProvider.authenticate(..., ...) method and decide to route the request to the implementation or to refuse it. I mean, the router can either pass the request to the implementation or reject the request with an Unauthorized status code and proper headers taken from the Wagger spec.

  2. How must a user login for the first time? Let's say I have a login endpoint; how this endpoint gets an object of AuthProvider?

  3. It is not practical to pass the username/password alongside all the requests, how can I generate and send to the client a token (let's say a random string) that can be passed to subsequent API calls as an evidence to show that the use is still authenticated. (This is something I would like the router checks and does proper action, according to #1 above.)

  4. I have my own specific authentication logic; how can I develop my own xAuthProvider (that implements Vertx's AuthProvider) and register it with the generated authentication mechanism? For example, a call like createServiceImplementation in verticles, using a dependency injection such as Guice, or even via a config file. This auth provider should be accessible to the login endpoint for logging in and out, as well as to the Swagger router to perform subsequent auth checks on incoming requests.

  5. The official PetStore swagger file comes with security and access control on some of the paths, it would be great if the there is a sample code here generated from that spec and a custom (even empty) auth provider.

Better management of artifacts version

All modules are in 1.0.0-SNAPSHOT and the generator module depends on the router module (not for code but for templates compatibilities).
I think I should rewrite pom files to handle the dependancies and to respect conventions

rootPackage is not configurable

On the vertx-swagger-codegen, the rootPackage variable is used determine the root package of generated resources, and is not configurable.
The packages for API and Model resources can be overriden using swagger's modelPackage and apiPackage parameters, but unfortunately MainApiVerticle and MainApiException package is impossible to change at the moment.

I'd propose to stop using rootPackage, and just use the three parameters that swagger provides: modelPackage, apiPackage and invokerPackage. I would change the MainApiVerticle and MainApiException classes to use the invokerPackage instead.

Would you like me prepare a PR with these changes?

Response code with headers are not supported

Assuming I have the following resource/path:

        "get": {
          "tags": [
            "Users"
          ],
          "summary": "Logs user into the system",
          "description": "",
          "operationId": "loginUser",
          "parameters": [
            {
              "name": "username",
              "in": "query",
              "description": "The user name for login",
              "required": true,
              "type": "string"
            },
            {
              "name": "password",
              "in": "query",
              "description": "The password for login in clear text",
              "required": true,
              "type": "string"
            }
          ],
          "responses": {
            "200": {
              "description": "successful operation",
              "schema": {
                "type": "string"
              },
              "headers": {
                "X-Rate-Limit": {
                  "type": "integer",
                  "format": "int32",
                  "description": "calls per hour allowed by the user"
                },
                "X-Expires-After": {
                  "type": "string",
                  "format": "date-time",
                  "description": "date in UTC when token expires"
                }
              }
            },
            "400": {
              "description": "Invalid username/password supplied"
            }
          }
        }
      }

On successful authentication, I want a way to access at set X-Rate-Limit and X-Expires-After response headers or there should be a mechanism to automatically set them. The generated code relies on the XXXApiImpl service class by passing a handler object to its methods; here loginUser method. But there is nothing on the handler that I can set response headers. Also, on the failure, the only option is to perform Future.failedfuture() and pass a throwable!
So, the question is how to access and set response headers from inside service classes? Or, what would be the best practice to do that?

Also, in the snippet, the router does not provide a way to set the response header, nor does it automatically!

            "401": {
              "description" : "Authentication information is missing or invalid",
              "headers": {
                "WWW_Authenticate": {
                    "type": "string"
                }
              }        
            }                  

Cannot serve static content

Hi,
I cannot serve static content when Swagger Router is enabled. I keep getting

Route matches: Route[ path:/docs pattern:null handler:io.vertx.rxjava.ext.web.Route$1@4454a62b failureHandler:null order:7 methods:[]]@1707828604 
Calling the  handler 

When calling the endpoint. With regular Vert.x router it does work.
I have to do this but it seems to be ignored

router.route().handler(CorsHandler.create("*")
                        .allowedMethod(HttpMethod.GET)
                        .allowedMethod(HttpMethod.POST)
                        .allowedMethod(HttpMethod.OPTIONS)
                        .allowedHeader("X-PINGARUNER")
                        .allowedHeader("Content-Type"));

                router.route("/docs").handler(
                        StaticHandler.create("src/main/resources/webroot/swagger-ui/index.html")
                );

                router.route("/docs/*").handler(
                        StaticHandler.create("src/main/resources/webroot/swagger-ui")
                );

after


 httpRequestServer = rxVertx.createHttpServer(
                                new HttpServerOptions().setPort(port).setHost(host)
                        ).requestHandler(swaggerRouter::accept).listen();

How can I serve static content using Swagger router? I don't want to have to declare it in swagger.json definition...

Use fluent setters in Models

Just like the generated Java clients, implement fluent setters in all models.
Example:

public class Example {

  private String value;

  //(...)

  public String getValue() {
    return this;
  }

  public void setValue() {
    this.value = value;
  }
  
  // fluent setter
  public Example value(String value) {
    this.value = value;
    return this;
  }

  // (...)
}

Does the generated code can be changed in a way that works with routingContext apart from eventBus?

Congratulations in such great project to integrate Swagger in a clean non-invasive way into Vert.x web.

I am a beginner with Vert.x and RxJava, and trying to use your library got generate routing from swagger.json. It is working nice generating code with the eventBus().consumer approach, but our team is more familiar with RoutingContext and handler in the RxJava way, like:

router.get("/path").handler(this::handlerName);

....
.flatMap(json -> {
                      
                    }).subscribe(next -> {
                               
                            ,
                            error -> {

                            });

Thank you!

Support for responses with schema type "array"

It seems that the SwaggerRouter class doesn't support responses with a schema type of "array".

My simple fix (for SwaggerRouter::configureRoute) looks like:

private static void configureRoute(Route route, String serviceId, Operation operation, EventBus eventBus) {
    Optional.ofNullable(operation.getConsumes()).ifPresent(consumes -> consumes.forEach(route::consumes));
    Optional.ofNullable(operation.getProduces()).ifPresent(produces -> produces.forEach(route::produces));

    route.handler(context -> {
        try {
            JsonObject message = new JsonObject();
            operation.getParameters().forEach(parameter -> {
                String name = parameter.getName();
                Object value = PARAMETER_EXTRACTORS.get(parameter.getIn()).extract(name, parameter, context);
                message.put(name, value);
            });
            String type = operation.getResponses().get("200").getSchema().getType();
            if ("array".equals(type)) {
            	eventBus.<JsonArray> send(serviceId, message, operationResponse -> {
            		if (operationResponse.succeeded()) {
            			if(operationResponse.result().body() != null)
            				context.response().end(operationResponse.result().body().encode());
            			else
            				context.response().end();
            		} else {
            			internalServerErrorEnd(context.response());
            		}
            	});
            }
            else {
                eventBus.<JsonObject> send(serviceId, message, operationResponse -> {
                    if (operationResponse.succeeded()) {
                        if(operationResponse.result().body() != null)
                            context.response().end(operationResponse.result().body().encode());
                        else
                            context.response().end();
                    } else {
                        internalServerErrorEnd(context.response());
                    }
                });
            }
        } catch (RuntimeException e) {
            VERTX_LOGGER.debug("sending Bad Request", e);
            badRequestEnd(context.response());
        }
        
    });

}

As an example I am using the petstore swagger.json API together with the vertx-swagger-codegen generator. In the generated ApiVerticle I had to fix the code as well. During runtime I get the following error:

Unhandled exception
java.lang.ClassCastException: io.vertx.core.json.JsonArray cannot be cast to io.vertx.core.json.JsonObject
at io.vertx.ext.swagger.router.SwaggerRouter.lambda$null$5(SwaggerRouter.java:81)
at io.vertx.core.eventbus.impl.EventBusImpl.lambda$convertHandler$125(EventBusImpl.java:333)
at io.vertx.core.eventbus.impl.HandlerRegistration.handleMessage(HandlerRegistration.java:207)
at io.vertx.core.eventbus.impl.HandlerRegistration.handle(HandlerRegistration.java:201)

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.