Skip to content

Instantly share code, notes, and snippets.

@erohana
Created August 17, 2020 10:45
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save erohana/2684cfdc4b8c889462997770b90b7921 to your computer and use it in GitHub Desktop.
Save erohana/2684cfdc4b8c889462997770b90b7921 to your computer and use it in GitHub Desktop.
openapi spring webflux server code generator
/**
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) ({{{generatorVersion}}}).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
package {{package}};
{{#imports}}import {{import}};
{{/imports}}
import io.swagger.annotations.*;
{{#jdk8-no-delegate}}
{{#virtualService}}
import io.virtualan.annotation.ApiVirtual;
import io.virtualan.annotation.VirtualService;
{{/virtualService}}
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
{{/jdk8-no-delegate}}
{{#useBeanValidation}}
import org.springframework.validation.annotation.Validated;
{{/useBeanValidation}}
import org.springframework.web.bind.annotation.CookieValue;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestPart;
{{#jdk8-no-delegate}}
{{^reactive}}
import org.springframework.web.context.request.NativeWebRequest;
{{/reactive}}
{{/jdk8-no-delegate}}
import org.springframework.web.multipart.MultipartFile;
{{#reactive}}
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;
{{/reactive}}
{{#useBeanValidation}}
import javax.validation.Valid;
import javax.validation.constraints.*;
{{/useBeanValidation}}
import java.util.List;
import java.util.Map;
{{#jdk8-no-delegate}}
import java.util.Optional;
{{/jdk8-no-delegate}}
{{^jdk8-no-delegate}}
{{#useOptional}}
import java.util.Optional;
{{/useOptional}}
{{/jdk8-no-delegate}}
{{#async}}
import java.util.concurrent.{{^jdk8}}Callable{{/jdk8}}{{#jdk8}}CompletableFuture{{/jdk8}};
{{/async}}
{{>generatedAnnotation}}
{{#useBeanValidation}}
@Validated
{{/useBeanValidation}}
@Api(value = "{{{baseName}}}", description = "the {{{baseName}}} API")
{{#operations}}
{{#virtualService}}
@VirtualService
{{/virtualService}}
public interface {{classname}} {
{{#jdk8-default-interface}}
{{^isDelegate}}
{{^reactive}}
default Optional<NativeWebRequest> getRequest() {
return Optional.empty();
}
{{/reactive}}
{{/isDelegate}}
{{#isDelegate}}
default {{classname}}Delegate getDelegate() {
return new {{classname}}Delegate() {};
}
{{/isDelegate}}
{{/jdk8-default-interface}}
{{#operation}}
/**
* {{httpMethod}} {{{path}}}{{#summary}} : {{.}}{{/summary}}
{{#notes}}
* {{.}}
{{/notes}}
*
{{#allParams}}
* @param {{paramName}} {{description}}{{#required}} (required){{/required}}{{^required}} (optional{{#defaultValue}}, default to {{.}}{{/defaultValue}}){{/required}}
{{/allParams}}
* @return {{#responses}}{{message}} (status code {{code}}){{#hasMore}}
* or {{/hasMore}}{{/responses}}
{{#isDeprecated}}
* @deprecated
{{/isDeprecated}}
{{#externalDocs}}
* {{description}}
* @see <a href="{{url}}">{{summary}} Documentation</a>
{{/externalDocs}}
*/
{{#virtualService}}
@ApiVirtual
{{/virtualService}}
@ApiOperation(value = "{{{summary}}}", nickname = "{{{operationId}}}", notes = "{{{notes}}}"{{#returnBaseType}}, response = {{{returnBaseType}}}.class{{/returnBaseType}}{{#returnContainer}}, responseContainer = "{{{returnContainer}}}"{{/returnContainer}}{{#hasAuthMethods}}, authorizations = {
{{#authMethods}}@Authorization(value = "{{name}}"{{#isOAuth}}, scopes = {
{{#scopes}}@AuthorizationScope(scope = "{{scope}}", description = "{{description}}"){{#hasMore}},
{{/hasMore}}{{/scopes}}
}{{/isOAuth}}){{#hasMore}},
{{/hasMore}}{{/authMethods}}
}{{/hasAuthMethods}}, tags={ {{#vendorExtensions.x-tags}}"{{tag}}",{{/vendorExtensions.x-tags}} })
@ApiResponses(value = { {{#responses}}
@ApiResponse(code = {{{code}}}, message = "{{{message}}}"{{#baseType}}, response = {{{baseType}}}.class{{/baseType}}{{#containerType}}, responseContainer = "{{{containerType}}}"{{/containerType}}){{#hasMore}},{{/hasMore}}{{/responses}} })
{{#implicitHeaders}}
@ApiImplicitParams({
{{#headerParams}}
{{>implicitHeader}}
{{/headerParams}}
})
{{/implicitHeaders}}
@RequestMapping(value = "{{{path}}}",{{#singleContentTypes}}{{#hasProduces}}
produces = "{{{vendorExtensions.x-accepts}}}", {{/hasProduces}}{{#hasConsumes}}
consumes = "{{{vendorExtensions.x-contentType}}}",{{/hasConsumes}}{{/singleContentTypes}}{{^singleContentTypes}}{{#hasProduces}}
produces = { {{#produces}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/produces}} }, {{/hasProduces}}{{#hasConsumes}}
consumes = { {{#consumes}}"{{{mediaType}}}"{{#hasMore}}, {{/hasMore}}{{/consumes}} },{{/hasConsumes}}{{/singleContentTypes}}
method = RequestMethod.{{httpMethod}})
{{#jdk8-default-interface}}default {{/jdk8-default-interface}}{{>returnTypes}} {{#delegate-method}}_{{/delegate-method}}{{operationId}}({{#allParams}}{{>queryParams}}{{>pathParams}}{{>headerParams}}{{>bodyParams}}{{>formParams}}{{>cookieParams}}{{#hasMore}},{{/hasMore}}{{^hasMore}}{{#reactive}}, {{/reactive}}{{/hasMore}}{{/allParams}}{{#reactive}}ServerWebExchange exchange{{/reactive}}){{^jdk8-default-interface}};{{/jdk8-default-interface}}{{#jdk8-default-interface}}{{#unhandledException}} throws Exception{{/unhandledException}} {
{{#delegate-method}}
return {{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}});
}
// Override this method
{{#jdk8-default-interface}}default {{/jdk8-default-interface}} {{>returnTypes}} {{operationId}}({{#allParams}}{{^isFile}}{{^isBodyParam}}{{>optionalDataType}}{{/isBodyParam}}{{#isBodyParam}}{{^reactive}}{{{dataType}}}{{/reactive}}{{#reactive}}{{#isListContainer}}Flux{{/isListContainer}}<{{{baseType}}}>{{/reactive}}{{/isBodyParam}}{{/isFile}}{{#isFile}}MultipartFile{{/isFile}} {{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}ServerWebExchange exchange{{/reactive}}){{#unhandledException}} throws Exception{{/unhandledException}} {
{{/delegate-method}}
{{^isDelegate}}
{{>methodBody}}
{{/isDelegate}}
{{#isDelegate}}
return getDelegate().{{operationId}}({{#allParams}}{{paramName}}{{#hasMore}}, {{/hasMore}}{{/allParams}}{{#reactive}}{{#hasParams}}, {{/hasParams}}exchange{{/reactive}});
{{/isDelegate}}
}{{/jdk8-default-interface}}
{{/operation}}
}
{{/operations}}
{{^reactive}}
{{#examples}}
{{#-first}}
{{#jdk8}}
{{#async}}
return CompletableFuture.supplyAsync(()-> {
{{/async}}getRequest().ifPresent(request -> {
{{#async}} {{/async}} {{/jdk8}}for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
{{/-first}}
{{#async}} {{/async}}{{^async}}{{#jdk8}} {{/jdk8}}{{/async}} if (mediaType.isCompatibleWith(MediaType.valueOf("{{{contentType}}}"))) {
{{#async}} {{/async}}{{^async}}{{#jdk8}} {{/jdk8}}{{/async}} String exampleString = {{>exampleString}};
{{#async}} {{/async}}{{^async}}{{#jdk8}} {{/jdk8}}{{/async}} ApiUtil.setExampleResponse(request, "{{{contentType}}}", exampleString);
{{#async}} {{/async}}{{^async}}{{#jdk8}} {{/jdk8}}{{/async}} break;
{{#async}} {{/async}}{{^async}}{{#jdk8}} {{/jdk8}}{{/async}} }
{{#-last}}
{{#async}} {{/async}}{{^async}}{{#jdk8}} {{/jdk8}}{{/async}} }
{{#jdk8}}
{{#async}} {{/async}} });
{{/jdk8}}
{{#async}} {{/async}} return new ResponseEntity<>({{#returnSuccessCode}}HttpStatus.valueOf({{{statusCode}}}){{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}});
{{#jdk8}}
{{#async}}
}, Runnable::run);
{{/async}}
{{/jdk8}}
{{/-last}}
{{/examples}}
{{^examples}}
return {{#jdk8}}{{#async}}CompletableFuture.completedFuture({{/async}}{{/jdk8}}new ResponseEntity<>({{#returnSuccessCode}}HttpStatus.OK{{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}}){{#jdk8}}{{#async}}){{/async}}{{/jdk8}};
{{/examples}}
{{/reactive}}
{{#reactive}}
{{#isListContainer}}Flux{{/isListContainer}}{{^isListContainer}}Mono{{/isListContainer}}<Void> result = {{#isListContainer}}Flux{{/isListContainer}}{{^isListContainer}}Mono{{/isListContainer}}.empty();
{{#examples}}
{{#-first}}
exchange.getResponse().setStatusCode({{#returnSuccessCode}}HttpStatus.valueOf({{{statusCode}}}){{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}});
for (MediaType mediaType : exchange.getRequest().getHeaders().getAccept()) {
{{/-first}}
if (mediaType.isCompatibleWith(MediaType.valueOf("{{{contentType}}}"))) {
String exampleString = {{>exampleString}};
result = ApiUtil.getExampleResponse(exchange, exampleString){{#isListContainer}}.flux(){{/isListContainer}};
break;
}
{{#-last}}
}
{{/-last}}
{{/examples}}
{{^examples}}
exchange.getResponse().setStatusCode({{#returnSuccessCode}}HttpStatus.OK{{/returnSuccessCode}}{{^returnSuccessCode}}HttpStatus.NOT_IMPLEMENTED{{/returnSuccessCode}});
{{/examples}}
return {{#isListContainer}}result.concatMap(aVoid -> Mono.empty()){{/isListContainer}}{{^isListContainer}}result.then(Mono.empty()){{/isListContainer}};
{{/reactive}}
{{#isMapContainer}}Map<String, {{{returnType}}}>{{/isMapContainer}}{{#isListContainer}}{{#reactive}}Flux{{/reactive}}{{^reactive}}List{{/reactive}}<{{{returnType}}}>{{/isListContainer}}{{^returnContainer}}{{#reactive}}Mono<{{{returnType}}}>{{/reactive}}{{^reactive}}{{{returnType}}}{{/reactive}}{{/returnContainer}}
@d3vAdv3ntur3s
Copy link

HI @erohana I noticed your post on the open api generator issue

This seemed like a quick win to change the complicated signature, e.g. Mono<ResponseEntity<Flux<ContactDTO>>> to Flux<ContactDTO>

I just created the 3 files you kindly shared, I'm using version 5.0.1 and this no longer works, appears to malform the output for anything Flux based:

error: illegal start of type
>> getAllContacts(@Min(0)@ApiParam(value = "The number of items to skip before starting to collect the result set.") @Valid @RequestParam(value = "offset", required = false) Integer offset,@Min(20) @Max(100) @ApiParam(value = "The numbers of items to return.", defaultValue = "20") @Valid @RequestParam(value = "limit", required = false, defaultValue="20") Integer limit, @ApiIgnore final ServerWebExchange exchange);

Whereas the the Mono based endpoints signature changed to the following, with semi-malformed output, going onto the next lines, but still valid Java:

Mono<ResponseEntity<Mono<ContactDTO>
>> addContact(@ApiParam(value = ""  )  @Valid @RequestBody(required = false) Mono<ContactDTO> contactDTO, @ApiIgnore final ServerWebExchange exchange);

Have you updated the templates since, thanks for your time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment