Skip to content

Commit 63f2ef4

Browse files
author
Bastian Wilhelm
committed
Merge remote-tracking branch 'upstream/master' into #34-Support-bean-validation
# Conflicts: # src/testInt/groovy/com/github/hauner/openapi/generatr/GeneratrEndToEndTest.groovy
2 parents 4b74d49 + fa0b14a commit 63f2ef4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+823
-538
lines changed
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
layout: default
3+
title: Additional Parameters
4+
parent: The generatr
5+
nav_order: 11
6+
---
7+
8+
# Additional Parameters
9+
10+
Sometimes it may be useful to add an additional parameter to an endpoint that is an implementation detail.
11+
It should not be part of the public api. Think of the `HttpServletRequest` or a custom Spring
12+
`HandlerMethodArgumentResolver`.
13+
14+
Such an additional parameter can be described in the mappings as an endpoint parameter. Assuming there
15+
is an endpoint `/foo` defined in the OpenAPI interfaces it is possible to add extra parameters by using
16+
an `add <paramter name>` `as <java type>` entry.
17+
18+
```yaml
19+
map:
20+
paths:
21+
/foo:
22+
23+
parameters:
24+
- add: request
25+
as: javax.servlet.http.HttpServletRequest
26+
```
27+
28+
will add the *additional* parameter to the generated interface method.
29+
30+
```java
31+
@GetMapping(path = "/foo")
32+
ResponseEntity<?> getFoo(@RequestParam(name = "bar") String bar, HttpServletRequest request);
33+
```
34+

docs/howto/file_download.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ parent: HowTo's
55
nav_order: 10
66
---
77

8-
Describing an endpoint to download file attachments.
8+
# Describing an endpoint to download files
99

1010
```yaml
1111
/v1/attachments/{id}:

docs/howto/file_upload.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ parent: HowTo's
55
nav_order: 15
66
---
77

8-
Describing and endpoint for uploading a singe file:
8+
# Describing and endpoint for uploading a singe file
99

1010
```yaml
1111
/attachments:
@@ -30,7 +30,7 @@ Describing and endpoint for uploading a singe file:
3030
format: int64
3131
```
3232
33-
Describing an endpoint for uploading multiple files:
33+
# Describing an endpoint for uploading multiple files
3434
3535
```yaml
3636
/attachments:

docs/index.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@ See the [release notes][generatr-releases]{:target="_blank"}.
6565
- gradle support via [openapi-generatr-gradle][generatr-gradle] plugin (the plugin is currently the only option
6666
to run the generatr).
6767

68-
- <span class="label label-yellow">planned</span> add additional parameters to an endpoint which are not defined in
69-
the openapi description. For example to pass a `HttpServletRequest` to the endpoint implementation.
68+
- add additional parameters to an endpoint which are not defined in the OpenAPI description. For example to pass
69+
a `HttpServletRequest` to the endpoint implementation. <span class="label label-green">since 1.0.0.M6</span>
7070

7171
- <span class="label label-yellow">planned</span> handle multiple responses by generating one endpoint method for
7272
each response content type.

docs/mapping/basic.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ nav_order: 1
88
# Basic (primitive) Mappings
99

1010
The OpenAPI specification defines a couple of basic [data types][openapi-spec-types]{:target="_blank"}.
11-
The basic data types are built-in in the generatr. That means the generatr will map the basic types
11+
The basic data types are built-in into the generatr. That means the generatr will map the basic types
1212
automatically to a corresponding java type. There is no explicit type mapping required.
1313

1414
## OpenAPI to Java type mapping

src/main/groovy/com/github/hauner/openapi/spring/converter/ApiConverter.groovy

Lines changed: 70 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,15 +16,20 @@
1616

1717
package com.github.hauner.openapi.spring.converter
1818

