openapi springboot服务器生成器是否具有损坏的线程模型?

时间:2019-08-06 16:53:35

标签: java spring spring-boot spring-mvc openapi-generator

因此,我们正在尝试使用OpenAPI生成器,到目前为止,我们已经得到了混合的结果。

复制步骤:

  1. 下载openapi生成器jar:wget https://repo1.maven.org/maven2/org/openapitools/openapi-generator/4.0.3/openapi-generator-4.0.3.jar
  2. 为petstore示例生成springboot服务器:java -jar openapi-generator-cli-4.0.3.jar generate -g spring -i https://raw.githubusercontent.com/OAI/OpenAPI-Specification/master/examples/v3.0/petstore.yaml

您最终将获得如下所示的控制器类:

package org.openapitools.api;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.context.request.NativeWebRequest;
import java.util.Optional;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2019-08-06T15:08:49.070+01:00[Europe/London]")

@Controller
@RequestMapping("${openapi.swaggerPetstore.base-path:/v1}")
public class PetsApiController implements PetsApi {

    private final NativeWebRequest request;

    @org.springframework.beans.factory.annotation.Autowired
    public PetsApiController(NativeWebRequest request) {
        this.request = request;
    }

    @Override
    public Optional<NativeWebRequest> getRequest() {
        return Optional.ofNullable(request);
    }

}
/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech) (4.0.3).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */
package org.openapitools.api;

import org.openapitools.model.Error;
import org.openapitools.model.Pet;
import io.swagger.annotations.*;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.validation.annotation.Validated;
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;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.multipart.MultipartFile;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@javax.annotation.Generated(value = "org.openapitools.codegen.languages.SpringCodegen", date = "2019-08-06T15:08:49.070+01:00[Europe/London]")

@Validated
@Api(value = "pets", description = "the pets API")
public interface PetsApi {

    default Optional<NativeWebRequest> getRequest() {
        return Optional.empty();
    }

    @ApiOperation(value = "Create a pet", nickname = "createPets", notes = "", tags={ "pets", })
    @ApiResponses(value = { 
        @ApiResponse(code = 201, message = "Null response"),
        @ApiResponse(code = 200, message = "unexpected error", response = Error.class) })
    @RequestMapping(value = "/pets",
        produces = { "application/json" }, 
        method = RequestMethod.POST)
    default ResponseEntity<Void> createPets() {
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);

    }


    @ApiOperation(value = "List all pets", nickname = "listPets", notes = "", response = Pet.class, responseContainer = "List", tags={ "pets", })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "A paged array of pets", response = Pet.class, responseContainer = "List"),
        @ApiResponse(code = 200, message = "unexpected error", response = Error.class) })
    @RequestMapping(value = "/pets",
        produces = { "application/json" }, 
        method = RequestMethod.GET)
    default ResponseEntity<List<Pet>> listPets(@ApiParam(value = "How many items to return at one time (max 100)") @Valid @RequestParam(value = "limit", required = false) Integer limit) {
        getRequest().ifPresent(request -> {
            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
                    ApiUtil.setExampleResponse(request, "application/json", "null");
                    break;
                }
            }
        });
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);

    }


    @ApiOperation(value = "Info for a specific pet", nickname = "showPetById", notes = "", response = Pet.class, tags={ "pets", })
    @ApiResponses(value = { 
        @ApiResponse(code = 200, message = "Expected response to a valid request", response = Pet.class),
        @ApiResponse(code = 200, message = "unexpected error", response = Error.class) })
    @RequestMapping(value = "/pets/{petId}",
        produces = { "application/json" }, 
        method = RequestMethod.GET)
    default ResponseEntity<Pet> showPetById(@ApiParam(value = "The id of the pet to retrieve",required=true) @PathVariable("petId") String petId) {
        getRequest().ifPresent(request -> {
            for (MediaType mediaType: MediaType.parseMediaTypes(request.getHeader("Accept"))) {
                if (mediaType.isCompatibleWith(MediaType.valueOf("application/json"))) {
                    ApiUtil.setExampleResponse(request, "application/json", "null");
                    break;
                }
            }
        });
        return new ResponseEntity<>(HttpStatus.NOT_IMPLEMENTED);

    }

}

所以我的问题是这样的:我所能找到的一切都意味着Spring Controllers是多线程的,并且可以一次处理多个请求。代码生成器是否损坏?我在解释这完全错误吗?

PetsApiController的构造函数使我停顿了一下。如果每个请求都被自动接线一次,那意味着每个请求只有一个接线端?

    @org.springframework.beans.factory.annotation.Autowired
    public PetsApiController(NativeWebRequest request) {
        this.request = request;
    }

1 个答案:

答案 0 :(得分:2)

众所周知,摇摇欲坠的代码生成器很糟糕,我的朋友说生成器具有广度而不是深度。您可以为各种语言和框架生成框架,但是它们有严格的限制。例如,尝试使用Page<Something>或其他泛型从SwaggerDoc生成一个好的骨架。我很难过地说,它们几乎没有实用程序,并且这些工具往往只能以相反的方式可靠地工作,即先进行编码,然后生成SwaggerDoc。

在我工作过的一个地方,我非常喜欢一个很棒的概念,您可以在实现API之前先设计它,这听起来像是您正在尝试做的事情。某些IDE甚至支持生成的代码,并且有用于构建工具(如maven gradle等)的插件,可从您的Yaml生成代码。

但是在实践中,我花了几天时间尝试从这些工具中获得理想的结果并放弃了。我认为真正的问题是Swagger / OpenAPI仍然被大量视为文档工具,而不是设计工具。我还认为,尝试创建一个包罗万象的项目生成器会导致一开始就失败。

我本人试图自定义生成器使用的胡须模板,但是Java中的泛型是一个噩梦,您无法正常工作,因此我无法更改SwaggerDoc,然后更新代码,因为我的方法是生成一个接口,然后实现该接口,但是注释并没有被继承,因此我不得不复制所有代码,这意味着没有任何好处。