You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@servicecomb.apache.org by li...@apache.org on 2023/08/16 01:37:43 UTC
[servicecomb-java-chassis] 10/12: [SCB-2803]response support different media types
This is an automated email from the ASF dual-hosted git repository.
liubao pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/servicecomb-java-chassis.git
commit d3ab52dca88bb5d8abdcf5030076fe7ccf5217f5
Author: liubao <bi...@qq.com>
AuthorDate: Tue Aug 15 11:46:19 2023 +0800
[SCB-2803]response support different media types
---
.../generator/core/AbstractOperationGenerator.java | 54 ++++---
.../generator/core/OperationGeneratorContext.java | 65 ++++++++
.../annotation/ApiResponseMethodProcessor.java | 46 +++++-
.../annotation/ApiResponsesClassProcessor.java | 43 ------
.../annotation/ApiResponsesMethodProcessor.java | 45 +++++-
.../OperationMethodAnnotationProcessor.java | 53 ++++++-
.../generator/pojo/PojoSwaggerGenerator.java | 2 +-
...comb.swagger.generator.ClassAnnotationProcessor | 1 -
.../swagger/generator/core/TestApiOperation.java | 4 +-
.../swagger/generator/core/TestApiResponse.java | 16 +-
.../generator/core/TestOperationGenerator.java | 23 +--
.../OperationMethodAnnotationProcessorTest.java | 16 +-
.../swagger/generator/core/schema/Schema.java | 6 +-
.../resources/schemas/ParameterAnnotation.yaml | 11 ++
.../src/test/resources/schemas/Schema.yaml | 163 +++++++++++++++++++--
.../src/test/resources/schemas/pojoExample1.yaml | 18 +++
.../servicecomb/swagger/generator/jaxrs/Echo.java | 2 +-
.../generator/jaxrs/FullSwaggerService.java | 20 ++-
.../test/resources/schemas/ClassAnnotation.yaml | 12 ++
.../test/resources/schemas/FullSwaggerService.yaml | 35 ++++-
.../src/test/resources/schemas/echo.yaml | 78 +++++++++-
.../resources/schemas/DefaultParameterSchema.yaml | 36 +++++
.../src/test/resources/schemas/echo.yaml | 36 +++++
.../test/resources/schemas/mixupAnnotations.yaml | 96 ++++++++++++
.../src/test/resources/schemas/responseEntity.yaml | 60 ++++++++
25 files changed, 805 insertions(+), 136 deletions(-)
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
index dbbc9ec14..f23a4d91d 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/AbstractOperationGenerator.java
@@ -45,7 +45,6 @@ import org.apache.servicecomb.swagger.generator.ParameterAnnotationProcessor;
import org.apache.servicecomb.swagger.generator.ParameterGenerator;
import org.apache.servicecomb.swagger.generator.ParameterTypeProcessor;
import org.apache.servicecomb.swagger.generator.ResponseTypeProcessor;
-import org.apache.servicecomb.swagger.generator.SwaggerConst;
import org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils;
import org.apache.servicecomb.swagger.generator.core.model.HttpParameterType;
import org.apache.servicecomb.swagger.generator.core.utils.MethodUtils;
@@ -62,7 +61,9 @@ import io.swagger.v3.oas.models.OpenAPI;
import io.swagger.v3.oas.models.Operation;
import io.swagger.v3.oas.models.PathItem;
import io.swagger.v3.oas.models.Paths;
+import io.swagger.v3.oas.models.headers.Header;
import io.swagger.v3.oas.models.media.Content;
+import io.swagger.v3.oas.models.media.MediaType;
import io.swagger.v3.oas.models.media.Schema;
import io.swagger.v3.oas.models.responses.ApiResponse;
import io.swagger.v3.oas.models.responses.ApiResponses;
@@ -370,26 +371,43 @@ public abstract class AbstractOperationGenerator implements OperationGenerator {
}
public void scanResponse() {
- if (swaggerOperation.getResponses() == null) {
- swaggerOperation.setResponses(new ApiResponses());
- }
+ operationGeneratorContext.updateProduces();
+ swaggerOperation.setResponses(new ApiResponses());
+ for (Entry<String, Schema<?>> response : operationGeneratorContext.getResponses().entrySet()) {
+ ApiResponse apiResponse = new ApiResponse();
+ if (StringUtils.isNotEmpty(operationGeneratorContext.getResponseDescriptions().get(response.getKey()))) {
+ apiResponse.setDescription(operationGeneratorContext.getResponseDescriptions().get(response.getKey()));
+ }
+ if (operationGeneratorContext.getResponseHeaders().get(response.getKey()) != null) {
+ operationGeneratorContext.getResponseHeaders().get(response.getKey()).forEach((k, v) -> {
+ Header header = new Header();
+ header.setSchema(v);
+ apiResponse.addHeaderObject(k, header);
+ });
+ }
+ Schema<?> schema = response.getValue() != null ? response.getValue() :
+ createResponseModel();
- // If annotations contains ApiResponse, schema must be defined.
- if (swaggerOperation.getResponses().get(SwaggerConst.SUCCESS_KEY) != null) {
- return;
- }
+ if (schema == null) {
+ swaggerOperation.getResponses().addApiResponse(response.getKey(), apiResponse);
+ continue;
+ }
- Schema model = createResponseModel();
- if (model == null) {
- return;
+ apiResponse.setContent(new Content());
+ // file download using WILDCARD content-type
+ if ("string".equals(schema.getType()) && "binary".equals(schema.getFormat())) {
+ MediaType mediaType = new MediaType();
+ mediaType.setSchema(schema);
+ apiResponse.getContent().addMediaType(jakarta.ws.rs.core.MediaType.WILDCARD, mediaType);
+ } else {
+ for (String produce : operationGeneratorContext.getSupportedProduces()) {
+ MediaType mediaType = new MediaType();
+ mediaType.setSchema(schema);
+ apiResponse.getContent().addMediaType(produce, mediaType);
+ }
+ }
+ swaggerOperation.getResponses().addApiResponse(response.getKey(), apiResponse);
}
- swaggerOperation.getResponses().addApiResponse(SwaggerConst.SUCCESS_KEY, new ApiResponse());
- swaggerOperation.getResponses().get(SwaggerConst.SUCCESS_KEY).setContent(new Content());
- swaggerOperation.getResponses().get(SwaggerConst.SUCCESS_KEY).getContent()
- .addMediaType(SwaggerConst.DEFAULT_MEDIA_TYPE, new io.swagger.v3.oas.models.media.MediaType());
- swaggerOperation.getResponses().get(SwaggerConst.SUCCESS_KEY).getContent()
- .get(SwaggerConst.DEFAULT_MEDIA_TYPE)
- .setSchema(model);
}
protected Schema createResponseModel() {
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGeneratorContext.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGeneratorContext.java
index 650cb11f1..3cf1105c8 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGeneratorContext.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/OperationGeneratorContext.java
@@ -16,8 +16,73 @@
*/
package org.apache.servicecomb.swagger.generator.core;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.servicecomb.swagger.generator.SwaggerConst;
+
+import com.fasterxml.jackson.databind.JavaType;
+
+import io.swagger.v3.oas.models.media.Schema;
+
public class OperationGeneratorContext extends SwaggerGeneratorContext {
+ private final Map<String, Schema<?>> responses = new HashMap<>();
+
+ private JavaType responseType;
+
+ private final Map<String, String> responseDescriptions = new HashMap<>();
+
+ // statusCode:headerName:headerSchema
+ private final Map<String, Map<String, Schema<?>>> responseHeaders = new HashMap<>();
+
public OperationGeneratorContext(SwaggerGeneratorContext parent) {
super(parent);
+ updateResponse(SwaggerConst.SUCCESS_KEY, null);
+ }
+
+ public Map<String, Schema<?>> getResponses() {
+ return responses;
+ }
+
+ public void updateResponse(String code, Schema<?> schema) {
+ this.responses.put(code, schema);
+ }
+
+ public JavaType getResponseType() {
+ return responseType;
+ }
+
+ public void setResponseType(JavaType responseType) {
+ this.responseType = responseType;
+ }
+
+ public Map<String, String> getResponseDescriptions() {
+ return responseDescriptions;
+ }
+
+ public void updateResponseDescription(String code, String description) {
+ this.responseDescriptions.put(code, description);
+ }
+
+ public Map<String, Map<String, Schema<?>>> getResponseHeaders() {
+ return responseHeaders;
+ }
+
+ public void updateResponseHeader(String code, String header, Schema<?> schema) {
+ this.responseHeaders.computeIfAbsent(code, key -> new HashMap<>());
+ this.responseHeaders.get(code).put(header, schema);
+ }
+
+ public void updateProduces() {
+ List<String> removed = new ArrayList<>();
+ for (String media : supportedProduces) {
+ if (SUPPORTED_BODY_CONTENT_TYPE.contains(media)) {
+ continue;
+ }
+ removed.add(media);
+ }
+ supportedProduces.removeAll(removed);
}
}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponseMethodProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponseMethodProcessor.java
index a34957856..3f6850a21 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponseMethodProcessor.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponseMethodProcessor.java
@@ -17,13 +17,20 @@
package org.apache.servicecomb.swagger.generator.core.processor.annotation;
import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.swagger.SwaggerUtils;
import org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;
import org.apache.servicecomb.swagger.generator.OperationGenerator;
+import org.apache.servicecomb.swagger.generator.SwaggerConst;
import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
+import org.springframework.util.CollectionUtils;
+import io.swagger.v3.oas.annotations.headers.Header;
+import io.swagger.v3.oas.annotations.media.Content;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.models.responses.ApiResponses;
public class ApiResponseMethodProcessor implements MethodAnnotationProcessor<ApiResponse> {
@Override
@@ -34,11 +41,38 @@ public class ApiResponseMethodProcessor implements MethodAnnotationProcessor<Api
@Override
public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,
ApiResponse apiResponse) {
- if (operationGenerator.getOperation().getResponses() == null) {
- operationGenerator.getOperation().setResponses(new ApiResponses());
+ List<String> produces = new ArrayList<>();
+ String responseCode = apiResponse.responseCode();
+ if (StringUtils.isEmpty(responseCode) || "default".equals(responseCode)) {
+ responseCode = SwaggerConst.SUCCESS_KEY;
+ }
+ Class<?> type = null;
+ for (Content content : apiResponse.content()) {
+ if (StringUtils.isNotEmpty(content.mediaType())) {
+ produces.add(content.mediaType());
+ }
+ if (content.schema() != null && content.schema().implementation() != Void.class) {
+ type = content.schema().implementation();
+ }
+ }
+ operationGenerator.getOperationGeneratorContext().updateResponse(responseCode,
+ type == null ? null : SwaggerUtils.resolveTypeSchemas(swaggerGenerator.getOpenAPI(), type));
+ if (StringUtils.isNotEmpty(apiResponse.description())) {
+ operationGenerator.getOperationGeneratorContext().updateResponseDescription(responseCode,
+ apiResponse.description());
+ }
+ for (Header header : apiResponse.headers()) {
+ if (header.schema() == null || header.schema().implementation() == Void.class) {
+ throw new IllegalArgumentException("@ApiResponse header schema implementation must be defined.");
+ }
+ if (StringUtils.isEmpty(header.name())) {
+ throw new IllegalArgumentException("@ApiResponse header name must be defined.");
+ }
+ operationGenerator.getOperationGeneratorContext().updateResponseHeader(responseCode,
+ header.name(), AnnotationUtils.schemaModel(swaggerGenerator.getOpenAPI(), header.schema()));
+ }
+ if (!CollectionUtils.isEmpty(produces)) {
+ operationGenerator.getOperationGeneratorContext().updateProduces(produces);
}
- operationGenerator.getOperation().getResponses().addApiResponse(
- AnnotationUtils.responseCodeModel(apiResponse),
- AnnotationUtils.apiResponseModel(swaggerGenerator.getOpenAPI(), apiResponse));
}
}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponsesClassProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponsesClassProcessor.java
deleted file mode 100644
index 88ef6ebc6..000000000
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponsesClassProcessor.java
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.servicecomb.swagger.generator.core.processor.annotation;
-
-import static org.apache.servicecomb.swagger.generator.SwaggerGeneratorUtils.findClassAnnotationProcessor;
-
-import java.lang.reflect.Type;
-
-import org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor;
-import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
-
-import io.swagger.v3.oas.annotations.responses.ApiResponse;
-import io.swagger.v3.oas.annotations.responses.ApiResponses;
-
-
-public class ApiResponsesClassProcessor implements ClassAnnotationProcessor<ApiResponses> {
- @Override
- public Type getProcessType() {
- return ApiResponses.class;
- }
-
- @Override
- public void process(SwaggerGenerator swaggerGenerator, ApiResponses apiResponses) {
- ClassAnnotationProcessor<ApiResponse> processor = findClassAnnotationProcessor(ApiResponse.class);
- for (ApiResponse apiResponse : apiResponses.value()) {
- processor.process(swaggerGenerator, apiResponse);
- }
- }
-}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponsesMethodProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponsesMethodProcessor.java
index 1e4eea4f1..383598aa1 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponsesMethodProcessor.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/ApiResponsesMethodProcessor.java
@@ -17,11 +17,19 @@
package org.apache.servicecomb.swagger.generator.core.processor.annotation;
import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.swagger.SwaggerUtils;
import org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;
import org.apache.servicecomb.swagger.generator.OperationGenerator;
import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
+import org.springframework.util.CollectionUtils;
+import io.swagger.v3.oas.annotations.headers.Header;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
@@ -34,8 +42,39 @@ public class ApiResponsesMethodProcessor implements MethodAnnotationProcessor<Ap
@Override
public void process(SwaggerGenerator swaggerGenerator, OperationGenerator operationGenerator,
ApiResponses apiResponses) {
- io.swagger.v3.oas.models.responses.ApiResponses responses =
- AnnotationUtils.apiResponsesModel(swaggerGenerator.getOpenAPI(), apiResponses);
- operationGenerator.getOperation().setResponses(responses);
+ List<String> produces = new ArrayList<>();
+ for (ApiResponse apiResponse : apiResponses.value()) {
+ if (StringUtils.isEmpty(apiResponse.responseCode()) || "default".equals(apiResponse.responseCode())) {
+ throw new IllegalArgumentException("@ApiResponse status code must be defined.");
+ }
+ Class<?> type = null;
+ for (Content content : apiResponse.content()) {
+ if (StringUtils.isNotEmpty(content.mediaType())) {
+ produces.add(content.mediaType());
+ }
+ if (content.schema() != null && content.schema().implementation() != Void.class) {
+ type = content.schema().implementation();
+ }
+ }
+ operationGenerator.getOperationGeneratorContext().updateResponse(apiResponse.responseCode(),
+ type == null ? null : SwaggerUtils.resolveTypeSchemas(swaggerGenerator.getOpenAPI(), type));
+ if (StringUtils.isNotEmpty(apiResponse.description())) {
+ operationGenerator.getOperationGeneratorContext().updateResponseDescription(apiResponse.responseCode(),
+ apiResponse.description());
+ }
+ for (Header header : apiResponse.headers()) {
+ if (header.schema() == null || header.schema().implementation() == Void.class) {
+ throw new IllegalArgumentException("@ApiResponse header schema implementation must be defined.");
+ }
+ if (StringUtils.isEmpty(header.name())) {
+ throw new IllegalArgumentException("@ApiResponse header name must be defined.");
+ }
+ operationGenerator.getOperationGeneratorContext().updateResponseHeader(apiResponse.responseCode(),
+ header.name(), AnnotationUtils.schemaModel(swaggerGenerator.getOpenAPI(), header.schema()));
+ }
+ }
+ if (!CollectionUtils.isEmpty(produces)) {
+ operationGenerator.getOperationGeneratorContext().updateProduces(produces);
+ }
}
}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessor.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessor.java
index 6d00f0d6b..86986a90c 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessor.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessor.java
@@ -18,14 +18,20 @@
package org.apache.servicecomb.swagger.generator.core.processor.annotation;
import java.lang.reflect.Type;
+import java.util.ArrayList;
+import java.util.List;
import org.apache.commons.lang3.StringUtils;
+import org.apache.servicecomb.swagger.SwaggerUtils;
import org.apache.servicecomb.swagger.generator.MethodAnnotationProcessor;
import org.apache.servicecomb.swagger.generator.OperationGenerator;
import org.apache.servicecomb.swagger.generator.SwaggerGenerator;
import org.springframework.util.CollectionUtils;
import io.swagger.v3.oas.annotations.Operation;
+import io.swagger.v3.oas.annotations.headers.Header;
+import io.swagger.v3.oas.annotations.media.Content;
+import io.swagger.v3.oas.annotations.responses.ApiResponse;
public class OperationMethodAnnotationProcessor implements MethodAnnotationProcessor<Operation> {
public Type getProcessType() {
@@ -36,13 +42,52 @@ public class OperationMethodAnnotationProcessor implements MethodAnnotationProce
public void process(SwaggerGenerator swaggerGenerator,
OperationGenerator operationGenerator, Operation apiOperationAnnotation) {
io.swagger.v3.oas.models.Operation operation = operationGenerator.getOperation();
- io.swagger.v3.oas.models.Operation specificOperation =
- AnnotationUtils.operationModel(swaggerGenerator.getOpenAPI(), apiOperationAnnotation);
if (!StringUtils.isEmpty(apiOperationAnnotation.method())) {
operationGenerator.setHttpMethod(apiOperationAnnotation.method());
}
+ if (apiOperationAnnotation.responses() != null) {
+ // This is a bit different from swagger annotation intention.
+ // Here we assume @Content defines all supported media type and only one implementation class for one status code.
+ List<String> produces = new ArrayList<>();
+ for (ApiResponse apiResponse : apiOperationAnnotation.responses()) {
+ if (StringUtils.isEmpty(apiResponse.responseCode()) || "default".equals(apiResponse.responseCode())) {
+ throw new IllegalArgumentException("@ApiResponse status code must be defined.");
+ }
+ Class<?> type = null;
+ for (Content content : apiResponse.content()) {
+ if (StringUtils.isNotEmpty(content.mediaType())) {
+ produces.add(content.mediaType());
+ }
+ if (content.schema() != null && content.schema().implementation() != Void.class) {
+ type = content.schema().implementation();
+ }
+ }
+ operationGenerator.getOperationGeneratorContext().updateResponse(apiResponse.responseCode(),
+ type == null ? null : SwaggerUtils.resolveTypeSchemas(swaggerGenerator.getOpenAPI(), type));
+ if (StringUtils.isNotEmpty(apiResponse.description())) {
+ operationGenerator.getOperationGeneratorContext().updateResponseDescription(apiResponse.responseCode(),
+ apiResponse.description());
+ }
+ for (Header header : apiResponse.headers()) {
+ if (header.schema() == null || header.schema().implementation() == Void.class) {
+ throw new IllegalArgumentException("@ApiResponse header schema implementation must be defined.");
+ }
+ if (StringUtils.isEmpty(header.name())) {
+ throw new IllegalArgumentException("@ApiResponse header name must be defined.");
+ }
+ operationGenerator.getOperationGeneratorContext().updateResponseHeader(apiResponse.responseCode(),
+ header.name(), AnnotationUtils.schemaModel(swaggerGenerator.getOpenAPI(), header.schema()));
+ }
+ }
+ if (!CollectionUtils.isEmpty(produces)) {
+ operationGenerator.getOperationGeneratorContext().updateProduces(produces);
+ }
+ }
+
+ io.swagger.v3.oas.models.Operation specificOperation =
+ AnnotationUtils.operationModel(swaggerGenerator.getOpenAPI(), apiOperationAnnotation);
if (!StringUtils.isEmpty(specificOperation.getSummary())) {
operation.setSummary(specificOperation.getSummary());
}
@@ -62,9 +107,5 @@ public class OperationMethodAnnotationProcessor implements MethodAnnotationProce
if (!CollectionUtils.isEmpty(specificOperation.getTags())) {
operation.setTags(specificOperation.getTags());
}
-
- if (!CollectionUtils.isEmpty(specificOperation.getResponses())) {
- operation.setResponses(specificOperation.getResponses());
- }
}
}
diff --git a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/pojo/PojoSwaggerGenerator.java b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/pojo/PojoSwaggerGenerator.java
index f82c40ec1..0a2e6985a 100644
--- a/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/pojo/PojoSwaggerGenerator.java
+++ b/swagger/swagger-generator/generator-core/src/main/java/org/apache/servicecomb/swagger/generator/pojo/PojoSwaggerGenerator.java
@@ -28,7 +28,7 @@ import jakarta.ws.rs.core.MediaType;
public class PojoSwaggerGenerator extends AbstractSwaggerGenerator {
protected static final List<String> SUPPORTED_CONTENT_TYPE
- = Arrays.asList(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE);
+ = Arrays.asList(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN);
public PojoSwaggerGenerator(Class<?> cls) {
super(cls);
diff --git a/swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor b/swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor
index 21398e599..3b9c9f840 100644
--- a/swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor
+++ b/swagger/swagger-generator/generator-core/src/main/resources/META-INF/services/org.apache.servicecomb.swagger.generator.ClassAnnotationProcessor
@@ -16,4 +16,3 @@
#
org.apache.servicecomb.swagger.generator.core.processor.annotation.OpenAPIDefinitionProcessor
-org.apache.servicecomb.swagger.generator.core.processor.annotation.ApiResponsesClassProcessor
diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiOperation.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiOperation.java
index 046bd42fd..73f63e714 100644
--- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiOperation.java
+++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiOperation.java
@@ -59,7 +59,7 @@ public class TestApiOperation {
responses = @ApiResponse(responseCode = "202",
content = @Content(mediaType = MediaType.APPLICATION_JSON,
schema = @Schema(implementation = String.class)),
- headers = @Header(name = "h1", schema = @Schema(type = "integer"))),
+ headers = @Header(name = "h1", schema = @Schema(implementation = Integer.class))),
extensions = {@Extension(
name = "x-tagA",
properties = {@ExtensionProperty(name = "x-tagAExt", value = "value of tagAExt")})})
@@ -107,7 +107,7 @@ public class TestApiOperation {
Assertions.assertEquals(Arrays.asList("tag1", "tag2"), operation.getTags());
ApiResponses responseMap = operation.getResponses();
- Assertions.assertEquals(1, responseMap.size());
+ Assertions.assertEquals(2, responseMap.size());
io.swagger.v3.oas.models.responses.ApiResponse response = responseMap.get("202");
Assertions.assertNotNull(response);
diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java
index 1f8615c0b..58e1ebeb7 100644
--- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java
+++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestApiResponse.java
@@ -40,25 +40,25 @@ public class TestApiResponse {
interface ApiResponseAnnotation {
@ApiResponse(
- headers = {@Header(name = "k1", schema = @Schema(type = "integer", format = "int32")),
- @Header(name = "k2", schema = @Schema(type = "string"))},
+ headers = {@Header(name = "k1", schema = @Schema(implementation = Integer.class)),
+ @Header(name = "k2", schema = @Schema(implementation = String.class))},
responseCode = "200",
description = "")
void testApiResponseHeader();
@ApiResponse(responseCode = "200",
- headers = {@Header(name = "k1", schema = @Schema(type = "integer", format = "int32"))})
+ headers = {@Header(name = "k1", schema = @Schema(implementation = Integer.class))})
void testResponseHeader();
@ApiResponse(
- content = @Content(schema = @Schema(type = "integer", format = "int32")),
+ content = @Content(schema = @Schema(implementation = Integer.class)),
responseCode = "200",
description = "msg")
void testSingle();
@ApiResponses(value = {
- @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(type = "integer", format = "int32")), description = "msg1"),
- @ApiResponse(responseCode = "301", content = @Content(schema = @Schema(type = "string")), description = "msg2")})
+ @ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = Integer.class)), description = "msg1"),
+ @ApiResponse(responseCode = "301", content = @Content(schema = @Schema(implementation = String.class)), description = "msg2")})
void testMulti();
}
@@ -98,7 +98,7 @@ public class TestApiResponse {
property = response.getHeaders().get("k2");
Assertions.assertEquals("string", property.getSchema().getType());
- Assertions.assertEquals("", property.getSchema().getFormat());
+ Assertions.assertEquals(null, property.getSchema().getFormat());
}
@Test
@@ -122,6 +122,6 @@ public class TestApiResponse {
response = swaggerOperation.getOperation().getResponses().get("301");
Assertions.assertEquals("string", response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getType());
- Assertions.assertEquals("", response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getFormat());
+ Assertions.assertEquals(null, response.getContent().get(MediaType.APPLICATION_JSON).getSchema().getFormat());
}
}
diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java
index bfd314139..f238e91ff 100644
--- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java
+++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/TestOperationGenerator.java
@@ -51,12 +51,12 @@ public class TestOperationGenerator {
private static class TestClass {
@ApiResponse(responseCode = "200", description = "200 is ok............",
content = @Content(mediaType = "application/json", schema = @Schema(name = "String")),
- headers = @Header(name = "x-user-domain", schema = @Schema(name = "String")))
+ headers = @Header(name = "x-user-domain", schema = @Schema(implementation = String.class)))
@Operation(summary = "value1", tags = {"tag1", "tag2"},
responses = {
@ApiResponse(responseCode = "200", headers =
- {@Header(name = "x-user-name", schema = @Schema(name = "String")),
- @Header(name = "x-user-id", schema = @Schema(name = "String"))})},
+ {@Header(name = "x-user-name", schema = @Schema(implementation = String.class)),
+ @Header(name = "x-user-id", schema = @Schema(implementation = String.class))})},
extensions = {
@Extension(name = "x-class-name", properties = @ExtensionProperty(value = "value", name = "key"))})
public void responseThenApiOperation() {
@@ -64,14 +64,14 @@ public class TestOperationGenerator {
@Operation(summary = "value1", tags = {"tag1", "tag2"},
responses = {@ApiResponse(responseCode = "200", headers = {
- @Header(name = "x-user-name", schema = @Schema(name = "String")),
- @Header(name = "x-user-id", schema = @Schema(name = "String"))})},
+ @Header(name = "x-user-name", schema = @Schema(implementation = String.class)),
+ @Header(name = "x-user-id", schema = @Schema(implementation = String.class))})},
extensions = {
@Extension(name = "x-class-name", properties = {
@ExtensionProperty(value = "value", name = "key")})})
@ApiResponse(responseCode = "200", description = "200 is ok............",
- content = @Content(mediaType = "application/json", schema = @Schema(name = "String")),
- headers = @Header(name = "x-user-domain", schema = @Schema(name = "String")))
+ content = @Content(mediaType = "application/json", schema = @Schema(implementation = String.class)),
+ headers = @Header(name = "x-user-domain", schema = @Schema(implementation = String.class)))
public void apiOperationThenResponse() {
}
@@ -106,10 +106,11 @@ public class TestOperationGenerator {
MatcherAssert.assertThat(tags, contains("tag1", "tag2"));
io.swagger.v3.oas.models.responses.ApiResponse response = swaggerOperation.getOperation().getResponses().get("200");
- Assertions.assertEquals("response of 200", response.getDescription());
- Assertions.assertNull(response.getHeaders().get("x-user-domain"));
+ Assertions.assertEquals("200 is ok............", response.getDescription());
+ Assertions.assertNotNull(response.getHeaders().get("x-user-domain"));
Assertions.assertNotNull(response.getHeaders().get("x-user-name"));
Assertions.assertNotNull(swaggerOperation.getOperation().getExtensions().get("x-class-name"));
+ Assertions.assertNull(swaggerOperation.getOperation().getExtensions().get("x-not-exists"));
}
@Test
@@ -119,8 +120,8 @@ public class TestOperationGenerator {
MatcherAssert.assertThat(tags, contains("tag1", "tag2"));
io.swagger.v3.oas.models.responses.ApiResponse response = swaggerOperation.getOperation().getResponses().get("200");
- Assertions.assertEquals("response of 200", response.getDescription());
- Assertions.assertNull(response.getHeaders().get("x-user-domain"));
+ Assertions.assertEquals("200 is ok............", response.getDescription());
+ Assertions.assertNotNull(response.getHeaders().get("x-user-domain"));
Assertions.assertNotNull(response.getHeaders().get("x-user-name"));
Assertions.assertNotNull(swaggerOperation.getOperation().getExtensions().get("x-class-name"));
}
diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java
index 70d2f344f..b4720f15d 100644
--- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java
+++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/processor/annotation/OperationMethodAnnotationProcessorTest.java
@@ -58,9 +58,10 @@ public class OperationMethodAnnotationProcessorTest {
public void functionWithNoTag() {
}
+ // mediaType will be ignored
@Operation(summary = "testSingleMediaType",
responses = {@ApiResponse(responseCode = "200", content = @Content(
- mediaType = MediaType.APPLICATION_XML, schema = @Schema(implementation = String.class)))})
+ mediaType = MediaType.TEXT_PLAIN, schema = @Schema(implementation = String.class)))})
public String testSingleMediaType(String input) {
return input;
}
@@ -76,7 +77,7 @@ public class OperationMethodAnnotationProcessorTest {
}
@Operation(summary = "testBlankMediaType",
- responses = {@ApiResponse(content = @Content(mediaType = ""))},
+ responses = {@ApiResponse(responseCode = "200", content = @Content(mediaType = ""))},
requestBody = @RequestBody(content = @Content(mediaType = "",
schema = @Schema(implementation = String.class))))
public String testBlankMediaType(String input) {
@@ -144,7 +145,7 @@ public class OperationMethodAnnotationProcessorTest {
public void testMultiMediaType() {
SwaggerOperation swaggerOperation = swaggerOperations.findOperation("testMultiMediaType");
MatcherAssert.assertThat(swaggerOperation.getOperation().getRequestBody().getContent().keySet(),
- Matchers.contains(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE));
+ Matchers.contains(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN));
MatcherAssert.assertThat(swaggerOperation.getOperation().getResponses().get("200").getContent().keySet(),
Matchers.contains(MediaType.APPLICATION_JSON, MediaType.TEXT_PLAIN));
}
@@ -156,7 +157,7 @@ public class OperationMethodAnnotationProcessorTest {
.getRequestBody().getContent().get(MediaType.APPLICATION_JSON).getSchema().get$ref(),
Matchers.equalTo(Components.COMPONENTS_SCHEMAS_REF + "testSingleMediaTypeBody"));
MatcherAssert.assertThat(swaggerOperation.getOperation()
- .getResponses().get("200").getContent().get(MediaType.APPLICATION_XML).getSchema().getType(),
+ .getResponses().get("200").getContent().get(MediaType.TEXT_PLAIN).getSchema().getType(),
Matchers.equalTo("string"));
}
@@ -164,9 +165,10 @@ public class OperationMethodAnnotationProcessorTest {
public void testBlankMediaType() {
SwaggerOperation swaggerOperation = swaggerOperations.findOperation("testBlankMediaType");
MatcherAssert.assertThat(swaggerOperation.getOperation().getRequestBody().getContent().keySet(),
- Matchers.contains(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE));
- MatcherAssert.assertThat(swaggerOperation.getOperation().getResponses().getDefault().getContent().keySet(),
- Matchers.contains(MediaType.APPLICATION_JSON));
+ Matchers.contains(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN));
+ MatcherAssert.assertThat(swaggerOperation.getOperation().getResponses()
+ .get(SwaggerConst.SUCCESS_KEY).getContent().keySet(),
+ Matchers.contains(MediaType.APPLICATION_JSON, SwaggerConst.PROTOBUF_TYPE, MediaType.TEXT_PLAIN));
}
@Test
diff --git a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/schema/Schema.java b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/schema/Schema.java
index c370c3b1f..de65caa81 100644
--- a/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/schema/Schema.java
+++ b/swagger/swagger-generator/generator-core/src/test/java/org/apache/servicecomb/swagger/generator/core/schema/Schema.java
@@ -42,19 +42,19 @@ public class Schema {
}
@ApiResponse(headers = {@Header(name = "h",
- schema = @io.swagger.v3.oas.annotations.media.Schema(type = "string"))}, responseCode = "200", description = "")
+ schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = String.class))}, responseCode = "200", description = "")
public void testApiResponse() {
}
@ApiResponse(headers = {@Header(name = "h",
- schema = @io.swagger.v3.oas.annotations.media.Schema(type = "string"))}, description = "")
+ schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = String.class))}, description = "")
public void testApiOperation() {
}
@ApiResponse(headers = {@Header(name = "h",
- schema = @io.swagger.v3.oas.annotations.media.Schema(type = "string"))})
+ schema = @io.swagger.v3.oas.annotations.media.Schema(implementation = String.class))})
public void testResponseHeader() {
}
diff --git a/swagger/swagger-generator/generator-core/src/test/resources/schemas/ParameterAnnotation.yaml b/swagger/swagger-generator/generator-core/src/test/resources/schemas/ParameterAnnotation.yaml
index 5c2ffe0ee..64e81e853 100644
--- a/swagger/swagger-generator/generator-core/src/test/resources/schemas/ParameterAnnotation.yaml
+++ b/swagger/swagger-generator/generator-core/src/test/resources/schemas/ParameterAnnotation.yaml
@@ -35,6 +35,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/differentNameBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/differentNameBody'
x-name: differentNameBody
responses:
"200":
@@ -44,6 +47,14 @@ paths:
schema:
type: integer
format: int32
+ application/protobuf:
+ schema:
+ type: integer
+ format: int32
+ text/plain:
+ schema:
+ type: integer
+ format: int32
components:
schemas:
differentNameBody:
diff --git a/swagger/swagger-generator/generator-core/src/test/resources/schemas/Schema.yaml b/swagger/swagger-generator/generator-core/src/test/resources/schemas/Schema.yaml
index 44d2ad5bf..0de5a305e 100644
--- a/swagger/swagger-generator/generator-core/src/test/resources/schemas/Schema.yaml
+++ b/swagger/swagger-generator/generator-core/src/test/resources/schemas/Schema.yaml
@@ -34,6 +34,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/ignoreRequestBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/ignoreRequestBody'
x-name: ignoreRequestBody
responses:
"200":
@@ -49,6 +52,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/nestedListStringBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/nestedListStringBody'
x-name: nestedListStringBody
responses:
"200":
@@ -61,6 +67,20 @@ paths:
type: array
items:
type: string
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ type: array
+ items:
+ type: string
+ text/plain:
+ schema:
+ type: array
+ items:
+ type: array
+ items:
+ type: string
/testAllType:
post:
operationId: testAllType
@@ -72,6 +92,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/AllType'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/AllType'
x-name: obj
responses:
"200":
@@ -80,18 +103,15 @@ paths:
post:
operationId: testApiOperation
responses:
- default:
- description: response of default
+ "200":
+ description: response of 200
headers:
h:
- description: ""
schema:
type: string
description: ""
- format: ""
nullable: false
example: ""
- content: {}
/testApiResponse:
post:
operationId: testApiResponse
@@ -100,14 +120,11 @@ paths:
description: response of 200
headers:
h:
- description: ""
schema:
type: string
description: ""
- format: ""
nullable: false
example: ""
- content: {}
/testArray:
post:
operationId: testArray
@@ -119,6 +136,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testArrayBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testArrayBody'
x-name: testArrayBody
responses:
"200":
@@ -134,6 +154,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testBooleanBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testBooleanBody'
x-name: testBooleanBody
responses:
"200":
@@ -149,6 +172,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testByteBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testByteBody'
x-name: testByteBody
responses:
"200":
@@ -164,6 +190,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testBytesBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testBytesBody'
x-name: testBytesBody
responses:
"200":
@@ -179,6 +208,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testCharBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testCharBody'
x-name: testCharBody
responses:
"200":
@@ -193,6 +225,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testCompletableFutureOptional:
post:
operationId: testCompletableFutureOptional
@@ -203,6 +241,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testDate:
post:
operationId: testDate
@@ -214,6 +258,14 @@ paths:
schema:
type: string
format: date-time
+ application/protobuf:
+ schema:
+ type: string
+ format: date-time
+ text/plain:
+ schema:
+ type: string
+ format: date-time
/testDouble:
post:
operationId: testDouble
@@ -225,6 +277,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testDoubleBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testDoubleBody'
x-name: testDoubleBody
responses:
"200":
@@ -240,6 +295,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testEnumBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testEnumBody'
x-name: testEnumBody
responses:
"200":
@@ -255,6 +313,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testFloatBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testFloatBody'
x-name: testFloatBody
responses:
"200":
@@ -270,6 +331,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testIntegerBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testIntegerBody'
x-name: testIntegerBody
responses:
"200":
@@ -285,6 +349,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testListBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testListBody'
x-name: testListBody
responses:
"200":
@@ -300,6 +367,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testLongBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testLongBody'
x-name: testLongBody
responses:
"200":
@@ -315,6 +385,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testMapBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testMapBody'
x-name: testMapBody
responses:
"200":
@@ -330,6 +403,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testMapListBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testMapListBody'
x-name: testMapListBody
responses:
"200":
@@ -345,6 +421,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testMultiParamBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testMultiParamBody'
x-name: testMultiParamBody
responses:
"200":
@@ -355,6 +434,16 @@ paths:
type: array
items:
type: string
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ type: string
+ text/plain:
+ schema:
+ type: array
+ items:
+ type: string
/testObject:
post:
operationId: testObject
@@ -366,6 +455,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/User'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/User'
x-name: user
responses:
"200":
@@ -381,6 +473,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testOneEnumBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testOneEnumBody'
x-name: testOneEnumBody
responses:
"200":
@@ -395,22 +490,25 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testResponseHeader:
post:
operationId: testResponseHeader
responses:
- default:
- description: response of default
+ "200":
+ description: response of 200
headers:
h:
- description: ""
schema:
type: string
description: ""
- format: ""
nullable: false
example: ""
- content: {}
/testSet:
post:
operationId: testSet
@@ -422,6 +520,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testSetBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testSetBody'
x-name: testSetBody
responses:
"200":
@@ -437,6 +538,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testShortBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testShortBody'
x-name: testShortBody
responses:
"200":
@@ -452,6 +556,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testStringBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testStringBody'
x-name: testStringBody
responses:
"200":
@@ -467,6 +574,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testbooleanBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testbooleanBody'
x-name: testbooleanBody
responses:
"200":
@@ -482,6 +592,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testbyteBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testbyteBody'
x-name: testbyteBody
responses:
"200":
@@ -497,6 +610,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testbytesBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testbytesBody'
x-name: testbytesBody
responses:
"200":
@@ -512,6 +628,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testcharBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testcharBody'
x-name: testcharBody
responses:
"200":
@@ -527,6 +646,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testdoubleBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testdoubleBody'
x-name: testdoubleBody
responses:
"200":
@@ -542,6 +664,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testfloatBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testfloatBody'
x-name: testfloatBody
responses:
"200":
@@ -557,6 +682,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testintBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testintBody'
x-name: testintBody
responses:
"200":
@@ -572,6 +700,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testlongBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testlongBody'
x-name: testlongBody
responses:
"200":
@@ -587,6 +718,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testshortBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testshortBody'
x-name: testshortBody
responses:
"200":
@@ -602,6 +736,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/wrapToBodyWithDescBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/wrapToBodyWithDescBody'
x-name: wrapToBodyWithDescBody
responses:
"200":
diff --git a/swagger/swagger-generator/generator-core/src/test/resources/schemas/pojoExample1.yaml b/swagger/swagger-generator/generator-core/src/test/resources/schemas/pojoExample1.yaml
index 096e157a2..1ba1c76fc 100644
--- a/swagger/swagger-generator/generator-core/src/test/resources/schemas/pojoExample1.yaml
+++ b/swagger/swagger-generator/generator-core/src/test/resources/schemas/pojoExample1.yaml
@@ -34,6 +34,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/testMultiParameterBody'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/testMultiParameterBody'
x-name: testMultiParameterBody
responses:
"200":
@@ -42,6 +45,12 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/XXX'
+ application/protobuf:
+ schema:
+ $ref: '#/components/schemas/XXX'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/XXX'
/testOneParameter:
post:
operationId: testOneParameter
@@ -53,6 +62,9 @@ paths:
application/protobuf:
schema:
$ref: '#/components/schemas/XXX'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/XXX'
x-name: testType1
responses:
"200":
@@ -61,6 +73,12 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/XXX'
+ application/protobuf:
+ schema:
+ $ref: '#/components/schemas/XXX'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/XXX'
components:
schemas:
XXX:
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java
index 67a8ac39c..2bae2974c 100644
--- a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/Echo.java
@@ -61,7 +61,7 @@ public class Echo {
@POST
@ApiResponse(content = {
- @Content(schema = @Schema(type = "number", format = "int32"))}, responseCode = "200", description = "")
+ @Content(schema = @Schema(implementation = Integer.class))}, responseCode = "200", description = "")
@Path("response")
public Response response() {
return null;
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/FullSwaggerService.java b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/FullSwaggerService.java
index 5541b4a63..d8cb38fa4 100644
--- a/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/FullSwaggerService.java
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/java/org/apache/servicecomb/swagger/generator/jaxrs/FullSwaggerService.java
@@ -16,6 +16,7 @@
*/
package org.apache.servicecomb.swagger.generator.jaxrs;
+import java.io.File;
import java.io.IOException;
import java.util.List;
@@ -60,11 +61,16 @@ public class FullSwaggerService {
return "Hello " + a + b + c + d + e;
}
- // TODO: should produces text/plain for string
-// @Path("/textPlain")
-// @GET
-// @Produces(MediaType.TEXT_PLAIN)
-// public String textPlain() {
-// return null;
-// }
+ @Path("/textPlain")
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String textPlain() {
+ return null;
+ }
+
+ @Path("/fileDownload")
+ @GET
+ public File fileDownload() {
+ return null;
+ }
}
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/ClassAnnotation.yaml b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/ClassAnnotation.yaml
index a1c4739d5..46b0d2449 100644
--- a/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/ClassAnnotation.yaml
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/ClassAnnotation.yaml
@@ -39,6 +39,9 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/User'
+ text/plain:
+ schema:
+ $ref: '#/components/schemas/User'
/testForm:
post:
operationId: testForm
@@ -58,6 +61,9 @@ paths:
application/json:
schema:
type: string
+ text/plain:
+ schema:
+ type: string
/testString:
post:
operationId: testString
@@ -74,6 +80,9 @@ paths:
application/json:
schema:
type: string
+ text/plain:
+ schema:
+ type: string
/testUpload:
post:
operationId: testUpload
@@ -93,6 +102,9 @@ paths:
application/json:
schema:
type: string
+ text/plain:
+ schema:
+ type: string
components:
schemas:
User:
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/FullSwaggerService.yaml b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/FullSwaggerService.yaml
index 2fb53e131..3e7cfa134 100644
--- a/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/FullSwaggerService.yaml
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/FullSwaggerService.yaml
@@ -63,6 +63,23 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
+ /fileDownload:
+ get:
+ operationId: fileDownload
+ responses:
+ "200":
+ description: response of 200
+ content:
+ '*/*':
+ schema:
+ type: string
+ format: binary
/fileUpload:
post:
operationId: fileUpload
@@ -82,7 +99,7 @@ paths:
"200":
description: response of 200
content:
- application/json:
+ text/plain:
schema:
type: string
/queryListMULTI:
@@ -105,4 +122,20 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
+ /textPlain:
+ get:
+ operationId: textPlain
+ responses:
+ "200":
+ description: response of 200
+ content:
+ text/plain:
+ schema:
+ type: string
components: {}
\ No newline at end of file
diff --git a/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/echo.yaml b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/echo.yaml
index 3776926a6..04ba2b2be 100644
--- a/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/echo.yaml
+++ b/swagger/swagger-generator/generator-jaxrs/src/test/resources/schemas/echo.yaml
@@ -160,6 +160,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/dynamicStatusEnum:
post:
operationId: dynamicStatusEnum
@@ -198,6 +204,14 @@ paths:
schema:
type: integer
format: int32
+ application/protobuf:
+ schema:
+ type: integer
+ format: int32
+ text/plain:
+ schema:
+ type: integer
+ format: int32
/echo/{targetName}:
post:
operationId: echo
@@ -234,6 +248,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/emptyPath:
post:
operationId: emptyPath
@@ -288,6 +308,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/jdkStatusEnum:
post:
operationId: jdkStatusEnum
@@ -332,6 +358,18 @@ paths:
enum:
- BAD_REQUEST
- NOT_FOUND
+ application/protobuf:
+ schema:
+ type: string
+ enum:
+ - BAD_REQUEST
+ - NOT_FOUND
+ text/plain:
+ schema:
+ type: string
+ enum:
+ - BAD_REQUEST
+ - NOT_FOUND
/nestedListString:
post:
operationId: nestedListString
@@ -370,6 +408,20 @@ paths:
type: array
items:
type: string
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ type: array
+ items:
+ type: string
+ text/plain:
+ schema:
+ type: array
+ items:
+ type: array
+ items:
+ type: string
/:
patch:
operationId: patch
@@ -391,6 +443,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/queryComplex:
get:
operationId: queryComplex
@@ -408,6 +466,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testRawJson:
post:
operationId: rawJsonStringMethod
@@ -434,15 +498,19 @@ paths:
responses:
"200":
description: response of 200
- headers: {}
content:
application/json:
schema:
- type: number
- description: ""
+ type: integer
+ format: int32
+ application/protobuf:
+ schema:
+ type: integer
+ format: int32
+ text/plain:
+ schema:
+ type: integer
format: int32
- nullable: false
- example: ""
components:
schemas:
AggregatedParam:
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/DefaultParameterSchema.yaml b/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/DefaultParameterSchema.yaml
index 568dc238f..42c4a2ad0 100644
--- a/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/DefaultParameterSchema.yaml
+++ b/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/DefaultParameterSchema.yaml
@@ -38,6 +38,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testMultipleMediaType:
put:
operationId: testMultipleMediaType
@@ -53,6 +59,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testObjectParam:
get:
operationId: testObjectParam
@@ -73,6 +85,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testSimpleParam:
get:
operationId: testSimpleParam
@@ -88,6 +106,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testSingleMediaType:
post:
operationId: testSingleMediaType
@@ -103,6 +127,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testUnsupportedParamType:
get:
operationId: testUnsupportedParamType
@@ -131,6 +161,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
components:
schemas:
TestParam:
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/echo.yaml b/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/echo.yaml
index 97837adfb..7e70e366c 100644
--- a/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/echo.yaml
+++ b/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/echo.yaml
@@ -35,6 +35,16 @@ paths:
type: array
items:
type: string
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ type: string
+ text/plain:
+ schema:
+ type: array
+ items:
+ type: string
/cookie:
put:
operationId: cookie
@@ -136,6 +146,20 @@ paths:
type: array
items:
type: string
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ type: array
+ items:
+ type: string
+ text/plain:
+ schema:
+ type: array
+ items:
+ type: array
+ items:
+ type: string
/part:
put:
operationId: part
@@ -264,6 +288,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testResponseEntityOptional:
put:
operationId: testResponseEntityOptional
@@ -274,4 +304,10 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
components: {}
\ No newline at end of file
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/mixupAnnotations.yaml b/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/mixupAnnotations.yaml
index 7c04f5016..1644797b0 100644
--- a/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/mixupAnnotations.yaml
+++ b/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/mixupAnnotations.yaml
@@ -50,6 +50,14 @@ paths:
schema:
type: string
format: byte
+ application/protobuf:
+ schema:
+ type: string
+ format: byte
+ text/plain:
+ schema:
+ type: string
+ format: byte
/defaultQueryParam:
post:
operationId: defaultQueryParam
@@ -78,6 +86,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/diffNames:
get:
summary: differentName
@@ -103,6 +117,14 @@ paths:
schema:
type: integer
format: int32
+ application/protobuf:
+ schema:
+ type: integer
+ format: int32
+ text/plain:
+ schema:
+ type: integer
+ format: int32
/upload:
post:
operationId: fileUpload
@@ -125,6 +147,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/reduce:
get:
operationId: reduce
@@ -148,6 +176,14 @@ paths:
schema:
type: integer
format: int32
+ application/protobuf:
+ schema:
+ type: integer
+ format: int32
+ text/plain:
+ schema:
+ type: integer
+ format: int32
/testDefaultValue:
get:
operationId: testDefaultValue
@@ -193,6 +229,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/testImplicitForm:
post:
operationId: testImplicitForm
@@ -218,6 +260,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/uploadFileAndAttribute:
post:
operationId: uploadFileAndAttribute
@@ -239,6 +287,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/uploadFilesAndAttribute:
post:
operationId: uploadFilesAndAttribute
@@ -262,6 +316,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/usingDeleteMapping/{targetName}:
delete:
operationId: usingDeleteMapping
@@ -301,6 +361,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/usingGetMapping/{targetName}:
get:
operationId: usingGetMapping
@@ -340,6 +406,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/usingPatchMapping/{targetName}:
patch:
operationId: usingPatchMapping
@@ -379,6 +451,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/usingPostMapping/{targetName}:
post:
operationId: usingPostMapping
@@ -418,6 +496,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/usingPutMapping/{targetName}:
put:
operationId: usingPutMapping
@@ -457,6 +541,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
/usingRequestMapping/{targetName}:
post:
operationId: usingRequestMapping
@@ -496,6 +586,12 @@ paths:
application/json:
schema:
type: string
+ application/protobuf:
+ schema:
+ type: string
+ text/plain:
+ schema:
+ type: string
components:
schemas:
User:
diff --git a/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/responseEntity.yaml b/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/responseEntity.yaml
index 036f362a2..53459a889 100644
--- a/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/responseEntity.yaml
+++ b/swagger/swagger-generator/generator-springmvc/src/test/resources/schemas/responseEntity.yaml
@@ -35,6 +35,16 @@ paths:
type: array
items:
$ref: '#/components/schemas/User'
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ text/plain:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
/usingGetMapping:
get:
operationId: usingGetMapping
@@ -47,6 +57,16 @@ paths:
type: array
items:
$ref: '#/components/schemas/User'
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ text/plain:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
/usingPatchMapping:
patch:
operationId: usingPatchMapping
@@ -59,6 +79,16 @@ paths:
type: array
items:
$ref: '#/components/schemas/User'
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ text/plain:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
/usingPostMapping:
post:
operationId: usingPostMapping
@@ -71,6 +101,16 @@ paths:
type: array
items:
$ref: '#/components/schemas/User'
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ text/plain:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
/usingPutMapping:
put:
operationId: usingPutMapping
@@ -83,6 +123,16 @@ paths:
type: array
items:
$ref: '#/components/schemas/User'
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ text/plain:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
/usingRequestMapping:
put:
operationId: usingRequestMapping
@@ -95,6 +145,16 @@ paths:
type: array
items:
$ref: '#/components/schemas/User'
+ application/protobuf:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
+ text/plain:
+ schema:
+ type: array
+ items:
+ $ref: '#/components/schemas/User'
components:
schemas:
User: