This package provides a single function that generates a highly flexible plumber API for any R data.frame, tibble, or DBI-compatible database (dbplyr::src_dbi
) with just a couple of lines. The aim is to extend dplyr
's tidy data manipulation capabilities to the front-end client by providing an API syntax that mirrors that of dplyr - so you can filter, group, summarise and arrange - via API call - data that is located in a PostgreSQL database.
devtools::install_github('geotheory/quickplumb')
Create the following file:
# plumber.R
require(quickplumb)
require(plumber)
require(dplyr)
require(RPostgreSQL)
drv <<- dbDriver("PostgreSQL")
sapply(dbListConnections(drv), dbDisconnect)
con <<- dbConnect(drv, dbname = "mydb", host = "localhost",
port = 5432, user = "username")
#' redirect root to your Swagger API documentation page
#' @get /
#' @html
function(){'<meta http-equiv="refresh" content="0; URL=\'./__swagger__/\'" />'}
# To create iris db table run following line once:
# copy_to(con, iris, "iris", temporary = FALSE)
iris_pg <<- tbl(con, "iris")
iris_pg_names = names(collect(head(iris_pg, 1)))
#' iris dataset for demo & testing
#' @param all_params See documentation
#' @get /iris
quick_plumb(tbl = iris_pg, tbl_names = iris_pg_names, def_max_records = 100, hard_max_records = 150)
To start the API navigate R to the plumber.R
directory and run:
plumber::plumb()$run(port = 4444)
-
...
A placeholder for any field name in the dataset to query and filter by.- Numerical arguments are identified by starting with one of <, >, ~ characters (~ changes to =), e.g:
Sepal.Length=>~7.1
is interpreted as ">=" (i.e. greater than or equal to). While described as numerical this syntax also works with equivalent string comparisons. - String arguments (not starting ~/</>) are parsed with a boolean logic interpreter (using upper-case AND/OR operators) e.g:
Paris AND Berlin
orParis OR Berlin
; and recognises negation with "-" hyphen, e.g:Species=-setosa
.
- Numerical arguments are identified by starting with one of <, >, ~ characters (~ changes to =), e.g:
-
_select
: Fields to return - equivalent todplyr::select
. e.g. return only_select=Species,Sepal.Length
or omit_select=-Species
-
_group_by
: Fields to group by for aggregations - equivalent todplyr::group_by
. Must be used together with_summarise
and/or_count
-
_summarise
: Aggregate fields by a function - equivalent todplyr::summarise
. e.g._group_by=Species&_summarise=mean:Sepal.Length
. Accepts multiple formulae (separate by +) in the formatfun:field1,field2,..
where aggregate functionfun
is piped directly to dplyr::filter. Functions tested includemax
,min
,mean
, andsum
. Other desirables such asmode
,median
,dplyr::first/last
are not currently supported, but hopefully will be soon. -
_count
: Count records - equivalent todplyr::count
but requires any grouping to be done by_group_by
. e.g._group_by=Species&_count=yes
or just_count=yes
to count all records -
_arrange_by
: Sort resulting table by specific field(s) - equivalent todplyr::arrange
. e.g._arrange_by=Species,Sepal.Length
-
max_records
: Maximum data rows to return. e.g.max_records=1000
-
case_sen
: case-sensitivity - boolean querying ignores case by default. Providing this argument over-rides, e.g.case_sen=true
-
API root endpoint
-
a boolean logical query (URL spaces are replaced by '%20' by the browser)
-
a NOT query - i.e. omit setosa
-
a numerical comparative filter (tilde ~ becomes '=', so this example shows greater-than-and-equal-to and less-than usage)
http://127.0.0.1:4444/iris?Sepal.Length=>~7.0&Sepal.Length=<7.5
-
return specified fields only
-
return all fields except specified
-
sort matching data by field(s)
http://127.0.0.1:4444/iris?_arrange_by=Petal.Length,Petal.Width
-
number of records to return (unless overridden by
quick_plumb(hard_max_records=...)
) -
count rows by variable
-
aggregate data by variable(s)
-
for an idea of more complex query, create an API for ggplot2::diamonds at
/diamonds
and call: