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.rest.annotation; 014 015import static java.lang.annotation.ElementType.*; 016import static java.lang.annotation.RetentionPolicy.*; 017 018import java.lang.annotation.*; 019import java.nio.charset.*; 020 021import org.apache.juneau.*; 022import org.apache.juneau.annotation.*; 023import org.apache.juneau.rest.*; 024import org.apache.juneau.rest.converter.*; 025import org.apache.juneau.rest.guard.*; 026import org.apache.juneau.rest.httppart.*; 027import org.apache.juneau.rest.matcher.*; 028import org.apache.juneau.rest.servlet.*; 029import org.apache.juneau.rest.swagger.*; 030import org.apache.juneau.serializer.*; 031import org.apache.juneau.dto.swagger.*; 032import org.apache.juneau.encoders.*; 033 034/** 035 * Identifies a REST GET operation Java method on a {@link RestServlet} implementation class. 036 * 037 * <p> 038 * This is a specialized subtype of <c><ja>{@link RestOp @RestOp}(method=<jsf>GET</jsf>)</c>. 039 * 040 * <h5 class='section'>See Also:</h5><ul> 041 * <li class='link'><a class="doclink" href="../../../../../index.html#jrs.RestOpAnnotatedMethods">@RestOp-Annotated Methods</a> 042 043 * </ul> 044 */ 045@Target(METHOD) 046@Retention(RUNTIME) 047@Inherited 048@ContextApply(RestGetAnnotation.RestOpContextApply.class) 049@AnnotationGroup(RestOp.class) 050public @interface RestGet { 051 052 /** 053 * Specifies whether this method can be called based on the client version. 054 * 055 * <p> 056 * The client version is identified via the HTTP request header identified by 057 * {@link Rest#clientVersionHeader() @Rest(clientVersionHeader)} which by default is <js>"Client-Version"</js>. 058 * 059 * <p> 060 * This is a specialized kind of {@link RestMatcher} that allows you to invoke different Java methods for the same 061 * method/path based on the client version. 062 * 063 * <p> 064 * The format of the client version range is similar to that of OSGi versions. 065 * 066 * <p> 067 * In the following example, the Java methods are mapped to the same HTTP method and URL <js>"/foobar"</js>. 068 * <p class='bjava'> 069 * <jc>// Call this method if Client-Version is at least 2.0. 070 * // Note that this also matches 2.0.1.</jc> 071 * <ja>@RestGet</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>) 072 * <jk>public</jk> Object method1() {...} 073 * 074 * <jc>// Call this method if Client-Version is at least 1.1, but less than 2.0.</jc> 075 * <ja>@RestGet</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>) 076 * <jk>public</jk> Object method2() {...} 077 * 078 * <jc>// Call this method if Client-Version is less than 1.1.</jc> 079 * <ja>@RestGet</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"[0,1.1)"</js>) 080 * <jk>public</jk> Object method3() {...} 081 * </p> 082 * 083 * <p> 084 * It's common to combine the client version with transforms that will convert new POJOs into older POJOs for 085 * backwards compatibility. 086 * <p class='bjava'> 087 * <jc>// Call this method if Client-Version is at least 2.0.</jc> 088 * <ja>@RestGet</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"2.0"</js>) 089 * <jk>public</jk> NewPojo newMethod() {...} 090 * 091 * <jc>// Call this method if Client-Version is at least 1.1, but less than 2.0.</jc> 092 * <ja>@RestGet</ja>(path=<js>"/foobar"</js>, clientVersion=<js>"[1.1,2.0)"</js>) 093 * <ja>@BeanConfig(swaps=NewToOldSwap.<jk>class</jk>) 094 * <jk>public</jk> NewPojo oldMethod() { 095 * <jk>return</jk> newMethod(); 096 * } 097 * </p> 098 * 099 * <p> 100 * Note that in the previous example, we're returning the exact same POJO, but using a transform to convert it into 101 * an older form. 102 * The old method could also just return back a completely different object. 103 * The range can be any of the following: 104 * <ul> 105 * <li><js>"[0,1.0)"</js> = Less than 1.0. 1.0 and 1.0.0 does not match. 106 * <li><js>"[0,1.0]"</js> = Less than or equal to 1.0. Note that 1.0.1 will match. 107 * <li><js>"1.0"</js> = At least 1.0. 1.0 and 2.0 will match. 108 * </ul> 109 * 110 * <h5 class='section'>See Also:</h5><ul> 111 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#clientVersionHeader(String)} 112 * </ul> 113 * 114 * @return The annotation value. 115 */ 116 String clientVersion() default ""; 117 118 /** 119 * Class-level response converters. 120 * 121 * <p> 122 * Associates one or more {@link RestConverter converters} with this method. 123 * 124 * <h5 class='section'>See Also:</h5><ul> 125 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#converters()} - Registering converters with REST resources. 126 * </ul> 127 * 128 * @return The annotation value. 129 */ 130 Class<? extends RestConverter>[] converters() default {}; 131 132 /** 133 * Enable debug mode. 134 * 135 * <p> 136 * Enables the following: 137 * <ul class='spaced-list'> 138 * <li> 139 * HTTP request/response bodies are cached in memory for logging purposes. 140 * <li> 141 * Request/response messages are automatically logged. 142 * </ul> 143 * 144 * <ul class='values'> 145 * <li><js>"true"</js> - Debug is enabled for all requests. 146 * <li><js>"false"</js> - Debug is disabled for all requests. 147 * <li><js>"conditional"</js> - Debug is enabled only for requests that have a <c class='snippet'>Debug: true</c> header. 148 * <li><js>""</js> (or anything else) - Debug mode is inherited from class. 149 * </ul> 150 * 151 * <h5 class='section'>Notes:</h5><ul> 152 * <li class='note'> 153 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 154 * (e.g. <js>"$L{my.localized.variable}"</js>). 155 * </ul> 156 * 157 * <h5 class='section'>See Also:</h5><ul> 158 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#debugEnablement()} 159 * </ul> 160 * 161 * @return The annotation value. 162 */ 163 String debug() default ""; 164 165 /** 166 * Default <c>Accept</c> header. 167 * 168 * <p> 169 * The default value for the <c>Accept</c> header if not specified on a request. 170 * 171 * <p> 172 * This is a shortcut for using {@link #defaultRequestHeaders()} for just this specific header. 173 * 174 * @return The annotation value. 175 */ 176 String defaultAccept() default ""; 177 178 /** 179 * Default character encoding. 180 * 181 * <p> 182 * The default character encoding for the request and response if not specified on the request. 183 * 184 * <h5 class='section'>Notes:</h5><ul> 185 * <li class='note'> 186 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 187 * (e.g. <js>"$S{mySystemProperty}"</js>). 188 * </ul> 189 * 190 * <h5 class='section'>See Also:</h5><ul> 191 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultCharset(Charset)} 192 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#defaultCharset(Charset)} 193 * <li class='ja'>{@link Rest#defaultCharset} 194 * </ul> 195 * 196 * @return The annotation value. 197 */ 198 String defaultCharset() default ""; 199 200 /** 201 * Specifies default values for query parameters. 202 * 203 * <p> 204 * Strings are of the format <js>"name=value"</js>. 205 * 206 * <p> 207 * Affects values returned by {@link RestRequest#getQueryParam(String)} when the parameter is not present on the request. 208 * 209 * <h5 class='section'>Example:</h5> 210 * <p class='bjava'> 211 * <ja>@RestGet</ja>(path=<js>"/*"</js>, defaultRequestQueryData={<js>"foo=bar"</js>}) 212 * <jk>public</jk> String doGet(<ja>@Query</ja>(<js>"foo"</js>) String <jv>foo</jv>) {...} 213 * </p> 214 * 215 * <h5 class='section'>Notes:</h5><ul> 216 * <li class='note'> 217 * You can use either <js>':'</js> or <js>'='</js> as the key/value delimiter. 218 * <li class='note'> 219 * Key and value is trimmed of whitespace. 220 * <li class='note'> 221 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 222 * (e.g. <js>"$S{mySystemProperty}"</js>). 223 * </ul> 224 * 225 * @return The annotation value. 226 */ 227 String[] defaultRequestQueryData() default {}; 228 229 /** 230 * Default request attributes. 231 * 232 * <p> 233 * Specifies default values for request attributes if they're not already set on the request. 234 * 235 * <p> 236 * Affects values returned by the following methods: 237 * <ul> 238 * <li class='jm'>{@link RestRequest#getAttribute(String)}. 239 * <li class='jm'>{@link RestRequest#getAttributes()}. 240 * </ul> 241 * 242 * <h5 class='section'>Example:</h5> 243 * <p class='bjava'> 244 * <jc>// Defined via annotation resolving to a config file setting with default value.</jc> 245 * <ja>@Rest</ja>(defaultRequestAttributes={<js>"Foo=bar"</js>, <js>"Baz: $C{REST/myAttributeValue}"</js>}) 246 * <jk>public class</jk> MyResource { 247 * 248 * <jc>// Override at the method level.</jc> 249 * <ja>@RestGet</ja>(defaultRequestAttributes={<js>"Foo: bar"</js>}) 250 * <jk>public</jk> Object myMethod() {...} 251 * } 252 * </p> 253 * 254 * </ul> 255 * <h5 class='section'>Notes:</h5><ul> 256 * <li class='note'> 257 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 258 * (e.g. <js>"$L{my.localized.variable}"</js>). 259 * </ul> 260 * 261 * <h5 class='section'>See Also:</h5><ul> 262 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultRequestAttributes(NamedAttribute...)} 263 * <li class='ja'>{@link Rest#defaultRequestAttributes()} 264 * </ul> 265 * 266 * @return The annotation value. 267 */ 268 String[] defaultRequestAttributes() default {}; 269 270 /** 271 * Default request headers. 272 * 273 * <p> 274 * Specifies default values for request headers if they're not passed in through the request. 275 * 276 * <h5 class='section'>Example:</h5> 277 * <p class='bjava'> 278 * <jc>// Assume "text/json" Accept value when Accept not specified</jc> 279 * <ja>@RestGet</ja>(path=<js>"/*"</js>, defaultRequestHeaders={<js>"Accept: text/json"</js>}) 280 * <jk>public</jk> String doGet() {...} 281 * </p> 282 * 283 * <h5 class='section'>Notes:</h5><ul> 284 * <li class='note'> 285 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 286 * (e.g. <js>"$S{mySystemProperty}"</js>). 287 * </ul> 288 * 289 * <h5 class='section'>See Also:</h5><ul> 290 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultRequestHeaders(org.apache.http.Header...)} 291 * </ul> 292 * 293 * @return The annotation value. 294 */ 295 String[] defaultRequestHeaders() default {}; 296 297 /** 298 * Default response headers. 299 * 300 * <p> 301 * Specifies default values for response headers if they're not overwritten during the request. 302 * 303 * <h5 class='section'>Example:</h5> 304 * <p class='bjava'> 305 * <jc>// Assume "text/json" Accept value when Accept not specified</jc> 306 * <ja>@RestGet</ja>(path=<js>"/*"</js>, defaultResponseHeaders={<js>"Content-Type: text/json"</js>}) 307 * <jk>public</jk> String doGet() {...} 308 * </p> 309 * 310 * <h5 class='section'>Notes:</h5><ul> 311 * <li class='note'> 312 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 313 * (e.g. <js>"$S{mySystemProperty}"</js>). 314 * </ul> 315 * 316 * <h5 class='section'>See Also:</h5><ul> 317 * <li class='jm'>{@link org.apache.juneau.rest.RestContext.Builder#defaultResponseHeaders(org.apache.http.Header...)} 318 * </ul> 319 * 320 * @return The annotation value. 321 */ 322 String[] defaultResponseHeaders() default {}; 323 324 /** 325 * Optional description for the exposed API. 326 * 327 * <p> 328 * This description is used in the following locations: 329 * <ul class='spaced-list'> 330 * <li> 331 * The value returned by {@link Operation#getDescription()} in the auto-generated swagger. 332 * <li> 333 * The <js>"$RS{operationDescription}"</js> variable. 334 * <li> 335 * The description of the method in the Swagger page. 336 * </ul> 337 * 338 * <h5 class='section'>Notes:</h5><ul> 339 * <li class='note'> 340 * Corresponds to the swagger field <c>/paths/{path}/{method}/description</c>. 341 * <li class='note'> 342 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 343 * (e.g. <js>"$L{my.localized.variable}"</js>). 344 * </ul> 345 * 346 * @return The annotation value. 347 */ 348 String[] description() default {}; 349 350 /** 351 * Specifies the compression encoders for this method. 352 * 353 * <p> 354 * Encoders are used to enable various kinds of compression (e.g. <js>"gzip"</js>) on requests and responses. 355 * 356 * <p> 357 * This value overrides encoders specified at the class level using {@link Rest#encoders()}. 358 * The {@link org.apache.juneau.encoders.EncoderSet.Inherit} class can be used to include values from the parent class. 359 * 360 * <h5 class='section'>Example:</h5> 361 * <p class='bjava'> 362 * <jc>// Define a REST resource that handles GZIP compression.</jc> 363 * <ja>@Rest</ja>( 364 * encoders={ 365 * GzipEncoder.<jk>class</jk> 366 * } 367 * ) 368 * <jk>public class</jk> MyResource { 369 * 370 * <jc>// Define a REST method that can also use a custom encoder.</jc> 371 * <ja>@RestGet</ja>( 372 * method=<jsf>GET</jsf>, 373 * encoders={ 374 * EncoderSet.Inherit.<jk>class</jk>, MyEncoder.<jk>class</jk> 375 * } 376 * ) 377 * <jk>public</jk> MyBean doGet() { 378 * ... 379 * } 380 * } 381 * </p> 382 * 383 * <p> 384 * The programmatic equivalent to this annotation is: 385 * <p class='bjava'> 386 * RestOpContext.Builder <jv>builder</jv> = RestOpContext.<jsm>create</jsm>(<jv>method</jv>,<jv>restContext</jv>); 387 * <jv>builder</jv>.getEncoders().set(<jv>classes</jv>); 388 * </p> 389 * 390 * <h5 class='section'>See Also:</h5><ul> 391 * <li class='link'><a class="doclink" href="../../../../../index.html#jrs.Encoders">Encoders</a> 392 * </ul> 393 * 394 * @return The annotation value. 395 */ 396 Class<? extends Encoder>[] encoders() default {}; 397 398 /** 399 * Method-level guards. 400 * 401 * <p> 402 * Associates one or more {@link RestGuard RestGuards} with this method. 403 * 404 * <h5 class='section'>See Also:</h5><ul> 405 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#guards()} 406 * </ul> 407 * 408 * @return The annotation value. 409 */ 410 Class<? extends RestGuard>[] guards() default {}; 411 412 /** 413 * Method matchers. 414 * 415 * <p> 416 * Associates one more more {@link RestMatcher RestMatchers} with this method. 417 * 418 * <p> 419 * Matchers are used to allow multiple Java methods to handle requests assigned to the same URL path pattern, but 420 * differing based on some request attribute, such as a specific header value. 421 * 422 * <h5 class='section'>See Also:</h5><ul> 423 * <li class='jac'>{@link RestMatcher} 424 * </ul> 425 * 426 * @return The annotation value. 427 */ 428 Class<? extends RestMatcher>[] matchers() default {}; 429 430 /** 431 * Dynamically apply this annotation to the specified methods. 432 * 433 * <h5 class='section'>See Also:</h5><ul> 434 * <li class='link'><a class="doclink" href="../../../../../index.html#jm.DynamicallyAppliedAnnotations">Dynamically Applied Annotations</a> 435 * </ul> 436 * 437 * @return The annotation value. 438 */ 439 String[] on() default {}; 440 441 /** 442 * Optional path pattern for the specified method. 443 * 444 * <p> 445 * Appending <js>"/*"</js> to the end of the path pattern will make it match any remainder too. 446 * <br>Not appending <js>"/*"</js> to the end of the pattern will cause a 404 (Not found) error to occur if the exact 447 * pattern is not found. 448 * 449 * <p> 450 * The path can contain variables that get resolved to {@link org.apache.juneau.http.annotation.Path @Path} parameters. 451 * 452 * <h5 class='figure'>Examples:</h5> 453 * <p class='bjava'> 454 * <ja>@RestGet</ja>(path=<js>"/myurl/{foo}/{bar}/{baz}/*"</js>) 455 * </p> 456 * <p class='bjava'> 457 * <ja>@RestGet</ja>(path=<js>"/myurl/{0}/{1}/{2}/*"</js>) 458 * </p> 459 * 460 * <p> 461 * Note that you can also use {@link #value()} to specify the path. 462 * 463 * <h5 class='section'>See Also:</h5><ul> 464 * <li class='ja'>{@link org.apache.juneau.http.annotation.Path} 465 * </ul> 466 * 467 * @return The annotation value. 468 */ 469 String[] path() default {}; 470 471 /** 472 * Supported accept media types. 473 * 474 * <p> 475 * Overrides the media types inferred from the serializers that identify what media types can be produced by the resource. 476 * 477 * <h5 class='section'>Notes:</h5><ul> 478 * <li class='note'> 479 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 480 * (e.g. <js>"$S{mySystemProperty}"</js>). 481 * </ul> 482 * 483 * <h5 class='section'>See Also:</h5><ul> 484 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#produces(MediaType...)} 485 * </ul> 486 * 487 * @return The annotation value. 488 */ 489 String[] produces() default {}; 490 491 /** 492 * Role guard. 493 * 494 * <p> 495 * An expression defining if a user with the specified roles are allowed to access this method. 496 * 497 * <h5 class='section'>Example:</h5> 498 * <p class='bjava'> 499 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 500 * 501 * <ja>@RestGet</ja>( 502 * path=<js>"/foo"</js>, 503 * roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js> 504 * ) 505 * <jk>public</jk> Object doGet() { 506 * } 507 * } 508 * </p> 509 * 510 * <h5 class='section'>Notes:</h5><ul> 511 * <li class='note'> 512 * Supports any of the following expression constructs: 513 * <ul> 514 * <li><js>"foo"</js> - Single arguments. 515 * <li><js>"foo,bar,baz"</js> - Multiple OR'ed arguments. 516 * <li><js>"foo | bar | baz"</js> - Multiple OR'ed arguments, pipe syntax. 517 * <li><js>"foo || bar || baz"</js> - Multiple OR'ed arguments, Java-OR syntax. 518 * <li><js>"fo*"</js> - Patterns including <js>'*'</js> and <js>'?'</js>. 519 * <li><js>"fo* & *oo"</js> - Multiple AND'ed arguments, ampersand syntax. 520 * <li><js>"fo* && *oo"</js> - Multiple AND'ed arguments, Java-AND syntax. 521 * <li><js>"fo* || (*oo || bar)"</js> - Parenthesis. 522 * </ul> 523 * <li class='note'> 524 * AND operations take precedence over OR operations (as expected). 525 * <li class='note'> 526 * Whitespace is ignored. 527 * <li class='note'> 528 * <jk>null</jk> or empty expressions always match as <jk>false</jk>. 529 * <li class='note'> 530 * If patterns are used, you must specify the list of declared roles using {@link #rolesDeclared()} or {@link org.apache.juneau.rest.RestOpContext.Builder#rolesDeclared(String...)}. 531 * <li class='note'> 532 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 533 * (e.g. <js>"$L{my.localized.variable}"</js>). 534 * <li class='note'> 535 * When defined on parent/child classes and methods, ALL guards within the hierarchy must pass. 536 * </ul> 537 * 538 * <h5 class='section'>See Also:</h5><ul> 539 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#roleGuard(String)} 540 * </ul> 541 * 542 * @return The annotation value. 543 */ 544 String roleGuard() default ""; 545 546 /** 547 * Declared roles. 548 * 549 * <p> 550 * A comma-delimited list of all possible user roles. 551 * 552 * <p> 553 * Used in conjunction with {@link #roleGuard()} is used with patterns. 554 * 555 * <h5 class='section'>Example:</h5> 556 * <p class='bjava'> 557 * <jk>public class</jk> MyResource <jk>extends</jk> BasicRestServlet { 558 * 559 * <ja>@RestGet</ja>( 560 * path=<js>"/foo"</js>, 561 * rolesDeclared=<js>"ROLE_ADMIN,ROLE_READ_WRITE,ROLE_READ_ONLY,ROLE_SPECIAL"</js>, 562 * roleGuard=<js>"ROLE_ADMIN || (ROLE_READ_WRITE && ROLE_SPECIAL)"</js> 563 * ) 564 * <jk>public</jk> Object doGet() { 565 * } 566 * } 567 * </p> 568 * 569 * <h5 class='section'>See Also:</h5><ul> 570 * <li class='jm'>{@link org.apache.juneau.rest.RestOpContext.Builder#rolesDeclared(String...)} 571 * </ul> 572 * 573 * @return The annotation value. 574 */ 575 String rolesDeclared() default ""; 576 577 /** 578 * Specifies the serializers for marshalling POJOs into response bodies for this method. 579 * 580 * <p> 581 * Serializer are used to convert POJOs to HTTP response bodies. 582 * <br>Any of the Juneau framework serializers can be used in this setting. 583 * <br>The serializer selected is based on the request <c>Accept</c> header matched against the values returned by the following method 584 * using a best-match algorithm: 585 * <ul class='javatree'> 586 * <li class='jm'>{@link Serializer#getMediaTypeRanges()} 587 * </ul> 588 * 589 * <p> 590 * This value overrides serializers specified at the class level using {@link Rest#serializers()}. 591 * The {@link org.apache.juneau.serializer.SerializerSet.Inherit} class can be used to include values from the parent class. 592 * 593 * <h5 class='section'>Example:</h5> 594 * <p class='bjava'> 595 * <jc>// Define a REST resource that can produce JSON and HTML.</jc> 596 * <ja>@Rest</ja>( 597 * serializers={ 598 * JsonParser.<jk>class</jk>, 599 * HtmlParser.<jk>class</jk> 600 * } 601 * ) 602 * <jk>public class</jk> MyResource { 603 * 604 * <jc>// Define a REST method that can also produce XML.</jc> 605 * <ja>@RestGet</ja>( 606 * parsers={ 607 * SerializerSet.Inherit.<jk>class</jk>, XmlParser.<jk>class</jk> 608 * } 609 * ) 610 * <jk>public</jk> MyBean doGet() { 611 * ... 612 * } 613 * } 614 * </p> 615 * 616 * <p> 617 * The programmatic equivalent to this annotation is: 618 * <p class='bjava'> 619 * RestOpContext.Builder <jv>builder</jv> = RestOpContext.<jsm>create</jsm>(<jv>method</jv>,<jv>restContext</jv>); 620 * <jv>builder</jv>.getSerializers().set(<jv>classes</jv>); 621 * </p> 622 * 623 * <h5 class='section'>See Also:</h5><ul> 624 * <li class='link'><a class="doclink" href="../../../../../index.html#jrs.Marshalling">Marshalling</a> 625 * </ul> 626 * 627 * @return The annotation value. 628 */ 629 Class<? extends Serializer>[] serializers() default {}; 630 631 /** 632 * Optional summary for the exposed API. 633 * 634 * <p> 635 * This summary is used in the following locations: 636 * <ul class='spaced-list'> 637 * <li> 638 * The value returned by {@link Operation#getSummary()} in the auto-generated swagger. 639 * <li> 640 * The <js>"$RS{operationSummary}"</js> variable. 641 * <li> 642 * The summary of the method in the Swagger page. 643 * </ul> 644 * 645 * <h5 class='section'>Notes:</h5><ul> 646 * <li class='note'> 647 * Corresponds to the swagger field <c>/paths/{path}/{method}/summary</c>. 648 * <li class='note'> 649 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 650 * (e.g. <js>"$L{my.localized.variable}"</js>). 651 * </ul> 652 * 653 * @return The annotation value. 654 */ 655 String summary() default ""; 656 657 /** 658 * Provides swagger-specific metadata on this method. 659 * 660 * <p> 661 * Used to populate the auto-generated OPTIONS swagger documentation. 662 * 663 * <p> 664 * The format of this annotation is JSON when all individual parts are concatenated. 665 * <br>The starting and ending <js>'{'</js>/<js>'}'</js> characters around the entire value are optional. 666 * 667 * <h5 class='section'>Example:</h5> 668 * <p class='bjava'> 669 * <ja>@RestGet</ja>( 670 * path=<js>"/{propertyName}"</js>, 671 * 672 * <jc>// Swagger info.</jc> 673 * swagger={ 674 * <js>"parameters:["</js>, 675 * <js>"{name:'propertyName',in:'path',description:'The system property name.'},"</js>, 676 * <js>"{in:'body',description:'The new system property value.'}"</js>, 677 * <js>"],"</js>, 678 * <js>"responses:{"</js>, 679 * <js>"302: {headers:{Location:{description:'The root URL of this resource.'}}},"</js>, 680 * <js>"403: {description:'User is not an admin.'}"</js>, 681 * <js>"}"</js> 682 * } 683 * ) 684 * </p> 685 * 686 * <h5 class='section'>Notes:</h5><ul> 687 * <li class='note'> 688 * The format is <a class="doclink" href="../../../../../index.html#jd.Swagger">Swagger</a>. 689 * <br>Multiple lines are concatenated with newlines. 690 * <li class='note'> 691 * The starting and ending <js>'{'</js>/<js>'}'</js> characters around the entire value are optional. 692 * <li class='note'> 693 * These values are superimposed on top of any Swagger JSON file present for the resource in the classpath. 694 * <li class='note'> 695 * Supports <a class="doclink" href="../../../../../index.html#jrs.SvlVariables">SVL Variables</a> 696 * (e.g. <js>"$L{my.localized.variable}"</js>). 697 * </ul> 698 * 699 * <h5 class='section'>See Also:</h5><ul> 700 * <li class='ja'>{@link OpSwagger} 701 * <li class='jc'>{@link SwaggerProvider} 702 * </ul> 703 * 704 * @return The annotation value. 705 */ 706 OpSwagger swagger() default @OpSwagger; 707 708 /** 709 * REST method path. 710 * 711 * <p> 712 * Can be used to provide a shortened form for the {@link #path()} value. 713 * 714 * <p> 715 * The following examples are considered equivalent. 716 * <p class='bjava'> 717 * <jc>// Normal form</jc> 718 * <ja>@RestGet</ja>(path=<js>"/{propertyName}"</js>) 719 * 720 * <jc>// Shortened form</jc> 721 * <ja>@RestGet</ja>(<js>"/{propertyName}"</js>) 722 * </p> 723 * 724 * @return The annotation value. 725 */ 726 String value() default ""; 727}