blob: 061fd0c317a576cfc647ec52086c38a4a3c2d783 [file] [log] [blame]
<!--
/***************************************************************************************************************************
* Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
***************************************************************************************************************************/
-->
OpenAPI Methodology
<p>
Unlike the other Juneau serializers and parsers that convert input and output directly to-and-from POJOs,
the OpenAPI serializers and parsers use intermediate objects based on the <c>type</c> and <c>format</c>
of the schema.
</p>
<p>
The following table shows the "natural" intermediate type of the object based on the <c>type/format</c>:
</p>
<table class='styled w800'>
<tr><th>Type</th><th>Format</th><th>Intermediate Java Type</th></tr>
<tr class='dark bb'>
<td rowspan='4'><c>string</c> or empty</td>
<td><c>byte<br>binary<br>binary-spaced</c></td>
<td><c><jk>byte</jk>[]</c></td>
</tr>
<tr class='dark bb'>
<td><c>date<br>date-time</c></td>
<td>{@link java.util.Calendar}</td>
</tr>
<tr class='dark bb'>
<td><c>uon</c></td>
<td>No intermediate type.<br>(serialized directly to/from POJO)</td>
</tr>
<tr class='dark bb'>
<td>empty</td>
<td>{@link java.lang.String}</td>
</tr>
<tr class='light bb'>
<td rowspan='1'><c>boolean</c></td>
<td>empty</td>
<td>{@link java.lang.Boolean}</td>
</tr>
<tr class='dark bb'>
<td rowspan='2'><c>integer</c></td>
<td><c>int32</c></td>
<td>{@link java.lang.Integer}</td>
</tr>
<tr class='dark bb'>
<td><c>int64</c></td>
<td>{@link java.lang.Long}</td>
</tr>
<tr class='light bb'>
<td rowspan='2'><c>number</c></td>
<td><c>float</c></td>
<td>{@link java.lang.Float}</td>
</tr>
<tr class='light bb'>
<td><c>double</c></td>
<td>{@link java.lang.Double}</td>
</tr>
<tr class='dark bb'>
<td rowspan='2'><c>array</c></td>
<td>empty</td>
<td>Arrays of intermediate types on this list.</td>
</tr>
<tr class='dark bb'>
<td><c>uon</c></td>
<td>No intermediate type.<br>(serialized directly to/from POJO)</td>
</tr>
<tr class='light bb'>
<td rowspan='2'><c>object</c></td>
<td>empty</td>
<td><c>Map&lt;String,Object&gt;</c></td>
</tr>
<tr class='light bb'>
<td><c>uon</c></td>
<td>No intermediate type.<br>(serialized directly to/from POJO)</td>
</tr>
</table>
<p>
The valid POJO types for serializing/parsing are based on the intermediate types above.
As a general rule, any POJOs that are the intermediate type or transformable to or from
the intermediate type are valid POJO types.
</p>
<p>
For example, the following POJO type can be transformed to and from a byte array.
</p>
<p class='bpcode w800'>
<jc>// Sample POJO class convertable to and from a byte[].</jc>
<jk>public class</jk> MyPojo {
<jc>// Constructor used by parser.</jc>
<jk>public</jk> MyPojo(<jk>byte</jk>[] fromBytes) {...}
<jc>// toX method used by serializer.</jc>
<jk>public byte</jk>[] toBytes() {...}
}
</p>
<p>
This example shows how that POJO can be converted to a BASE64-encoded string.
</p>
<p class='bpcode w800'>
<jc>// Construct a POJO.</jc>
MyPojo myPojo = ...;
<jc>// Define a schema.</jc>
HttpPartSchema schema = HttpPartSchema.<jsm>create</jsm>().type(<js>"string"</js>).format(<js>"byte"</js>).build();
<jc>// Convert POJO to BASE64-encoded string.</jc>
HttpPartSerializer s = OpenApiSerializer.<jsf>DEFAULT</jsf>;
String httpPart = s.serialize(schema, myPojo);
<jc>// Convert BASE64-encoded string back into a POJO.</jc>
HttpPartParser p = OpenApiParser.<jsf>DEFAULT</jsf>;
myPojo = p.parse(schema, httpPart, MyPojo.<jk>class</jk>);
</p>
<p>
In addition to defining format, the schema also allows for validations of the serialized form.
</p>
<p class='bpcode w800'>
<jc>// Construct a POJO.</jc>
MyPojo myPojo = ...;
<jc>// Define a schema.</jc>
<jc>// Serialized string must be no smaller than 100 characters.</jc>
HttpPartSchema schema = HttpPartSchema.<jsm>create</jsm>().type(<js>"string"</js>).format(<js>"byte"</js>).minLength(100).build();
<jc>// Convert POJO to BASE64-encoded string.</jc>
HttpPartSerializer s = OpenApiSerializer.<jsf>DEFAULT</jsf>;
String httpPart;
<jk>try</jk> {
httpPart = s.serialize(schema, myPojo);
} <jk>catch</jk> (SchemaValidationException e) {
<jc>// Oops, output too small.</jc>
}
<jc>// Convert BASE64-encoded string back into a POJO.</jc>
HttpPartParser p = OpenApiParser.<jsf>DEFAULT</jsf>;
<jk>try</jk> {
myPojo = p.parse(schema, httpPart, MyPojo.<jk>class</jk>);
} <jk>catch</jk> (SchemaValidationException e) {
<jc>// Oops, input too small.</jc>
}
</p>
<p>
It looks simple, but the implementation is highly sophisticated being able to serialize and parse and validate using complex schemas.
</p>
<p>
The next sections go more into depth on serializing and parsing various POJO types.
</p>