rstudio / plumber

Turn your R code into a web API.
https://www.rplumber.io
Other
1.4k stars 258 forks source link

Issue in Grouping Operations With Tags using OpenAPI 3.0 YAML file with plumber #537

Closed tezansahu closed 4 years ago

tezansahu commented 4 years ago

System details

Output of sessioninfo::session_info():

- Session info --------------------------------------------------------------------------------------------------------
 setting  value                       
 version  R version 3.6.3 (2020-02-29)
 os       Windows 10 x64              
 system   x86_64, mingw32             
 ui       RStudio                     
 language (EN)                        
 collate  English_India.1252          
 ctype    English_India.1252          
 tz       Asia/Calcutta               
 date     2020-05-25                  

- Packages ------------------------------------------------------------------------------------------------------------
 package     * version     date       lib source                          
 assertthat    0.2.1       2019-03-21 [1] CRAN (R 3.6.2)                  
 cli           2.0.2       2020-02-28 [1] CRAN (R 3.6.3)                  
 colorspace    1.4-1       2019-03-18 [1] CRAN (R 3.6.1)                  
 crayon        1.3.4       2017-09-16 [1] CRAN (R 3.6.2)                  
 dplyr         0.8.5       2020-03-07 [1] CRAN (R 3.6.3)                  
 fansi         0.4.1       2020-01-08 [1] CRAN (R 3.6.2)                  
 ggplot2     * 3.2.1       2019-08-10 [1] CRAN (R 3.6.2)                  
 glue          1.4.1       2020-05-13 [1] CRAN (R 3.6.3)                  
 gtable        0.3.0       2019-03-25 [1] CRAN (R 3.6.2)                  
 httpuv        1.5.2       2019-09-11 [1] CRAN (R 3.6.2)                  
 jsonlite      1.6.1       2020-02-02 [1] CRAN (R 3.6.2)                  
 later         1.0.0       2019-10-04 [1] CRAN (R 3.6.2)                  
 lazyeval      0.2.2       2019-03-15 [1] CRAN (R 3.6.2)                  
 lifecycle     0.1.0       2019-08-01 [1] CRAN (R 3.6.2)                  
 magrittr      1.5         2014-11-22 [1] CRAN (R 3.6.2)                  
 munsell       0.5.0       2018-06-12 [1] CRAN (R 3.6.2)                  
 pillar        1.4.3       2019-12-20 [1] CRAN (R 3.6.2)                  
 pkgconfig     2.0.3       2019-09-22 [1] CRAN (R 3.6.2)                  
 plumber     * 0.4.7.9000  2020-05-17 [1] Github (rstudio/plumber@b7ff05a)
 promises      1.1.0       2019-10-04 [1] CRAN (R 3.6.3)                  
 purrr         0.3.3       2019-10-18 [1] CRAN (R 3.6.3)                  
 R6            2.4.1       2019-11-12 [1] CRAN (R 3.6.2)                  
 Rcpp          1.0.4.6     2020-04-09 [1] CRAN (R 3.6.3)                  
 rlang         0.4.6       2020-05-02 [1] CRAN (R 3.6.3)                  
 rstudioapi    0.11        2020-02-07 [1] CRAN (R 3.6.3)                  
 scales        1.1.0       2019-11-18 [1] CRAN (R 3.6.2)                  
 sessioninfo   1.1.1       2018-11-05 [1] CRAN (R 3.6.3)                  
 stringi       1.4.6       2020-02-17 [1] CRAN (R 3.6.2)                  
 swagger       3.20.3.9999 2020-05-17 [1] Github (rstudio/swagger@67239fd)
 tibble        2.1.3       2019-06-06 [1] CRAN (R 3.6.2)                  
 tidyselect    1.0.0       2020-01-27 [1] CRAN (R 3.6.3)                  
 withr         2.1.2       2018-03-15 [1] CRAN (R 3.6.2)                  
 yaml          2.2.1       2020-02-01 [1] CRAN (R 3.6.2)                  

[1] C:/Users/tezan/Documents/R/win-library/3.6
[2] C:/Program Files/R/R-3.6.3/library

Example application or steps to reproduce the problem

These are files (all to be placed in the same folder) necessary for reproducing the issue:

api-spec.yaml:

# api-spec.yaml
openapi: 3.0.0
servers:
  - description: Localhost
    url: http://127.0.0.1:8000
info:
  description: This is a simple Plumber API with the spec defined in an external file
  version: "1.0.0"
  title: Simple Plumber

paths:
  /echo/echo:
    get:
      summary: Echos back a message
      tags:
      - echo
      description: |
        Pass a message and have it echoed in return in JSON
      parameters:
        - in: query
          name: msg
          description: Message to echo in return
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful message

echo.R:

# plumber.R
library(plumber)

#* @get /echo
function(msg = "") {
  list(msg = paste0("The message is: '", msg, "'"))
}

start_server.R:

library(plumber);

root <- plumber$new()
echo_pr <- plumber$new("echo.R")
root$mount("/echo", echo_pr)

root$run(port=8000, swagger = function(pr, spec, ...) {
  spec <- yaml::read_yaml("api-spec.yaml")
  spec
})

Now, run the start_server.R & inspect the Swagger documentation produced at http://127.0.0.1:8000/__swagger__/

Describe the problem in detail

The segregation into sections using tags behaves weirdly as shown: image Instead of the whole world echo, each letter of the word becomes a new section. I tried to write the tag as "echo" as well as 'echo', but still the problem persists.

However, while testing the same YAML file on online Swagger editor, it behaves normally as shown: image

I am unable to understand what is going wrong with the same file when being used in plumber.

meztez commented 4 years ago

tags should be an array. read_yaml return a character vector of length 1 for tags. It should be a list.

You can make it work this way, but you will have to find something else if you want to generalize this solution.

root$run(port=8000, swagger = function(pr, spec, ...) {
  spec <- yaml::read_yaml("../issue.yaml")
  spec$paths$`/echo/echo`$get$tags <- list(spec$paths$`/echo/echo`$get$tags)
  spec
})

What happens is read_yaml reads your tags as a single character vector instead of a list. It then gets transformed into json with tags being "tags":"echo". Swagger expects a list so it interprets it as a list of individual characters. Tags should be enclosed in square brackets [] in a valid OpenAPI specification.

Another easy alternative would be to add a second useless tag

# api-spec.yaml
openapi: 3.0.0
servers:
  - description: Localhost
    url: http://127.0.0.1:8000
info:
  description: This is a simple Plumber API with the spec defined in an external file
  version: "1.0.0"
  title: Simple Plumber

paths:
  /echo/echo:
    get:
      summary: Echos back a message
      tags:
      - echo
      - +
      description: |
        Pass a message and have it echoed in return in JSON
      parameters:
        - in: query
          name: msg
          description: Message to echo in return
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful message

This is not a plumber issue, sorry

tezansahu commented 4 years ago

Thanks a lot @meztez ! It worked like a charm.

Instead of a second useless tag like + (which leads to the appearance of an extra unnecessary section called "+" in the swagger documentation), I actually used an empty tag...that did not result in any extra section other than those that I had actually tagged.

Looked something like this:

paths:
  /echo/echo:
    get:
      summary: Echos back a message
      tags:
      - echo
      - 
      description: |
        Pass a message and have it echoed in return in JSON
      parameters:
        - in: query
          name: msg
          description: Message to echo in return
          required: true
          schema:
            type: string
      responses:
        '200':
          description: successful message
meztez commented 4 years ago

@tezansahu Can you close the issue?