Skip to content

Commit baadf78

Browse files
committed
Merge pull request #1501 from swagger-api/feature/example-values
Feature/example values
2 parents 5576aba + da61c09 commit baadf78

File tree

12 files changed

+410
-138
lines changed

12 files changed

+410
-138
lines changed

modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiImplicitParam.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,4 +109,22 @@
109109
* Valid values are {@code path}, {@code query}, {@code body}, {@code header} or {@code form}.
110110
*/
111111
String paramType() default "";
112+
113+
/**
114+
* a single example for non-body type parameters
115+
*
116+
* @since 1.5.4
117+
*
118+
* @return
119+
*/
120+
String example() default "";
121+
122+
/**
123+
* Examples for the parameter. Applies only to BodyParameters
124+
*
125+
* @since 1.5.4
126+
*
127+
* @return
128+
*/
129+
Example examples() default @Example(value = @ExampleProperty(mediaType = "", value = ""));
112130
}

modules/swagger-annotations/src/main/java/io/swagger/annotations/ApiParam.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,22 @@
9292
* Hides the parameter from the list of parameters.
9393
*/
9494
boolean hidden() default false;
95+
96+
/**
97+
* a single example for non-body type parameters
98+
*
99+
* @since 1.5.4
100+
*
101+
* @return
102+
*/
103+
String example() default "";
104+
105+
/**
106+
* Examples for the parameter. Applies only to BodyParameters
107+
*
108+
* @since 1.5.4
109+
*
110+
* @return
111+
*/
112+
Example examples() default @Example(value = @ExampleProperty(mediaType = "", value = ""));
95113
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
/**
2+
* Copyright 2015 SmartBear Software
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.swagger.annotations;
18+
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
/**
25+
* An optionally named list of example properties.
26+
*
27+
* @since 1.5.4
28+
*/
29+
@Target(ElementType.ANNOTATION_TYPE)
30+
@Retention(RetentionPolicy.RUNTIME)
31+
public @interface Example {
32+
/**
33+
* The examples properties.
34+
*
35+
* @return the actual extension properties
36+
* @see ExampleProperty
37+
*/
38+
ExampleProperty[] value();
39+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/**
2+
* Copyright 2015 SmartBear Software
3+
* <p>
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
* <p>
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
* <p>
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.swagger.annotations;
18+
19+
import java.lang.annotation.ElementType;
20+
import java.lang.annotation.Retention;
21+
import java.lang.annotation.RetentionPolicy;
22+
import java.lang.annotation.Target;
23+
24+
/**
25+
* A mediaType/value property within a Swagger example
26+
*
27+
* @see Example
28+
* @since 1.5.4
29+
*/
30+
@Target(ElementType.ANNOTATION_TYPE)
31+
@Retention(RetentionPolicy.RUNTIME)
32+
public @interface ExampleProperty {
33+
34+
/**
35+
* The name of the property.
36+
*
37+
* @return the name of the property
38+
*/
39+
String mediaType() default "default";
40+
41+
/**
42+
* The value of the example.
43+
*
44+
* @return the value of the example
45+
*/
46+
String value();
47+
}

modules/swagger-core/src/main/java/io/swagger/util/ParameterProcessor.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
import io.swagger.annotations.ApiImplicitParam;
44
import io.swagger.annotations.ApiParam;
5+
import io.swagger.annotations.Example;
6+
import io.swagger.annotations.ExampleProperty;
57
import io.swagger.converter.ModelConverters;
68
import io.swagger.models.Model;
79
import io.swagger.models.Swagger;
@@ -50,12 +52,18 @@ public static Parameter applyAnnotations(Swagger swagger, Parameter parameter, T
5052
if (StringUtils.isNotEmpty(param.getDescription())) {
5153
p.setDescription(param.getDescription());
5254
}
55+
if (StringUtils.isNotEmpty(param.getExample())) {
56+
p.setExample(param.getExample());
57+
}
5358
if (StringUtils.isNotEmpty(param.getAccess())) {
5459
p.setAccess(param.getAccess());
5560
}
5661
if (StringUtils.isNotEmpty(param.getDataType())) {
5762
p.setType(param.getDataType());
5863
}
64+
if (StringUtils.isNotEmpty(param.getExample())) {
65+
p.setType(param.getExample());
66+
}
5967
if (helper.getMinItems() != null) {
6068
p.setMinItems(helper.getMinItems());
6169
}
@@ -80,6 +88,7 @@ public static Parameter applyAnnotations(Swagger swagger, Parameter parameter, T
8088
args.put(PropertyBuilder.PropertyId.MAXIMUM, p.getMaximum());
8189
p.setMaximum(null);
8290
args.put(PropertyBuilder.PropertyId.EXCLUSIVE_MAXIMUM, p.isExclusiveMaximum());
91+
args.put(PropertyBuilder.PropertyId.EXAMPLE, p.getExample());
8392
p.setExclusiveMaximum(null);
8493
Property items = PropertyBuilder.build(p.getType(), p.getFormat(), args);
8594
p.type(ArrayProperty.TYPE).format(null).items(items);
@@ -103,6 +112,35 @@ public static Parameter applyAnnotations(Swagger swagger, Parameter parameter, T
103112
// must be a body param
104113
BodyParameter bp = new BodyParameter();
105114

115+
if (helper.getApiParam() != null) {
116+
ParamWrapper<?> pw = helper.getApiParam();
117+
118+
if (pw instanceof ApiParamWrapper) {
119+
ApiParamWrapper apiParam = (ApiParamWrapper) pw;
120+
Example example = apiParam.getExamples();
121+
if (example != null && example.value() != null) {
122+
for (ExampleProperty ex : example.value()) {
123+
String mediaType = ex.mediaType();
124+
String value = ex.value();
125+
if (!mediaType.isEmpty() && !value.isEmpty()) {
126+
bp.example(mediaType.trim(), value.trim());
127+
}
128+
}
129+
}
130+
} else if (pw instanceof ApiImplicitParamWrapper) {
131+
ApiImplicitParamWrapper apiParam = (ApiImplicitParamWrapper) pw;
132+
Example example = apiParam.getExamples();
133+
if (example != null && example.value() != null) {
134+
for (ExampleProperty ex : example.value()) {
135+
String mediaType = ex.mediaType();
136+
String value = ex.value();
137+
if (!mediaType.isEmpty() && !value.isEmpty()) {
138+
bp.example(mediaType.trim(), value.trim());
139+
}
140+
}
141+
}
142+
}
143+
}
106144
bp.setRequired(param.isRequired());
107145
bp.setName(StringUtils.isNotEmpty(param.getName()) ? param.getName() : "body");
108146

@@ -179,6 +217,8 @@ public interface ParamWrapper<T extends Annotation> {
179217
T getAnnotation();
180218

181219
boolean isHidden();
220+
221+
String getExample();
182222
}
183223

184224
/**
@@ -341,6 +381,19 @@ public ApiParam getAnnotation() {
341381
public boolean isHidden() {
342382
return apiParam.hidden();
343383
}
384+
385+
@Override
386+
public String getExample() {
387+
return apiParam.example();
388+
}
389+
390+
;
391+
392+
public Example getExamples() {
393+
return apiParam.examples();
394+
}
395+
396+
;
344397
}
345398

346399
/**
@@ -408,5 +461,14 @@ public ApiImplicitParam getAnnotation() {
408461
public boolean isHidden() {
409462
return false;
410463
}
464+
465+
@Override
466+
public String getExample() {
467+
return apiParam.example();
468+
}
469+
470+
public Example getExamples() {
471+
return apiParam.examples();
472+
}
411473
}
412474
}

modules/swagger-jaxrs/src/test/java/io/swagger/SimpleScannerTest.java

Lines changed: 44 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -28,32 +28,9 @@
2828
import io.swagger.models.properties.Property;
2929
import io.swagger.models.properties.RefProperty;
3030
import io.swagger.models.properties.StringProperty;
31-
import io.swagger.resources.HiddenResource;
32-
import io.swagger.resources.Resource1041;
33-
import io.swagger.resources.Resource1073;
34-
import io.swagger.resources.Resource1085;
35-
import io.swagger.resources.Resource653;
36-
import io.swagger.resources.Resource841;
37-
import io.swagger.resources.Resource877;
38-
import io.swagger.resources.Resource937;
39-
import io.swagger.resources.ResourceWithApiOperationCode;
40-
import io.swagger.resources.ResourceWithApiResponseResponseContainer;
41-
import io.swagger.resources.ResourceWithBodyParams;
42-
import io.swagger.resources.ResourceWithEmptyModel;
43-
import io.swagger.resources.ResourceWithEnums;
44-
import io.swagger.resources.ResourceWithInnerClass;
45-
import io.swagger.resources.ResourceWithMapReturnValue;
46-
import io.swagger.resources.ResourceWithRanges;
47-
import io.swagger.resources.ResourceWithResponse;
48-
import io.swagger.resources.ResourceWithResponseHeaders;
49-
import io.swagger.resources.ResourceWithTypedResponses;
50-
import io.swagger.resources.ResourceWithVoidReturns;
51-
import io.swagger.resources.SimpleResource;
52-
import io.swagger.resources.SimpleResourceWithoutAnnotations;
53-
import io.swagger.resources.SimpleSelfReferencingSubResource;
54-
import io.swagger.resources.TaggedResource;
55-
import io.swagger.resources.NicknamedOperation;
31+
import io.swagger.resources.*;
5632

33+
import io.swagger.util.Json;
5734
import org.testng.annotations.Test;
5835

5936
import java.util.ArrayList;
@@ -541,4 +518,46 @@ public void scanResourceWithApiOperationNickname() {
541518

542519
assertEquals(op.getOperationId(), "getMyNicknameTest");
543520
}
521+
522+
@Test(description = "scan a resource with operation post example")
523+
public void scanClassWithExamplePost() {
524+
Swagger swagger = getSwagger(ClassWithExamplePost.class);
525+
Parameter param = swagger.getPaths().get("/external/info").getPost().getParameters().get(0);
526+
BodyParameter bp = (BodyParameter) param;
527+
assertNotNull(bp.getExamples());
528+
assertTrue(bp.getExamples().size() == 1);
529+
String value = bp.getExamples().get("application/json");
530+
assertEquals("[\"a\",\"b\"]", value);
531+
}
532+
533+
@Test(description = "scan a resource with operation implicit post example")
534+
public void scanClassWithImplicitExamplePost() {
535+
Swagger swagger = getSwagger(ClassWithExamplePost.class);
536+
Parameter param = swagger.getPaths().get("/external/info2").getPost().getParameters().get(0);
537+
BodyParameter bp = (BodyParameter) param;
538+
assertNotNull(bp.getExamples());
539+
assertTrue(bp.getExamples().size() == 1);
540+
String value = bp.getExamples().get("application/json");
541+
assertEquals("[\"a\",\"b\"]", value);
542+
}
543+
544+
@Test(description = "scan a resource with query param example")
545+
public void scanClassWithExampleQuery() {
546+
Swagger swagger = getSwagger(ClassWithExamplePost.class);
547+
Parameter param = swagger.getPaths().get("/external/info").getGet().getParameters().get(0);
548+
QueryParameter bp = (QueryParameter) param;
549+
assertNotNull(bp.getExample());
550+
Object value = bp.getExample();
551+
assertEquals("a,b,c", value);
552+
}
553+
554+
@Test(description = "scan a resource with implicit operation query example")
555+
public void scanClassWithImplicitExampleQuery() {
556+
Swagger swagger = getSwagger(ClassWithExamplePost.class);
557+
Parameter param = swagger.getPaths().get("/external/info2").getGet().getParameters().get(0);
558+
QueryParameter bp = (QueryParameter) param;
559+
assertNotNull(bp.getExample());
560+
Object value = bp.getExample();
561+
assertEquals("77", value);
562+
}
544563
}
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package io.swagger.resources;
2+
3+
import io.swagger.annotations.*;
4+
5+
import javax.ws.rs.GET;
6+
import javax.ws.rs.POST;
7+
import javax.ws.rs.Path;
8+
import javax.ws.rs.QueryParam;
9+
import java.util.ArrayList;
10+
11+
@Api("/external/info/")
12+
public class ClassWithExamplePost {
13+
@ApiOperation(value = "test")
14+
@POST
15+
@Path("external/info")
16+
public void postTest(@ApiParam(value = "test",
17+
examples = @Example(value = {
18+
@ExampleProperty(mediaType="application/json", value="[\"a\",\"b\"]")
19+
})) ArrayList<String> tenantId) {
20+
return;
21+
}
22+
23+
@ApiOperation(value = "test")
24+
@POST
25+
@Path("external/info2")
26+
@ApiImplicitParams({
27+
@ApiImplicitParam(
28+
paramType = "body",
29+
name = "myPody",
30+
dataType = "[Ljava.lang.String;",
31+
examples = @Example(value = {
32+
@ExampleProperty(mediaType="application/json", value="[\"a\",\"b\"]")}))
33+
})
34+
public void implicitPostTest() {
35+
return;
36+
}
37+
38+
@ApiOperation(value = "test")
39+
@GET
40+
@Path("external/info")
41+
public void queryExample(@ApiParam(value = "test",
42+
example = "a,b,c") @QueryParam("tenantId") ArrayList<String> tenantId) {
43+
return;
44+
}
45+
46+
@ApiOperation(value = "test")
47+
@GET
48+
@Path("external/info2")
49+
@ApiImplicitParams({
50+
@ApiImplicitParam(
51+
paramType = "query",
52+
name = "myId",
53+
dataType = "java.lang.Long",
54+
example = "77") })
55+
public void implicitQueryExample() {
56+
return;
57+
}
58+
}

0 commit comments

Comments
 (0)