Skip to content

Commit 41894c9

Browse files
committed
Describe the mapping between Aspects and the OpenAPI specification.
1 parent c82e045 commit 41894c9

File tree

1 file changed

+208
-0
lines changed
  • documentation/developer-guide/modules/tooling-guide/pages

1 file changed

+208
-0
lines changed

documentation/developer-guide/modules/tooling-guide/pages/bamm-cli.adoc

Lines changed: 208 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,214 @@ The full command would result in:
140140
java -jar bamm-cli-{sds-sdk-version}.jar aspect _AspectModel.ttl_ to openapi -b "https://www.example.org" -r "/resources/\{resourceId}" -p _fileLocation_
141141
----
142142

143+
=== Mapping between the Aspect models and the OpenAPI Specification
144+
145+
In this section, a detailed description of the mapping between individual Aspect elements and the OpenAPI specification is given.
146+
To make it easier to follow, the mapping is explained based on a concrete example, divided into logically coherent blocks. Please bear in mind
147+
that these blocks are snippets or fragments of a larger whole; viewed in isolation they do not necessarily form a valid or meaningful aspect model or OpenAPI specification.
148+
149+
==== Naming and versioning
150+
151+
Please consider the following model fragment, with the attention focused on the numbered elements:
152+
153+
----
154+
@prefix bamm: <urn:bamm:io.openmanufacturing:meta-model:2.0.0#>.
155+
@prefix : <urn:bamm:test:2.0.0#>. <1>
156+
157+
:Test a bamm:Aspect;
158+
bamm:name "Test"; <3>
159+
bamm:preferredName "TestAspect"@en ; <2>
160+
bamm:preferredName "TestAspekt"@de .
161+
----
162+
<1> full URN of :Test Aspect
163+
<2> the preferred name of the Aspect in language of user's choice
164+
<3> the name of the Aspect
165+
166+
For the generated OpenAPI Specification, the following mapping would apply:
167+
168+
[source,JSON]
169+
----
170+
{
171+
"openapi" : "3.0.3",
172+
"info" : {
173+
"title" : "TestAspect", // <2> <3>
174+
"version" : "v2" // <1>
175+
}
176+
}
177+
----
178+
<1> depending on parameters used when generating the specification, this is either the major version of the full Aspect URN (*2*.0.0),
179+
or it can be the full version (`v2.0.0`), if using `-sv` (semantic version) command line switch
180+
<2> if present, `bamm:preferredName` is used as the value for the `title` element of the specification
181+
<3> as `bamm:preferredName` is an optional element, in cases when it is missing the value of `bamm:name` is used instead
182+
183+
The version information as described above is also used in the url definitions of the `servers` block of the specification:
184+
185+
[source,JSON]
186+
----
187+
{
188+
"servers" : [ {
189+
"url" : "http://mysite/api/v2", // <1>
190+
"variables" : {
191+
"api-version" : {
192+
"default" : "v2" // <1>
193+
}
194+
}
195+
} ]
196+
}
197+
----
198+
199+
The name of the Aspect is used to generate several important OpenAPI artifacts, like the path definitions for the API:
200+
201+
[source,JSON]
202+
----
203+
{
204+
"paths" : {
205+
"/{tenant-id}/test" : { // <3>
206+
"get" : {
207+
"tags" : [ "Test" ], // <3>
208+
"operationId" : "getTest" // <3>
209+
}
210+
}
211+
}
212+
}
213+
----
214+
215+
and the definitions for request bodies and responses in the corresponding blocks (`requestBodies` and `responses`) of the OpenAPI specification (example omitted for simplicity).
216+
217+
==== Mapping of Aspect and its properties
218+
219+
For each Aspect in the model, an entry in the `components/schemas` part of the OpenAPI specification is generated.
220+
For an example Aspect from the following fragment:
221+
222+
----
223+
:Test a bamm:Aspect; <1>
224+
bamm:properties (
225+
:prop1 <2>
226+
[ bamm:property :prop2; bamm:payloadName "givenName"; ] <3>
227+
[ bamm:property :prop3; bamm:optional true; ] ). <4>
228+
229+
:prop1 a bamm:Property;
230+
bamm:name "property1";
231+
bamm:description "Description of Property1"@en; <5>
232+
bamm:characteristic :Enum. <6>
233+
----
234+
235+
an entry like the one given in the following JSON will be generated:
236+
237+
[source,JSON]
238+
----
239+
"Test" : { // <1>
240+
"type" : "object",
241+
"properties" : {
242+
"prop1" : { // <2>
243+
"description" : "Description of Property1", // <5>
244+
"$ref" : "#/components/schemas/urn_bamm_test_2.0.0_Enum" // <6>
245+
},
246+
"givenName" : { // <3>
247+
"$ref" : "#/components/schemas/urn_bamm_test_2.0.0_EntityChar"
248+
},
249+
"prop3" : { // <4>
250+
"$ref" : "#/components/schemas/urn_bamm_test_2.0.0_StringCharacteristic"
251+
}
252+
},
253+
"required" : [ "prop1", "givenName" ] // <2> <3>
254+
}
255+
----
256+
<1> the name of the Aspect is used to name the schema object for the aspect
257+
<2> with plain property references, the name of the property is used to name the property definition
258+
<3> in cases where a payload name is defined on a specific property, it is used in preference to the plain property name
259+
<4> if the property use is also defined as optional, the property will not be included in the list of the required properties
260+
<5> the values of `bamm:description` elements in property definitions are included in the generated JSON
261+
<6> for each of the properties characteristics an entry in `components/schemas` is generated and referenced here; if the characteristic is of complex type,
262+
the whole procedure is applied recursively to the complex type's properties
263+
264+
265+
==== Mapping of Aspect's operations
266+
267+
If the Aspect also has a non-empty list of operations defined, like the one in the following example:
268+
269+
----
270+
:AspectWithOperation a bamm:Aspect ;
271+
bamm:properties ( ) ;
272+
bamm:operations ( :testOperation ) .
273+
274+
:testOperation a bamm:Operation ;
275+
bamm:input ( :input ) ; <1>
276+
bamm:output :output . <2>
277+
278+
:output a bamm:Property ;
279+
bamm:characteristic bamm-c:Text . <3>
280+
281+
:input a bamm:Property ;
282+
bamm:characteristic bamm-c:Text . <4>
283+
----
284+
285+
then additional entries are added to the generated OpenAPI specification.
286+
First, there is an additional entry in the `paths` section of the specification: `/{tenant-id}/aspect-with-operation/*operations*`.
287+
The available operations are then added to the `components/schemas` part:
288+
289+
[source,JSON]
290+
----
291+
{
292+
"Operation" : {
293+
"allOf" : [ {
294+
"$ref" : "#/components/schemas/JsonRpc"
295+
}, {
296+
"properties" : {
297+
"params" : {
298+
"type" : "object",
299+
"required" : [ "input" ], // <1>
300+
"properties" : {
301+
"input" : { // <1>
302+
"$ref" : "#/components/schemas/urn_bamm_io.openmanufacturing_characteristic_2.0.0_Text" // <3>
303+
}
304+
}
305+
},
306+
"method" : {
307+
"type" : "string",
308+
"description" : "The method name",
309+
"example" : "testOperation"
310+
}
311+
}
312+
} ]
313+
},
314+
"OperationResponse" : {
315+
"allOf" : [ {
316+
"$ref" : "#/components/schemas/JsonRpc"
317+
}, {
318+
"properties" : {
319+
"result" : {
320+
"type" : "object",
321+
"required" : [ "output" ], // <2>
322+
"properties" : {
323+
"output" : { // <2>
324+
"$ref" : "#/components/schemas/urn_bamm_io.openmanufacturing_characteristic_2.0.0_Text" // <4>
325+
}
326+
}
327+
}
328+
}
329+
} ]
330+
}
331+
}
332+
----
333+
<1> the names of the input
334+
<2> and output parameters are reflected in the properties generated for the request/response objects
335+
<3> the characteristics are generated
336+
<4> and referenced as described in the point 6 of the section "Mapping of Aspect and its properties"
337+
338+
As usual, corresponding entries referencing the definitions above are added to the `requestBodies` and `responses` sections (examples omitted for simplicity).
339+
For technical reasons, there may be a slight variation in the generated JSON depending on whether the aspect has one or more operations defined.
340+
341+
==== Mapping of Collections
342+
343+
There are some additional JSON entries generated for complex types related to various types of collections to facilitate
344+
access to the individual elements of these collections via paging. As these entries are rather of static character
345+
without direct references to any aspect elements, it suffices here to give a short overview about which kind of paging
346+
is available for which type of collection:
347+
348+
* a general Collection - cursor and/or offset based paging
349+
* TimeSeries - cursor, offset and/or time based paging
350+
143351
[[models-directory-structure]]
144352
== Understanding the models directory structure
145353

0 commit comments

Comments
 (0)