001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.http.annotation; 014 015import static java.lang.annotation.ElementType.*; 016import static java.lang.annotation.RetentionPolicy.*; 017 018import java.lang.annotation.*; 019 020import org.apache.juneau.*; 021import org.apache.juneau.annotation.*; 022import org.apache.juneau.httppart.*; 023import org.apache.juneau.json.*; 024import org.apache.juneau.jsonschema.*; 025 026/** 027 * REST request body annotation. 028 * 029 * <p> 030 * Identifies a POJO to be used as the body of an HTTP request. 031 * 032 * <p> 033 * Can be used in the following locations: 034 * <ul> 035 * <li>Arguments and argument-types of server-side <ja>@RestMethod</ja>-annotated methods. 036 * <li>Arguments and argument-types of client-side <ja>@RemoteMethod</ja>-annotated interfaces. 037 * <li>Methods and return types of server-side and client-side <ja>@Request</ja>-annotated interfaces. 038 * </ul> 039 * 040 * <h5 class='topic'>Arguments and argument-types of server-side @RestMethod-annotated methods</h5> 041 * 042 * <p> 043 * On server-side REST, this annotation can be applied to method parameters or parameter classes to identify them as the body of an HTTP request. 044 * 045 * <h5 class='section'>Examples:</h5> 046 * <p class='bcode w800'> 047 * <jc>// Used on parameter</jc> 048 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>) 049 * <jk>public void</jk> addPet(<ja>@Body</ja> Pet pet) {...} 050 * </p> 051 * <p class='bcode w800'> 052 * <jc>// Used on class</jc> 053 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>) 054 * <jk>public void</jk> addPet(Pet pet) {...} 055 * 056 * <ja>@Body</ja> 057 * <jk>public class</jk> Pet {...} 058 * </p> 059 * 060 * <p> 061 * This is functionally equivalent to the following code... 062 * <p class='bcode w800'> 063 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>) 064 * <jk>public void</jk> addPet(RestRequest req) { 065 * Pet pet = req.getBody().asType(Pet.<jk>class</jk>); 066 * ... 067 * } 068 * </p> 069 * 070 * <p> 071 * Also used to populate the auto-generated Swagger documentation. 072 * 073 * <h5 class='section'>Examples:</h5> 074 * <p class='bcode w800'> 075 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>,path=<js>"/pets"</js>) 076 * <jk>public void</jk> addPet(Pet pet) {...} 077 * 078 * <ja>@Body</ja>( 079 * description=<js>"Pet object to add to the store"</js>, 080 * required=<jk>true</jk>, 081 * example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 082 * ) 083 * <jk>public class</jk> Pet {...} 084 * </p> 085 * 086 * <p> 087 * Swagger documentation values are coalesced from multiple sources in the following order of precedence: 088 * <ol> 089 * <li><ja>@Body</ja> annotation on parameter. 090 * <li><ja>@Body</ja> annotation on parameter class. 091 * <li><ja>@Body</ja> annotation on parent classes and interfaces. 092 * <li><ja>@MethodSwagger(value)</ja> annotation. 093 * <li>Localized resource bundle property <js>"[method-name].produces"</js>. 094 * <li><ja>@ResourceSwagger(value)</ja> annotation. 095 * <li>Localized classpath resource file <js>"[enclosing-class].[simple-class-name]_[locale].json"</js> (if it's an inner or member class). 096 * <li>Default classpath resource file <js>"[enclosing-class].[simple-class-name].json"</js> (if it's an inner or member class). 097 * <li>Localized classpath resource file <js>"[simple-class-name]_[locale].json"</js>. 098 * <li>Default classpath resource file <js>"[simple-class-name].json"</js>. 099 * </ol> 100 * 101 * <h5 class='section'>See Also:</h5> 102 * <ul> 103 * <li class='link'>{@doc juneau-rest-server.HttpPartAnnotations.Body} 104 * <li class='link'>{@doc juneau-rest-server.Swagger} 105 * <li class='extlink'>{@doc SwaggerParameterObject} 106 * </ul> 107 * 108 * <h5 class='topic'>Arguments and argument-types of client-side @RemoteResource-annotated interfaces</h5> 109 * 110 * <h5 class='section'>See Also:</h5> 111 * <ul class='doctree'> 112 * <li class='link'>{@doc juneau-rest-client.RestProxies.Body} 113 * </ul> 114 * 115 * <h5 class='topic'>Methods and return types of server-side and client-side @Request-annotated interfaces</h5> 116 * 117 * <h5 class='section'>See Also:</h5> 118 * <ul class='doctree'> 119 * <li class='link'>{@doc juneau-rest-server.HttpPartAnnotations.Request} 120 * <li class='link'>{@doc juneau-rest-client.RestProxies.Request} 121 * </ul> 122 */ 123@Documented 124@Target({PARAMETER,FIELD,METHOD,TYPE}) 125@Retention(RUNTIME) 126@Inherited 127public @interface Body { 128 129 //================================================================================================================= 130 // Attributes common to all Swagger Parameter objects 131 //================================================================================================================= 132 133 /** 134 * <mk>description</mk> field of the {@doc SwaggerParameterObject}. 135 * 136 * <p> 137 * A brief description of the body. This could contain examples of use. 138 * 139 * <h5 class='section'>Examples:</h5> 140 * <p class='bcode w800'> 141 * <jc>// Used on parameter</jc> 142 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 143 * <jk>public void</jk> addPet( 144 * <ja>@Body</ja>(description=<js>"Pet object to add to the store"</js>) Pet input 145 * ) {...} 146 * </p> 147 * <p class='bcode w800'> 148 * <jc>// Used on class</jc> 149 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 150 * <jk>public void</jk> addPet(Pet input) {...} 151 * 152 * <ja>@Body</ja>(description=<js>"Pet object to add to the store"</js>) 153 * <jk>public class</jk> Pet {...} 154 * </p> 155 * 156 * <h5 class='section'>Used for:</h5> 157 * <ul class='spaced-list'> 158 * <li> 159 * Server-side generated Swagger documentation. 160 * </ul> 161 * 162 * <h5 class='section'>Notes:</h5> 163 * <ul class='spaced-list'> 164 * <li> 165 * The format is plain text. 166 * <br>Multiple lines are concatenated with newlines. 167 * <li> 168 * Supports {@doc DefaultRestSvlVariables} 169 * (e.g. <js>"$L{my.localized.variable}"</js>). 170 * </ul> 171 */ 172 String[] description() default {}; 173 174 /** 175 * <mk>required</mk> field of the {@doc SwaggerParameterObject}. 176 * 177 * <p> 178 * Determines whether the body is mandatory. 179 * 180 * <p> 181 * If validation fails during serialization or parsing, the part serializer/parser will throw a {@link SchemaValidationException}. 182 * <br>On the client-side, this gets converted to a <code>RestCallException</code> which is thrown before the connection is made. 183 * <br>On the server-side, this gets converted to a <code>BadRequest</code> (400). 184 * 185 * <h5 class='section'>Examples:</h5> 186 * <p class='bcode w800'> 187 * <jc>// Used on parameter</jc> 188 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 189 * <jk>public void</jk> addPet( 190 * <ja>@Body</ja>(required=<jk>true</jk>) Pet input 191 * ) {...} 192 * </p> 193 * <p class='bcode w800'> 194 * <jc>// Used on class</jc> 195 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 196 * <jk>public void</jk> addPet(Pet input) {...} 197 * 198 * <ja>@Body</ja>(required=<jk>true</jk>) 199 * <jk>public class</jk> Pet {...} 200 * </p> 201 * 202 * <h5 class='section'>Used for:</h5> 203 * <ul class='spaced-list'> 204 * <li> 205 * Server-side schema-based parsing validation. 206 * <li> 207 * Server-side generated Swagger documentation. 208 * <li> 209 * Client-side schema-based serializing validation. 210 * </ul> 211 * 212 * <h5 class='section'>Notes:</h5> 213 * <ul class='spaced-list'> 214 * <li> 215 * Supports {@doc DefaultRestSvlVariables} 216 * (e.g. <js>"$L{my.localized.variable}"</js>). 217 * </ul> 218 */ 219 boolean required() default false; 220 221 //================================================================================================================= 222 // Attributes specific to in=body 223 //================================================================================================================= 224 225 /** 226 * <mk>schema</mk> field of the {@doc SwaggerParameterObject}. 227 * 228 * <p> 229 * The schema defining the type used for the body parameter. 230 * 231 * <p> 232 * This is a required attribute per the swagger definition. 233 * However, if not explicitly specified, the value will be auto-generated using {@link JsonSchemaSerializer}. 234 * 235 * <h5 class='section'>Used for:</h5> 236 * <ul class='spaced-list'> 237 * <li> 238 * Server-side schema-based parsing and parsing validation. 239 * <li> 240 * Server-side generated Swagger documentation. 241 * <li> 242 * Client-side schema-based serializing and serializing validation. 243 * </ul> 244 * 245 * <h5 class='section'>Notes:</h5> 246 * <ul class='spaced-list'> 247 * <li> 248 * Supports {@doc DefaultRestSvlVariables} 249 * (e.g. <js>"$L{my.localized.variable}"</js>). 250 * </ul> 251 */ 252 Schema schema() default @Schema; 253 254 //================================================================================================================= 255 // Other 256 //================================================================================================================= 257 258 /** 259 * A serialized example of the body of a request. 260 * 261 * <p> 262 * This is the {@doc juneau-marshall.JsonDetails.SimplifiedJson} of an example of the body. 263 * 264 * <p> 265 * This value is converted to a POJO and then serialized to all the registered serializers on the REST method to produce examples for all 266 * supported language types. 267 * <br>These values are then used to automatically populate the {@link #examples} field. 268 * 269 * <h5 class='section'>Example:</h5> 270 * <p class='bcode w800'> 271 * <jc>// A JSON representation of a PetCreate object.</jc> 272 * <ja>@Body</ja>( 273 * example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 274 * ) 275 * </p> 276 * <p> 277 * <img class='bordered' src='doc-files/Body_Example.png' style='width:860px'> 278 * 279 * <p> 280 * There are several other options for defining this example: 281 * <ul class='spaced-list'> 282 * <li> 283 * Defining an <js>"x-example"</js> field in the inherited Swagger JSON body field (classpath file or <code><ja>@ResourceSwagger</ja>(value)</code>/<code><ja>@MethodSwagger</ja>(value)</code>). 284 * <li> 285 * Defining an <js>"x-example"</js> field in the Swagger Schema Object for the body (including referenced <js>"$ref"</js> schemas). 286 * <li> 287 * Allowing Juneau to auto-generate a code example. 288 * </ul> 289 * 290 * <p> 291 * The latter is important because Juneau also supports auto-generation of JSON-Schema from POJO classes using {@link JsonSchemaSerializer} which has several of it's own 292 * options for auto-detecting and calculation POJO examples. 293 * 294 * <p> 295 * In particular, examples can be defined via static methods, fields, and annotations on the classes themselves. 296 * 297 * <p class='bcode w800'> 298 * <jc>// Annotation on class.</jc> 299 * <ja>@Example</ja>(<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js>) 300 * <jk>public class</jk> PetCreate { 301 * ... 302 * } 303 * </p> 304 * <p class='bcode w800'> 305 * <jc>// Annotation on static method.</jc> 306 * <jk>public class</jk> PetCreate { 307 * 308 * <ja>@Example</ja> 309 * <jk>public static</jk> PetCreate <jsm>sample</jsm>() { 310 * <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>}); 311 * } 312 * } 313 * </p> 314 * <p class='bcode w800'> 315 * <jc>// Static method with specific name 'example'.</jc> 316 * <jk>public class</jk> PetCreate { 317 * 318 * <jk>public static</jk> PetCreate <jsm>example</jsm>() { 319 * <jk>return new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>}); 320 * } 321 * } 322 * </p> 323 * <p class='bcode w800'> 324 * <jc>// Static field.</jc> 325 * <jk>public class</jk> PetCreate { 326 * 327 * <ja>@Example</ja> 328 * <jk>public static</jk> PetCreate <jsf>EXAMPLE</jsf> = <jk>new</jk> PetCreate(<js>"Doggie"</js>, 9.99f, <js>"Dog"</js>, <jk>new</jk> String[] {<js>"friendly"</js>,<js>"cute"</js>}); 329 * } 330 * </p> 331 * 332 * <p> 333 * Examples can also be specified via generic properties as well using the {@link BeanContext#BEAN_examples} property at either the class or method level. 334 * <p class='bcode w800'> 335 * <jc>// Examples defined at class level.</jc> 336 * <ja>@RestResource</ja>( 337 * properties={ 338 * <ja>@Property</ja>( 339 * name=<jsf>BEAN_examples</jsf>, 340 * value=<js>"{'org.apache.juneau.examples.rest.petstore.PetCreate': {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}}"</js> 341 * ) 342 * } 343 * ) 344 * </p> 345 * 346 * <h5 class='section'>Used for:</h5> 347 * <ul class='spaced-list'> 348 * <li> 349 * Server-side generated Swagger documentation. 350 * </ul> 351 * 352 * <h5 class='section'>See also:</h5> 353 * <ul> 354 * <li class='ja'>{@link Example} 355 * <li class='jc'>{@link BeanContext} 356 * <ul> 357 * <li class='jf'>{@link BeanContext#BEAN_examples BEAN_examples} 358 * </ul> 359 * <li class='jc'>{@link JsonSchemaSerializer} 360 * <ul> 361 * <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_addExamplesTo JSONSCHEMA_addExamplesTo} 362 * <li class='jf'>{@link JsonSchemaGenerator#JSONSCHEMA_allowNestedExamples JSONSCHEMA_allowNestedExamples} 363 * </ul> 364 * </ul> 365 * 366 * <h5 class='section'>Notes:</h5> 367 * <ul class='spaced-list'> 368 * <li> 369 * The format is any {@doc juneau-marshall.JsonDetails.SimplifiedJson} if the object can be converted to a POJO using {@link JsonParser#DEFAULT} or a simple String if the object 370 * has a schema associated with it meancan be converted from a String. 371 * <br>Multiple lines are concatenated with newlines. 372 * <li> 373 * The format of this object can also be a simple String if the body has a schema associated with it, meaning it's meant to be treated as an HTTP part. 374 * <li> 375 * Supports {@doc DefaultRestSvlVariables} 376 * (e.g. <js>"$L{my.localized.variable}"</js>). 377 * </ul> 378 */ 379 String[] example() default {}; 380 381 /** 382 * Serialized examples of the body of a request. 383 * 384 * <p> 385 * This is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object whose keys are media types and values are string representations of that value. 386 * 387 * <p> 388 * In general you won't need to populate this value directly since it will automatically be calculated based on the value provided in the {@link #example()} field. 389 * <br>However, this field allows you to override the behavior and show examples for only specified media types or different examples for different media types. 390 * 391 * <p class='bcode w800'> 392 * <jc>// A JSON representation of a PetCreate object.</jc> 393 * <ja>@Body</ja>( 394 * examples={ 395 * <js>"'application/json':'{name:\\'Doggie\\',species:\\'Dog\\'}',"</js>, 396 * <js>"'text/uon':'(name:Doggie,species=Dog)'"</js> 397 * } 398 * ) 399 * </p> 400 * 401 * <h5 class='section'>Used for:</h5> 402 * <ul class='spaced-list'> 403 * <li> 404 * Server-side generated Swagger documentation. 405 * </ul> 406 * 407 * <h5 class='section'>Notes:</h5> 408 * <ul class='spaced-list'> 409 * <li> 410 * The format is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object with string keys (media type) and string values (example for that media type) . 411 * <li> 412 * The leading/trailing <code>{ }</code> characters are optional. 413 * <li> 414 * Multiple lines are concatenated with newlines so that you can format the value to be readable: 415 * <li> 416 * Supports {@doc DefaultRestSvlVariables} 417 * (e.g. <js>"$L{my.localized.variable}"</js>). 418 * <li> 419 * Resolution of variables is delayed until request time and occurs before parsing. 420 * <br>This allows you to, for example, pull in a JSON construct from a properties file based on the locale of the HTTP request. 421 * </ul> 422 */ 423 String[] examples() default {}; 424 425 /** 426 * Free-form value for the {@doc SwaggerParameterObject}. 427 * 428 * <p> 429 * This is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object that makes up the swagger information for this parameter-info. 430 * 431 * <p> 432 * The following are completely equivalent ways of defining the swagger description of the body: 433 * <p class='bcode w800'> 434 * <jc>// Normal</jc> 435 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 436 * <jk>public void</jk> addPet( 437 * <ja>@Body</ja>( 438 * description=<js>"Pet object to add to the store"</js>, 439 * required=<jk>true</jk>, 440 * example=<js>"{name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 441 * ) Pet input 442 * ) {...} 443 * </p> 444 * <p class='bcode w800'> 445 * <jc>// Free-form</jc> 446 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 447 * <jk>public void</jk> addPet( 448 * <ja>@Body</ja>({ 449 * <js>"description: 'Pet object to add to the store',"</js>, 450 * <js>"required: true,"</js>, 451 * <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 452 * }) Pet input 453 * ) {...} 454 * </p> 455 * <p class='bcode w800'> 456 * <jc>// Free-form with variables</jc> 457 * <ja>@RestMethod</ja>(name=<jsf>POST</jsf>) 458 * <jk>public void</jk> addPet( 459 * <ja>@Body</ja>(<js>"$L{petObjectSwagger}"</js>) Pet input 460 * ) {...} 461 * </p> 462 * <p class='bcode w800'> 463 * <mc>// Contents of MyResource.properties</mc> 464 * <mk>petObjectSwagger</mk> = <mv>{ description: "Pet object to add to the store", required: true, example: {name:"Doggie",price:9.99,species:"Dog",tags:["friendly","cute"]} }</mv> 465 * </p> 466 * 467 * <p> 468 * The reasons why you may want to use this field include: 469 * <ul> 470 * <li>You want to pull in the entire Swagger JSON definition for this body from an external source such as a properties file. 471 * <li>You want to add extra fields to the Swagger documentation that are not officially part of the Swagger specification. 472 * </ul> 473 * 474 * <h5 class='section'>Used for:</h5> 475 * <ul class='spaced-list'> 476 * <li> 477 * Server-side generated Swagger documentation. 478 * </ul> 479 * 480 * <h5 class='section'>Notes:</h5> 481 * <ul class='spaced-list'> 482 * <li> 483 * The format is a {@doc juneau-marshall.JsonDetails.SimplifiedJson} object. 484 * <li> 485 * Schema-based serialization is NOT affected by values defined in this annotation. 486 * <br>It only affects the generated Swagger documentation. 487 * <li> 488 * The leading/trailing <code>{ }</code> characters are optional. 489 * <br>The following two example are considered equivalent: 490 * <p class='bcode w800'> 491 * <ja>@Body</ja>(<js>"{description: 'Pet object to add to the store'}"</js>) 492 * </p> 493 * <p class='bcode w800'> 494 * <ja>@Body</ja>(<js>"description: 'Pet object to add to the store'"</js>) 495 * </p> 496 * <li> 497 * Multiple lines are concatenated with newlines so that you can format the value to be readable. 498 * <li> 499 * Supports {@doc DefaultRestSvlVariables} 500 * (e.g. <js>"$L{my.localized.variable}"</js>). 501 * <li> 502 * Values defined in this field supersede values pulled from the Swagger JSON file and are superseded by individual values defined on this annotation. 503 * </ul> 504 */ 505 String[] value() default {}; 506 507 /** 508 * Equivalent to {@link #value()}. 509 * 510 * <p> 511 * The following are entirely equivalent: 512 * 513 * <p class='bcode w800'> 514 * <ja>@Body</ja>({ 515 * <js>"description: 'Pet object to add to the store',"</js>, 516 * <js>"required: true,"</js>, 517 * <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 518 * }) 519 * </p> 520 * <p class='bcode w800'> 521 * <ja>@Body</ja>(api={ 522 * <js>"description: 'Pet object to add to the store',"</js>, 523 * <js>"required: true,"</js>, 524 * <js>"example: {name:'Doggie',price:9.99,species:'Dog',tags:['friendly','cute']}"</js> 525 * }) 526 * </p> 527 * 528 * <h5 class='section'>Used for:</h5> 529 * <ul class='spaced-list'> 530 * <li> 531 * Server-side generated Swagger documentation. 532 * </ul> 533 * 534 * <h5 class='section'>Notes:</h5> 535 * <ul class='spaced-list'> 536 * <li> 537 * If you specify both {@link #value()} and {@link #api()}, {@link #value()} will be ignored. 538 * </ul> 539 */ 540 String[] api() default {}; 541}