--- title: "Annotations reference" knitr: opts_chunk: collapse: false comment: "#>" vignette: > %\VignetteIndexEntry{Annotations reference} %\VignetteEngine{quarto::html} %\VignetteEncoding{UTF-8} --- ```{r} #| include: false me <- normalizePath( if (Sys.getenv("QUARTO_DOCUMENT_PATH") != "") { Sys.getenv("QUARTO_DOCUMENT_PATH") } else if (file.exists("_helpers.R")) { getwd() } else if (file.exists("vignettes/_helpers.R")) { "vignettes" } else if (file.exists("articles/_helpers.R")) { "articles" } else { "vignettes/articles" }) source(file.path(me, "_helpers.R")) readLines <- function(x) base::readLines(file.path(me, x)) ``` ## Annotations {#annotations} Annotations are specially-structured comments used in your plumber file to create an API. A full annotation line starts with `#*`, then the annotation keyword `@...`, any number of space characters followed by the content. If you wish to use the annotation to document your API file but don't want any OpenAPI documentation to be generated you can use `@noDoc` tag which works much like roxygens `@noRd`. ## Annotation settings A few annotations modify how the file is parsed and interpreted. These must all appear in the first block of the file (in the case of `@roxygenPrefix` the first line). ### Use roxygen prefix By default, plumber2 uses the `#*` prefix for its blocks to avoid clashing with roxygen comments. plumber (the old one) allowed either and while it is recommended to differentiate between roxygen and plumber2 annotations you can opt in to also understanding roxygen prefix. >This tag **must** appear on the first line of the file to have an effect. | Annotation | Argument | Description/References | |-----------------|-----------------|-----------------------------| | `@roxygenPrefix` | None | Turns on roxygen prefix for the file | If you wish to always allow roxygen prefixes you can set the `plumber2.roxygenPrefix` option to `TRUE` ##### Annotations example ``` r #* @roxygenPrefix NULL ``` ##### Equivalent programmatic usage There is no direct equivalent in programmatic usage as this pertains to the parsing of the plumber file. ### Specifying route name By default, the name of the file (without extension) is used as the name for the route any handlers etc are attached to. However, you can change this by having a first block in your file with a `@routeName` tag specifying the name to use for all route specific blocks in the file. This also makes it possible to split out the specification of a single route among multiple files if it begins to grow unwieldy | Annotation | Argument | Description/References | |-----------------|-----------------|-----------------------------| | `@routeName` | `name` | Sets the name of the route to use for all blocks in the file | ##### Annotations example ``` r #* @routeName main_route NULL ``` ##### Equivalent programmatic usage There is no direct equivalent in programmatic usage as this pertains to the parsing of the plumber file. Any relevant function has a `route` argument where you can specify which route to add the given functionality to. ### Specifying route order Route files are processed in alphanumerical order which influence the order in which their route is attached. You can modify the route order (but not the file processing order) using the `@routeOrder` tag. If multiple files have the same `@routeName` then the lowest `@routeOrder` value will be used. Any file without a `@routeOrder` tag will be added after those that do, using the default alphanumeric order. | Annotation | Argument | Description/References | |-----------------|-----------------|-----------------------------| | `@routeOrder` | `order` | Sets the order in which routes are added to the api. Lower values means earlier position | ##### Annotations example ``` r #* @routeOrder 3 NULL ``` ##### Equivalent programmatic usage You can programmatically control the location of a route you add with `api_add_route()` using the `after` argument. ### Specifying root url for the whole file Many annotations somehow references URL paths, either as the endpoint of a handler, or where to serve a shiny app from. You can set a root for the whole file which will be prepended to any relevant URL. In this way it is easy to move all functionality from a single file to a different location if necessary. | Annotation | Argument | Description/References | |-----------------|-----------------|-----------------------------| | `@root` | `path` | Sets the root of every URL path in the file | ##### Annotations example ``` r #* @root /path/to/these/apis NULL ``` ##### Equivalent programmatic usage You can programmatically set the root of a new route you add with `api_add_route()` using the `root` argument. ## Global annotations {#global-annotations} Global annotations are not related to any handler and should be placed in their own block. The block should be terminated by a `"_API"` expression. Instead of `@title` and `@description` you can also use the convention that the first line gives the title and any proceeding lines until the first tag gives the description. | Annotation | Argument | Description/References | |-------------------|-------------------|----------------------------------| | `@title` | `Title` | [Info Object](https://spec.openapis.org/oas/v3.0.3#info-object) | | `@description` | `Description` | [Info Object](https://spec.openapis.org/oas/v3.0.3#info-object) | | `@tos` | `TOS link` | [Info Object](https://spec.openapis.org/oas/v3.0.3#info-object) | | `@contact` | `Contact object` | [Contact Object](https://spec.openapis.org/oas/v3.0.3#contact-object) | | `@license` | `License object` | [License Object](https://spec.openapis.org/oas/v3.0.3#license-object) | | `@version` | `Version` | [Info Object](https://spec.openapis.org/oas/v3.0.3#info-object) | | `@tag` | `Tag` `Description` | Can be repeated to add multiple tags. Quote with " or ' to use non word character (like spaces) in `Tag`. [Tag Object](https://spec.openapis.org/oas/v3.0.3#tag-object) | | `@noDoc` | None | Don't generate OpenAPI documentation from this block | ##### Annotations example ``` r #* Sample Pet Store App #* #* This is a sample server for a pet store. #* #* @tos http://example.com/terms/ #* @contact list(name = "API Support", url = "http://www.example.com/support", email = "support@example.com") #* @license list(name = "Apache 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0.html") #* @version 1.0.1 #* @tag pet Pets operations #* @tag toy Toys operations #* @tag "toy space" Toys operations "_API" ``` ##### Equivalent programmatic usage ```{r} #| output: false #| eval: !expr R.Version()$minor > package_version("4.0") api() |> api_doc_add( openapi( info = openapi_info( title = "Sample Pet Store App", description = "This is a sample server for a pet store.", terms_of_service = "http://example.com/terms/", contact = openapi_contact(name = "API Support", url = "http://www.example.com/support", email = "support@example.com"), license = openapi_license(name = "Apache 2.0", url = "https://www.apache.org/licenses/LICENSE-2.0.html"), version = "1.0.1" ), tags = list( openapi_tag(name = "pet", description = "Pets operations"), openapi_tag(name = "toy", description = "Toys operations"), openapi_tag(name = "toy space", description = "Toys operations") ) )) ``` ## Handler annotations {#handler-annotations} Handler annotation describe all aspects of a request handler and always proceeds a function which is considered the handler function. The following tags can be used in a handler block. The first line, unless it has a tag is considered the title of the handler and any proceeding lines until the first tag is considered a long-form description. ### Endpoint {#endpoint-block-annotations}
Annotation |
Argument |
Description/References |
---|---|---|
|
|
|
|
None |
Should the handler be attached to the header router |
|
|
Some serializers accept arguments. See serializers article and serializers reference. Aliases : |
|
None |
Turn on strict content negotiation. By default, the first serializer is chosen if the client requests a response type that isnt supported. By using strict content negotiation a 406 response is sent if the requested response type is not available |
|
|
Some parsers accept arguments. See parsers reference. Can be repeated to allow multiple parsers on the same endpoint. Aliases : |
|
|
Adding an asterix indicates that the parameter is required. Can be repeated to define different parameters. If a single |
|
|
Simple Response object. Can be repeated to define different responses. |
|
[ |
Mark the response as something that should be downloaded, optionally setting a default filename for the file |
|
|
Can be repeated to add multiple tags. Quote with or to use non word character (like spaces) in |
|
None |
Marks the handler as a WebSocket message handler. No other tags will have an effect if this tag is present (except |
|
[ |
Marks the handler as running asynchronously. The default uses mirai, but a different registered engine can be specified as well |
|
None |
Chains the handler to the preceeding message or request handler if that handler is asynchronous |
|
[ |
Add CORS to the endpoints in the handler. |
|
[ |
Adds a resource isolation policy to the `get` endpoints in the handler. |
|
None |
Dont generate OpenAPI documentation from this block |