Skip to content

Commit 52258a5

Browse files
committed
1 parent 6687d7b commit 52258a5

File tree

3 files changed

+247
-0
lines changed

3 files changed

+247
-0
lines changed

docs/modules/ROOT/pages/processor/configuration.adoc

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ openapi-processor-mapping: {var-mapping-version}
1313
1414
options:
1515
package-name: io.openapiprocessor.sample
16+
package-name-from-path: true
1617
model-name-suffix: Resource
1718
model-type: record
1819
enum-type: string
@@ -66,6 +67,31 @@ options:
6667
package-name: io.openapiprocessor.sample
6768
----
6869

70+
=== package-name-from-path (new with 2025.3)
71+
72+
**optional** (boolean, `true` or `false`, default is `false`)
73+
74+
`package-name-from-path` enables the creation of package names based on the file location of $ref'erenced parts of the OpenAPI description.
75+
76+
Enabling this has a few requirements:
77+
78+
- `package-name` must match a specific *parent* package name of the *target* package in the production code:
79+
+
80+
The *parent* package is shorter than the *target* package, and the *target* package starts with the *parent* package.
81+
+
82+
This is hard to explain in a few words. See the link below for an example.
83+
84+
- to create an interface or resource in a specific package, its OpenAPI description has to be in the target package and must be reachable from the root OpenAPI description.
85+
86+
- it only works with the `INTERNAL` OpenAPI parser (it is the default parser). It will not work with the `SWAGGER` OpenAPI parser.
87+
88+
See xref:processor/package-names.adoc[package-names] for a description with an example. It explains which package is the *parent* package and how to place OpenAPI parts into packages.
89+
90+
[WARNING]
91+
====
92+
This is still a bit experimental and may not behave nicely if the expected configuration requirements are not met.
93+
====
94+
6995
=== model-name-suffix
7096

