Plumber API and package structure

Hi all! Thanks for this thread - I found it very useful to pack our production APIs and thanks to @julia for the offline conversation to clarify some points.

We ended up with pretty much the same structure with additional code that doesn't only test the contents of the R folder but actually runs the API itself that sits in inst folder and checks it A to Z for the response validity. Now we can really make sure that things are working as expected before deploying.

Our solution below:

context("API testing")


test_that("local deployment works", {
    
    rs <- callr::r_bg(
    function() {
        pr <- plumber::plumb(file.path("path", "inst", "plumber.R"));
        pr$run(port=8000)
    })
    
    Sys.sleep(3)
    
    link <- "http://localhost:8000/calculate?x=2&y=4"
    
    call <- tryCatch(
    httr::GET(
    url = link,
    httr::add_headers(
    `accept` = 'application/json'),
    httr::content_type("application/json")
    ),
    error = function(x) NA)
    
    print(call)
    
    call_parse <- tryCatch(
    httr::content(call, encoding = "UTF-8"),
    error = function(x) NA)
    
    print(call_parse)
    
    expect_equal(as.numeric(unlist(call_parse)), as.numeric(3))
    
    rs$kill()
})

Brief explanation: we need to run another R process in the background where that particular API would be running so that the main thread could be occupied by the test. We also need to put the execution for a short sleep because it takes a short moment for the API to start. Hope somebody finds this useful!

9 Likes