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