7197
**optional** (string, default is empty (i.e., it is disabled))
Lines changed: 220 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,220 @@
1+
include::partial$links.adoc[]
2+
include::partial$vars.adoc[]
3+
4+
= package-names
5+
6+
[WARNING]
7+
====
8+
This is still a bit experimental and may not behave nicely if the expected configuration requirements are not met.
9+
10+
It also works *only* with the `INTERNAL` OpenAPI parser, which is the default OpenAPI parser.
11+
====
12+
13+
== package-names-from-path
14+
15+
The `package-name-from-path` option enables the creation of package names based on the file location of $ref'erenced parts of the OpenAPI description.
16+
17+
Enabling this has a few requirements:
18+
19+
- `package-name` must match a specific *parent* package name of the target package in the production code.
20+
+
21+
The *parent* package should be shorter than the *target* package, and the *target* package should start with the *parent* package.
22+
+
23+
See the example below.
24+
25+
- to create an interface or resource with a specific package, its OpenAPI description has to be in the *target* package and must be reachable from the root OpenAPI description.
26+
27+
- it is only supported with the `INTERNAL` OpenAPI parser (it is the default parser). It will not work with the `SWAGGER` OpenAPI parser.
28+
29+
=== mapping.yaml
30+
31+
The first step is to enable the feature in the `mapping.yaml`:
32+
33+
[source,yaml,subs="attributes",title="mapping.yaml"]
34+
----
35+
openapi-processor-mapping: {var-mapping-version}
36+
37+
options:
38+
# this must be a parent package of the target packages
39+
package-name: io.openapiprocessor.samples # <2>
40+
41+
# this enables package generation from the endpoint $ref file location
42+
package-name-from-path: true # <1>
43+
----
44+
45+
<1> this enables the package-name feature. Default is `false`.
46+
<2> the `package-name`, this *must* be a *parent* package name of the project's *target* packages.
47+
48+
=== OpenAPI and $refs
49+
50+
The second step is to split the OpenAPI definition into multiple files and place them into the desired packages.
51+
52+
The `openapi.yaml` is placed into the usual place, in this example in the source folder `src/api`.
53+
54+
[source,yaml,subs="attributes",title="openapi.yaml"]
55+
----
56+
openapi: {var-openapi-version}
57+
info:
58+
title: openapi-processor-spring sample api
59+
version: 1.0.0
60+
61+
servers:
62+
- url: "https://openapiprocessor.io/{path}"
63+
variables:
64+
path:
65+
default: api
66+
67+
paths:
68+
/foo:
69+
$ref: '../main/kotlin/io/openapiprocessor/samples/foo/foo.yaml' # <1>
70+
----
71+
72+
73+
The project directories so far look like this, where `sample` is the root folder of the project.
74+
75+
[title="directory structure, api"]
76+
----
77+
sample
78+
\---- src
79+
\---- api
80+
+---- mapping.yaml
81+
\---- openapi.yaml
82+
----
83+
84+
=== foo endpoint $ref
85+
86+
The `foo` path item in `openapi.yaml` $ref'erences the endpoint definition in `foo.yaml`.
87+
88+
[source,yaml,subs="attributes",title="foo.yaml"]
89+
----
90+
post:
91+
tags:
92+
- foo
93+
summary: echo a Foo.
94+
description: simple sample endpoint
95+
requestBody:
96+
$ref: 'resources.yaml#/FooBody'
97+
responses:
98+
'200':
99+
description: foo
100+
content:
101+
application/json:
102+
schema:
103+
$ref: 'resources.yaml#/Foo'
104+
----
105+
106+
`foo.yaml` is placed into the main source folder of the project into the *target* package the generated interface should have.
107+
108+
In this case the *target* package of `FooApi.java` will be `io.openapiprocessor.samples.foo`
109+
110+
The controller implementation and services for this endpoint will go into the same package.
111+
112+
`foo.yaml` also $ref'erences a `resources.yaml` file placed in the same package that defines the `Foo` payload schema:
113+
114+
[source,yaml,subs="attributes",title="resources.yaml"]
115+
----
116+
FooBody:
117+
content:
118+
application/json:
119+
schema:
120+
$ref: '#/Foo'
121+
122+
Foo:
123+
type: object
124+
description: Foo object description
125+
properties:
126+
foo:
127+
type: string
128+
maxLength: 10
129+
description: foo property description
130+
id:
131+
type: string
132+
format: uuid
133+
description: id property description
134+
----
135+
136+
The final directory structure then looks like this:
137+
138+
[title="directory structure, api and sources"]
139+
----
140+
sample
141+
\---- src
142+
+---- api
143+
| +---- mapping.yaml
144+
| \---- openapi.yaml
145+
\---- main
146+
+---- kotlin
147+
| \---- io
148+
| \---- openapiprocessor
149+
| \---- samples
150+
| +---- foo
151+
| | +---- FooController.kt
152+
| | +---- foo.yaml
153+
| | \---- resources.yaml
154+
| +---- bar
155+
| | \---- ...
156+
| \ Application.kt
157+
\---- resources
158+
\---- application.properties
159+
----
160+
161+
=== parent package name
162+
163+
Having an idea now how the files are organized, it is possible to explain which package is the *parent* package.
164+
165+
From the file tree above:
166+
167+
The package name of the `foo` endpoint files is `io.openapiprocessor.samples.foo` and the nearest *parent* package is `io.openapiprocessor.samples`. This is then the `package-name` option value.
168+
169+
It is possible to use `io.openapiprocessor` or even `io` as the *parent* package.
170+
171+
Important is that the *parent* package is shorter than the *target* package and that the *target* package starts with the *parent* package.
172+
173+
=== directory structure after processing
174+
175+
Assuming a Gradle build, the directory structure after processing is:
176+
177+
----
178+
sample
179+
+---- build
180+
| \---- openapi
181+
| +--- java
182+
| | \---- io
183+
| | \---- openapiprocessor
184+
| | \---- samples
185+
| | +---- foo
186+
| | | +---- Foo.java
187+
| | | \---- FooApi.java
188+
| | \---- bar
189+
| | \---- ...
190+
| \---- resources
191+
| \---- api.properties
192+
\---- src
193+
+---- api
194+
| +---- mapping.yaml
195+
| \---- openapi.yaml
196+
\---- main
197+
+---- kotlin
198+
| +---- io
199+
| | \---- openapiprocessor
200+
| | \---- samples
201+
| | +---- foo
202+
| | | +---- FooController.kt
203+
| | | +---- foo.yaml
204+
| | | \---- resources.yaml
205+
| | \---- bar
206+
| | \---- ...
207+
\---- resources
208+
\---- application.properties
209+
----
210+
211+
212+
=== sample code
213+
214+
A full working example with multiple endpoints is available in the link:{oap-sample-packages}[samples] repository.
215+
216+
217+
218+
219+
220+

docs/modules/ROOT/partials/links.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
:oapc-inttests: https://github.com/openapi-processor/openapi-processor-core/tree/master/src/testInt/resources/tests
1818
:json-schema: https://github.com/openapi-processor/openapi-processor-core/blob/master/src/main/resources/mapping/v2/mapping.yaml.json
1919
:json-schema-site: https://openapiprocessor.io/schemas/mapping/mapping-{var-mapping-version}.json
20+
:oap-sample-packages: https://github.com/openapi-processor/openapi-processor-samples/tree/master/samples/spring-mvc-boot-4-packages-kt
2021

2122
//
2223
// other external links

0 commit comments

Comments
 (0)