Skip to content

Commit cbdd30f

Browse files
authored
Merge pull request #179 from SentryMan/beanParam
BeanParam OpenAPI
2 parents 271d1d0 + bb234b4 commit cbdd30f

File tree

6 files changed

+156
-31
lines changed

6 files changed

+156
-31
lines changed

http-generator-core/src/main/java/io/avaje/http/generator/core/ElementReader.java

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
package io.avaje.http.generator.core;
22

3-
import static io.avaje.http.generator.core.ProcessingContext.*;
43
import static io.avaje.http.generator.core.ParamType.RESPONSE_HANDLER;
4+
import static io.avaje.http.generator.core.ProcessingContext.platform;
5+
import static io.avaje.http.generator.core.ProcessingContext.typeElement;
56

67
import java.util.List;
78
import java.util.Objects;
@@ -245,7 +246,7 @@ void writeParamName(Append writer) {
245246
* Build the OpenAPI documentation for this parameter.
246247
*/
247248
void buildApiDocumentation(MethodDocBuilder methodDoc) {
248-
if (!isPlatformContext() && !isParamMap) {
249+
if (!isPlatformContext() && !isParamMap && paramType != ParamType.BEANPARAM) {
249250
new MethodParamDocBuilder(methodDoc, this).build();
250251
}
251252
}

http-generator-core/src/main/java/io/avaje/http/generator/core/MethodParam.java

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
11
package io.avaje.http.generator.core;
22

3-
import io.avaje.http.generator.core.openapi.MethodDocBuilder;
3+
import static io.avaje.http.generator.core.ProcessingContext.asElement;
44

5+
import javax.lang.model.element.ElementKind;
56
import javax.lang.model.element.VariableElement;
67

8+
import io.avaje.http.generator.core.openapi.MethodDocBuilder;
9+
710
public class MethodParam {
811

912
private final ElementReader elementParam;
@@ -29,7 +32,25 @@ public void buildParamName(Append writer) {
2932
}
3033

3134
public void buildApiDocumentation(MethodDocBuilder methodDoc) {
32-
elementParam.buildApiDocumentation(methodDoc);
35+
if (elementParam.paramType() != ParamType.BEANPARAM)
36+
elementParam.buildApiDocumentation(methodDoc);
37+
else {
38+
asElement(elementParam.element().asType()).getEnclosedElements().stream()
39+
.filter(e -> e.getKind() == ElementKind.FIELD)
40+
.map(VariableElement.class::cast)
41+
.forEach(
42+
e -> {
43+
final var typeMirror = e.asType();
44+
45+
new ElementReader(
46+
e,
47+
Util.parse(typeMirror.toString()),
48+
Util.typeDef(typeMirror),
49+
ParamType.QUERYPARAM,
50+
false)
51+
.buildApiDocumentation(methodDoc);
52+
});
53+
}
3354
}
3455

3556
public boolean isBody() {

http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/DocContext.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import io.avaje.http.generator.core.SecuritySchemesPrism;
2323
import io.avaje.http.generator.core.TagPrism;
2424
import io.avaje.http.generator.core.TagsPrism;
25+
import io.avaje.http.generator.core.Util;
2526
import io.swagger.v3.oas.models.Components;
2627
import io.swagger.v3.oas.models.OpenAPI;
2728
import io.swagger.v3.oas.models.Operation;
@@ -77,12 +78,17 @@ private OpenAPI initOpenAPI() {
7778
}
7879

7980
Schema toSchema(String rawType, Element element) {
80-
TypeElement typeElement = elements.getTypeElement(rawType);
81+
final var typeElement = elements.getTypeElement(rawType);
82+
final var varElement =
83+
elements.getTypeElement(Util.trimAnnotations(element.asType().toString()));
84+
8185
if (typeElement == null) {
8286
// primitive types etc
8387
return schemaBuilder.toSchema(element.asType());
88+
} else if (varElement != null) {
89+
return schemaBuilder.toSchema(element);
8490
} else {
85-
return schemaBuilder.toSchema(typeElement.asType());
91+
return schemaBuilder.toSchema(typeElement);
8692
}
8793
}
8894

http-generator-core/src/main/java/io/avaje/http/generator/core/openapi/SchemaDocBuilder.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,17 @@ private static TypeMirror typeArgument(TypeMirror type) {
134134
return typeArguments.get(0);
135135
}
136136

137+
Schema<?> toSchema(Element element) {
138+
var schema = toSchema(element.asType());
139+
140+
setLengthMinMax(element, schema);
141+
setFormatFromValidation(element, schema);
142+
if (isNotNullable(element)) {
143+
schema.setNullable(Boolean.FALSE);
144+
}
145+
return schema;
146+
}
147+
137148
Schema<?> toSchema(TypeMirror type) {
138149
if (types.isAssignable(type, completableFutureType)) {
139150
type = typeArgument(type);

tests/test-javalin-jsonb/src/main/java/org/example/myapp/web/GetBeanForm.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import javax.validation.constraints.NotNull;
88
import javax.validation.constraints.Size;
99

10+
import io.avaje.http.api.Header;
1011
import io.avaje.jsonb.Json;
1112

1213
@Json
@@ -22,6 +23,8 @@ public class GetBeanForm {
2223
private String email;
2324

2425
private List<String> addresses;
26+
@Header
27+
private String head;
2528

2629
public String getName() {
2730
return name;
@@ -56,4 +59,12 @@ public List<String> getAddresses() {
5659
public void setAddresses(List<String> addresses) {
5760
this.addresses = addresses;
5861
}
62+
63+
public String getHead() {
64+
return head;
65+
}
66+
67+
public void setHead(String head) {
68+
this.head = head;
69+
}
5970
}

tests/test-javalin-jsonb/src/main/resources/public/openapi.json

Lines changed: 100 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -692,10 +692,39 @@
692692
"description" : "",
693693
"parameters" : [
694694
{
695-
"name" : "bean",
696-
"in" : "bean",
695+
"name" : "name",
696+
"in" : "query",
697+
"schema" : {
698+
"maxLength" : 150,
699+
"minLength" : 2,
700+
"type" : "string",
701+
"nullable" : false
702+
}
703+
},
704+
{
705+
"name" : "email",
706+
"in" : "query",
697707
"schema" : {
698-
"$ref" : "#/components/schemas/GetBeanForm"
708+
"maxLength" : 100,
709+
"type" : "string",
710+
"format" : "email"
711+
}
712+
},
713+
{
714+
"name" : "addresses",
715+
"in" : "query",
716+
"schema" : {
717+
"type" : "array",
718+
"items" : {
719+
"type" : "string"
720+
}
721+
}
722+
},
723+
{
724+
"name" : "head",
725+
"in" : "header",
726+
"schema" : {
727+
"type" : "string"
699728
}
700729
}
701730
],
@@ -1125,6 +1154,40 @@
11251154
}
11261155
}
11271156
},
1157+
"/test/byteArray" : {
1158+
"get" : {
1159+
"tags" : [
1160+
1161+
],
1162+
"summary" : "",
1163+
"description" : "",
1164+
"requestBody" : {
1165+
"content" : {
1166+
"application/json" : {
1167+
"schema" : {
1168+
"type" : "array",
1169+
"items" : {
1170+
"$ref" : "#/components/schemas/byte"
1171+
}
1172+
}
1173+
}
1174+
},
1175+
"required" : true
1176+
},
1177+
"responses" : {
1178+
"200" : {
1179+
"description" : "",
1180+
"content" : {
1181+
"application/json" : {
1182+
"schema" : {
1183+
"type" : "string"
1184+
}
1185+
}
1186+
}
1187+
}
1188+
}
1189+
}
1190+
},
11281191
"/test/ctx" : {
11291192
"get" : {
11301193
"tags" : [
@@ -1466,6 +1529,37 @@
14661529
}
14671530
}
14681531
},
1532+
"/test/inputStream" : {
1533+
"get" : {
1534+
"tags" : [
1535+
1536+
],
1537+
"summary" : "",
1538+
"description" : "",
1539+
"requestBody" : {
1540+
"content" : {
1541+
"application/json" : {
1542+
"schema" : {
1543+
"$ref" : "#/components/schemas/InputStream"
1544+
}
1545+
}
1546+
},
1547+
"required" : true
1548+
},
1549+
"responses" : {
1550+
"200" : {
1551+
"description" : "",
1552+
"content" : {
1553+
"application/json" : {
1554+
"schema" : {
1555+
"type" : "string"
1556+
}
1557+
}
1558+
}
1559+
}
1560+
}
1561+
}
1562+
},
14691563
"/test/int" : {
14701564
"put" : {
14711565
"tags" : [
@@ -1830,28 +1924,6 @@
18301924
}
18311925
}
18321926
},
1833-
"GetBeanForm" : {
1834-
"type" : "object",
1835-
"properties" : {
1836-
"name" : {
1837-
"maxLength" : 150,
1838-
"minLength" : 2,
1839-
"type" : "string",
1840-
"nullable" : false
1841-
},
1842-
"email" : {
1843-
"maxLength" : 100,
1844-
"type" : "string",
1845-
"format" : "email"
1846-
},
1847-
"addresses" : {
1848-
"type" : "array",
1849-
"items" : {
1850-
"type" : "string"
1851-
}
1852-
}
1853-
}
1854-
},
18551927
"HelloDto" : {
18561928
"type" : "object",
18571929
"properties" : {
@@ -1901,6 +1973,9 @@
19011973
}
19021974
}
19031975
},
1976+
"InputStream" : {
1977+
"type" : "object"
1978+
},
19041979
"MyForm" : {
19051980
"type" : "object",
19061981
"properties" : {

0 commit comments

Comments
 (0)