19-
import com.github.hauner.openapi.spring.converter.schema.ParameterSchemaInfo
19+
import com.github.hauner.openapi.spring.converter.mapping.AddParameterTypeMapping
20+
import com.github.hauner.openapi.spring.converter.mapping.Mapping
21+
import com.github.hauner.openapi.spring.converter.mapping.MappingSchema
22+
import com.github.hauner.openapi.spring.converter.mapping.TargetType
23+
import com.github.hauner.openapi.spring.converter.mapping.TypeMapping
2024
import com.github.hauner.openapi.spring.converter.schema.RefResolver
21-
import com.github.hauner.openapi.spring.converter.schema.ResponseSchemaInfo
2225
import com.github.hauner.openapi.spring.converter.schema.SchemaInfo
2326
import com.github.hauner.openapi.spring.model.Api
2427
import com.github.hauner.openapi.spring.model.DataTypes
2528
import com.github.hauner.openapi.spring.model.Endpoint
2629
import com.github.hauner.openapi.spring.model.RequestBody as ModelRequestBody
30+
import com.github.hauner.openapi.spring.model.datatypes.MappedDataType
2731
import com.github.hauner.openapi.spring.model.datatypes.ObjectDataType
32+
import com.github.hauner.openapi.spring.model.parameters.AdditionalParameter
2833
import com.github.hauner.openapi.spring.model.parameters.CookieParameter
2934
import com.github.hauner.openapi.spring.model.parameters.HeaderParameter
3035
import com.github.hauner.openapi.spring.model.parameters.MultipartParameter
@@ -56,6 +61,25 @@ class ApiConverter {
5661
private DataTypeConverter dataTypeConverter
5762
private ApiOptions options
5863

64+
class MappingSchemaEndpoint implements MappingSchema {
65+
Endpoint endpoint
66+
67+
@Override
68+
String getPath () {
69+
endpoint.path
70+
}
71+
72+
@Override
73+
String getName () {
74+
null
75+
}
76+
77+
@Override
78+
String getContentType () {
79+
null
80+
}
81+
}
82+
5983
ApiConverter(ApiOptions options) {
6084
this.options = options
6185

@@ -91,7 +115,8 @@ class ApiConverter {
91115
operations.each { httpOperation ->
92116
def itf = target.getInterface (getInterfaceName (httpOperation))
93117

94-
Endpoint ep = new Endpoint (path: path, method: httpOperation.httpMethod)
118+
Endpoint ep = new Endpoint (path: path,
119+
method: (httpOperation as HttpMethodTrait).httpMethod)
95120

96121
try {
97122
def resolver = new RefResolver (api.components)
@@ -103,7 +128,8 @@ class ApiConverter {
103128
itf.endpoints.add (ep)
104129

105130
} catch (UnknownDataTypeException e) {
106-
log.error ("failed to parse endpoint {} {} because of: '{}'", ep.path, ep.method, e.message)
131+
log.error ("failed to parse endpoint {} {} because of: '{}'",
132+
ep.path, ep.method, e.message)
107133
}
108134
}
109135
}
@@ -113,6 +139,11 @@ class ApiConverter {
113139
parameters.each { Parameter parameter ->
114140
ep.parameters.add (createParameter (ep.path, parameter, dataTypes, resolver))
115141
}
142+
143+
List<Mapping> addMappings = findAdditionalParameter (ep)
144+
addMappings.each {
145+
ep.parameters.add (createAdditionalParameter (ep.path, it as AddParameterTypeMapping, dataTypes, resolver))
146+
}
116147
}
117148

118149
private void collectRequestBody (RequestBody requestBody, Endpoint ep, DataTypes dataTypes, RefResolver resolver) {
@@ -161,8 +192,11 @@ class ApiConverter {
161192
}
162193

163194
private ModelParameter createParameter (String path, Parameter parameter, DataTypes dataTypes, resolver) {
164-
def info = new ParameterSchemaInfo (path, parameter.schema, parameter.name)
165-
info.resolver = resolver
195+
def info = new SchemaInfo (
196+
path: path,
197+
name: parameter.name,
198+
schema: parameter.schema,
199+
resolver: resolver)
166200

167201
DataType dataType = dataTypeConverter.convert (info, dataTypes)
168202

@@ -181,6 +215,19 @@ class ApiConverter {
181215
}
182216
}
183217

218+
private ModelParameter createAdditionalParameter (String path, AddParameterTypeMapping mapping, DataTypes dataTypes, RefResolver resolver) {
219+
TypeMapping tm = mapping.childMappings.first ()
220+
TargetType tt = tm.targetType
221+
222+
def addType = new MappedDataType (
223+
type: tt.name,
224+
pkg: tt.pkg,
225+
genericTypes: tt.genericNames
226+
)
227+
228+
new AdditionalParameter (name: mapping.parameterName, required: true, dataType: addType)
229+
}
230+
184231
private ModelRequestBody createRequestBody (String contentType, SchemaInfo info, boolean required, DataTypes dataTypes) {
185232
DataType dataType = dataTypeConverter.convert (info, dataTypes)
186233

@@ -209,12 +256,12 @@ class ApiConverter {
209256
def mediaType = contentEntry.value
210257
def schema = mediaType.schema
211258

212-
def info = new ResponseSchemaInfo (
213-
path,
214-
contentType,
215-
schema,
216-
inlineName)
217-
info.resolver = resolver
259+
def info = new SchemaInfo (
260+
path: path,
261+
contentType: contentType,
262+
name: inlineName,
263+
schema: schema,
264+
resolver: resolver)
218265

219266
DataType dataType = dataTypeConverter.convert (info, dataTypes)
220267

@@ -228,6 +275,17 @@ class ApiConverter {
228275
responses
229276
}
230277

278+
private List<Mapping> findAdditionalParameter (Endpoint ep) {
279+
def addMappings = options.typeMappings.findAll {
280+
it.matches (Mapping.Level.ENDPOINT, new MappingSchemaEndpoint (endpoint: ep))
281+
}.collectMany {
282+
it.childMappings
283+
}.findAll {
284+
it.matches (Mapping.Level.ADD, null as MappingSchema)
285+
}
286+
addMappings
287+
}
288+
231289
private String getInlineRequestBodyName (String path) {
232290
Identifier.toClass (path) + 'RequestBody'
233291
}

src/main/groovy/com/github/hauner/openapi/spring/converter/ApiOptions.groovy

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright 2019 the original authors
2+
* Copyright 2019-2020 the original authors
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -16,7 +16,7 @@
1616

1717
package com.github.hauner.openapi.spring.converter
1818

19-
import com.github.hauner.openapi.spring.converter.mapping.TypeMappingX
19+
import com.github.hauner.openapi.spring.converter.mapping.Mapping
2020

2121
/**
2222
* Options of the generatr.
@@ -50,13 +50,14 @@ class ApiOptions {
5050
* provide additional type mapping information to map OpenAPI types to java types. The list can
5151
* contain the following mappings:
5252
*
53-
* {@link com.github.hauner.openapi.spring.converter.mapping.TypeMapping}: used to globally override
54-
* the mapping of an OpenAPI schema to a specific java type.
53+
* {@link com.github.hauner.openapi.spring.converter.mapping.TypeMapping}: used to globally
54+
* override the mapping of an OpenAPI schema to a specific java type.
5555
*
56-
* {@link com.github.hauner.openapi.spring.converter.mapping.EndpointTypeMapping}: used to override
57-
* parameter, response type mappings or to add additional parameters on a single endpoint.
56+
* {@link com.github.hauner.openapi.spring.converter.mapping.EndpointTypeMapping}: used to
57+
* override parameter/response type mappings or to add additional parameters on a single
58+
* endpoint.
5859
*/
59-
List<TypeMappingX> typeMappings
60+
List<Mapping> typeMappings
6061

6162
/**
6263
* provide enabling Bean Validation (JSR303) annotations. Default is false (disabled)

0 commit comments

Comments
 (0)