| Type: | Package |
| Title: | A Framework for Building HTTP API |
| Description: | Allows to easily create high-performance full featured HTTP APIs from R functions. Provides high-level classes such as 'Request', 'Response', 'Application', 'Middleware' in order to streamline server side application development. Out of the box allows to serve requests using 'Rserve' package, but flexible enough to integrate with other HTTP servers such as 'httpuv'. |
| Version: | 1.2.4 |
| URL: | https://restrserve.org, https://github.com/rexyai/RestRserve |
| BugReports: | https://github.com/rexyai/RestRserve/issues |
| License: | GPL-2 | GPL-3 [expanded from: GPL (≥ 2)] |
| Depends: | R (≥ 3.6.0) |
| Imports: | methods, parallel, Rserve (≥ 1.7.3), Rcpp (≥ 1.0.3), R6 (≥ 2.4.0), uuid (≥ 0.1-2), checkmate (≥ 1.9.4), mime (≥ 0.7), jsonlite (≥ 1.6), digest (≥ 0.6.29) |
| Suggests: | tinytest (≥ 1.0.0), lgr (≥ 0.3.2), lintr, knitr, rmarkdown, curl, sys |
| LinkingTo: | Rcpp |
| ByteCompile: | true |
| KeepSource: | true |
| Encoding: | UTF-8 |
| RoxygenNote: | 7.3.1 |
| VignetteBuilder: | knitr |
| NeedsCompilation: | yes |
| Packaged: | 2025-03-14 07:55:35 UTC; dselivanov |
| Author: | Dmitry Selivanov |
| Maintainer: | Dmitry Selivanov <selivanov.dmitriy@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2025-03-14 10:30:01 UTC |
RestRserve: A Framework for Building HTTP API
Description
Allows to easily create high-performance full featured HTTP APIs from R functions. Provides high-level classes such as 'Request', 'Response', 'Application', 'Middleware' in order to streamline server side application development. Out of the box allows to serve requests using 'Rserve' package, but flexible enough to integrate with other HTTP servers such as 'httpuv'.
Details
Introduction
Suppose you’ve developed a very useful algorithm or statistical model and you need to integrate it with some external system. Nowadays HTTP became de facto a lingua-franca for this kind of tasks.
In this article we will demonstrate how to use RestRserve to build a basic REST API.
Workflow overview
Generally RestRserve workflow consists of several major steps:
Create application with
Application$new()Create a function which follows RestRserve API:
should take 2 arguments -
requestandresponseas an input.requestandresponseare instances ofRestRserve::RequestandRestRserve::Response. It is important to remember that bothrequestandresponseare mutable objects.should modify
responsein place orraise()exception in case of error
Register this function as a handler for an endpoint
Start application
1. Create application
library(RestRserve) app = Application$new()
2. Define logic
For simplicity we will use Fibonacci number calculation as an algorithm we want to expose.
calc_fib = function(n) {
if (n < 0L) stop("n should be >= 0")
if (n == 0L) return(0L)
if (n == 1L || n == 2L) return(1L)
x = rep(1L, n)
for (i in 3L:n) {
x[[i]] = x[[i - 1]] + x[[i - 2]]
}
return(x[[n]])
}
Create function which will handle requests.
fib_handler = function(.req, .res) {
n = as.integer(.req$parameters_query[["n"]])
if (length(n) == 0L || is.na(n)) {
raise(HTTPError$bad_request())
}
.res$set_body(as.character(calc_fib(n)))
.res$set_content_type("text/plain")
}
You may have noticed strange .req and .res argument names. Starting
from RestRserve v0.4.0 these “reserved” names allows to benefit from
autocomplete:
<img src=“https://s3.eu-west-1.amazonaws.com/cdn.rexy.ai/assets/req-res.gif” width=“640” style=“vertical-align:bottom”, alt=“request-response autocomplete gif”>
Technically .req and .res are just empty instances of ?Request and
?Response classes exported by RestRserve in order to make
autocomplete work.
2. Register endpoint
app$add_get(path = "/fib", FUN = fib_handler)
3. Test endpoints
Now we can test our application without starting it:
request = Request$new(path = "/fib", parameters_query = list(n = 10))
response = app$process_request(request)
cat("Response status:", response$status)
#> Response status: 200 OK
cat("Response body:", response$body)
#> Response body: 55
It is generally a good idea to write unit tests against application. One can use a common framework such as tinytest.
4. Add OpenAPI description and Swagger UI
Generally it is a good idea to provide documentation along with the API. Convenient way to do that is to supply a openapi specification. This as simple as adding a yaml file as an additional endpoint:
openapi: 3.0.1
info:
title: RestRserve OpenAPI
version: '1.0'
servers:
- url: /
paths:
/fib:
get:
description: Calculates Fibonacci number
parameters:
- name: "n"
description: "x for Fibonnacci number"
in: query
schema:
type: integer
example: 10
required: true
responses:
200:
description: API response
content:
text/plain:
schema:
type: string
example: 5
400:
description: Bad Request
yaml_file = system.file("examples", "openapi", "openapi.yaml", package = "RestRserve")
app$add_openapi(path = "/openapi.yaml", file_path = yaml_file)
app$add_swagger_ui(path = "/doc", path_openapi = "/openapi.yaml", use_cdn = TRUE)
5. Start the app
Now all is ready and we can start application with Rserve backend. It will block R session and start listening for incoming requests.
backend = BackendRserve$new() backend$start(app, http_port = 8080)
6. Test it
Send request to calculate fibonacci number:
curl localhost:8080/fib?n=10
Check out a swagger UI in the browser: http://localhost:8080/doc
Author(s)
Maintainer: Dmitry Selivanov selivanov.dmitriy@gmail.com (ORCID)
Authors:
Artem Klevtsov a.a.klevtsov@gmail.com (ORCID)
Other contributors:
David Zimmermann david_j_zimmermann@hotmail.com [contributor]
rexy.ai [copyright holder, funder]
See Also
Useful links:
Report bugs at https://github.com/rexyai/RestRserve/issues
Creates application - RestRserve usage starts from here
Description
Creates Application object. Application provides an interface for building high-performance REST API by registering R functions as handlers http requests.
Details
There are several advanced options to control how HTTP headers are processed:
-
options("RestRserve.headers.server")controls response"Server"header -
options("RestRserve.headers.split")controls which header values split by comma during parsing. See https://en.wikipedia.org/wiki/List_of_HTTP_header_fields, https://stackoverflow.com/a/29550711/3048453
There is also an option to switch-off runtime types validation in
the Request/Response handlers. This might provide some performance gains,
but ultimately leads to less robust applications. Use at your own risk!
See options("RestRserve.runtime.asserts")
Public fields
loggerLogger object which records events during request processing. Alternatively user can use loggers from lgr package as a drop-in replacement -
Loggermethods and loggers created bylgrshare function signatures.content_typeDefault response body content type.
HTTPErrorClass which raises HTTP errors. Global HTTPError is used by default. In theory user can replace it with his own class (see
RestRserve:::HTTPErrorFactory). However we believe in the majority of the cases using HTTPError will be enough.
Active bindings
endpointsPrints all the registered routes with allowed methods.
Methods
Public methods
Method new()
Creates Application object.
Usage
Application$new( middleware = list(EncodeDecodeMiddleware$new()), content_type = "text/plain", ... )
Arguments
middlewareList of Middleware objects.
content_typeDefault response body content (media) type.
"text/plain"by default....Not used at the moment.
Method add_route()
Adds endpoint and register user-supplied R function as a handler.
Usage
Application$add_route(
path,
method,
FUN,
match = c("exact", "partial", "regex"),
...
)Arguments
pathEndpoint path.
methodHTTP method. Allowed methods at the moment:
GET,HEAD,POST,PUT,DELETE,OPTIONS,PATCH.FUNUser function to handle requests.
FUNmust take two arguments: first isrequest(Request) and second isresponse(Response).
The goal of the user function is to modifyresponseor throw exception (callraise()orstop()).
Bothresponseandrequestobjects modified in-place and internally passed further to RestRserve execution pipeline.matchDefines how route will be processed. Allowed values:
-
exact- match route as is. Returns 404 if route is not matched. -
partial- match route as prefix. Returns 404 if prefix are not matched. -
regex- match route as template. Returns 404 if template pattern not matched.
-
...Not used.
Method add_get()
Shorthand to Application$add_route() with GET method.
Usage
Application$add_get(
path,
FUN,
match = c("exact", "partial", "regex"),
...,
add_head = TRUE
)Arguments
pathEndpoint path.
FUNUser function to handle requests.
FUNmust take two arguments: first isrequest(Request) and second isresponse(Response).
The goal of the user function is to modifyresponseor throw exception (callraise()orstop()).
Bothresponseandrequestobjects modified in-place and internally passed further to RestRserve execution pipeline.matchDefines how route will be processed. Allowed values:
-
exact- match route as is. Returns 404 if route is not matched. -
partial- match route as prefix. Returns 404 if prefix are not matched. -
regex- match route as template. Returns 404 if template pattern not matched.
-
...Not used.
add_headAdds HEAD method.
Method add_post()
Shorthand to Application$add_route() with POST method.
Usage
Application$add_post(path, FUN, match = c("exact", "partial", "regex"), ...)Arguments
pathEndpoint path.
FUNUser function to handle requests.
FUNmust take two arguments: first isrequest(Request) and second isresponse(Response).
The goal of the user function is to modifyresponseor throw exception (callraise()orstop()).
Bothresponseandrequestobjects modified in-place and internally passed further to RestRserve execution pipeline.matchDefines how route will be processed. Allowed values:
-
exact- match route as is. Returns 404 if route is not matched. -
partial- match route as prefix. Returns 404 if prefix are not matched. -
regex- match route as template. Returns 404 if template pattern not matched.
-
...Not used.
Method add_static()
Adds GET method to serve file or directory at file_path.
Usage
Application$add_static(path, file_path, content_type = NULL, ...)
Arguments
pathEndpoint path.
file_pathPath file or directory.
content_typeMIME-type for the content.
Ifcontent_type = NULLthen MIME codecontent_typewill be inferred automatically (from file extension).
If it will be impossible to guess about file type thencontent_typewill be set toapplication/octet-stream....Not used.
Method add_openapi()
Adds endpoint to serve OpenAPI description of available methods.
Usage
Application$add_openapi(path = "/openapi.yaml", file_path = "openapi.yaml")
Arguments
pathpath Endpoint path.
file_pathPath to the OpenAPI specification file.
Method add_swagger_ui()
Adds endpoint to show Swagger UI.
Usage
Application$add_swagger_ui( path = "/swagger", path_openapi = "/openapi.yaml", use_cdn = TRUE, path_swagger_assets = "/__swagger__/", file_path = "swagger-ui.html" )
Arguments
pathpath Endpoint path.
path_openapiPath to the OpenAPI specification file.
use_cdnUse CDN to load Swagger UI libraries.
path_swagger_assetsSwagger UI asstes endpoint.
file_pathPath to Swagger UI HTML file.
Method append_middleware()
Appends middleware to handlers pipeline.
Usage
Application$append_middleware(mw)
Arguments
mwMiddleware object.
Method process_request()
Process incoming request and generate Response object.
Usage
Application$process_request(request = NULL)
Arguments
requestRequest object.
Useful for tests your handlers before deploy application.
Method print()
Prints application details.
Usage
Application$print()
Method clone()
The objects of this class are cloneable with this method.
Usage
Application$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
HTTPError Middleware Request Response
Examples
# init logger
app_logger = Logger$new()
# set log level for the middleware
app_logger$set_log_level("debug")
# set logger name
app_logger$set_name("MW Logger")
# init middleware to logging
mw = Middleware$new(
process_request = function(rq, rs) {
app_logger$info(sprintf("Incomming request (id %s): %s", rq$id, rq$path))
},
process_response = function(rq, rs) {
app_logger$info(sprintf("Outgoing response (id %s): %s", rq$id, rs$status))
},
id = "awesome-app-logger"
)
# init application
app = Application$new(middleware = list(mw))
# set internal log level
app$logger$set_log_level("error")
# define simply request handler
status_handler = function(rq, rs) {
rs$set_body("OK")
rs$set_content_type("text/plain")
rs$set_status_code(200L)
}
# add route
app$add_get("/status", status_handler, "exact")
# add static file handler
desc_file = system.file("DESCRIPTION", package = "RestRserve")
# add route
app$add_static("/desc", desc_file, "text/plain")
# define say message handler
say_handler = function(rq, rs) {
who = rq$parameters_path[["user"]]
msg = rq$parameters_query[["message"]]
if (is.null(msg)) msg = "Hello"
rs$set_body(paste(who, "say", dQuote(msg)))
rs$set_content_type("text/plain")
rs$set_status_code(200L)
}
# add route
app$add_get("/say/{user}", say_handler, "regex")
# print application info
app
# test app
# simulate requests
not_found_rq = Request$new(path = "/no")
status_rq = Request$new(path = "/status")
desc_rq = Request$new(path = "/desc")
say_rq = Request$new(path = "/say/anonym", parameters_query = list("message" = "Hola"))
# process prepared requests
app$process_request(not_found_rq)
app$process_request(status_rq)
app$process_request(desc_rq)
app$process_request(say_rq)
# run app
backend = BackendRserve$new()
if (interactive()) {
backend$start(app, 8080)
}
Creates ApplicationProcess object
Description
Creates ApplicationProcess to hold PID of the running application.
Public fields
pidProcess identificator.
Methods
Public methods
Method new()
Creates ApplicationProcess object
Usage
ApplicationProcess$new(pid)
Arguments
pidProcess identificator.
Method kill()
Send signal to process.
Usage
ApplicationProcess$kill(signal = 15L)
Arguments
signalSignal code.
Method clone()
The objects of this class are cloneable with this method.
Usage
ApplicationProcess$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Create AuthBackend
Description
Creates AuthBackend class object.
Public fields
HTTPErrorClass which raises HTTP errors.
Methods
Public methods
Method new()
Creates AuthBackend class object.
Usage
AuthBackend$new(FUN, auth_header_prefix)
Arguments
FUNAuthentication handler function.
auth_header_prefixAuthentication HTTP header prefix.
Method authenticate()
This placeholder. It must be implemented in the subclass.
Usage
AuthBackend$authenticate()
Method clone()
The objects of this class are cloneable with this method.
Usage
AuthBackend$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Note
This object is typically constructed via a derived classes, e.g. AuthBackendBasic or AuthBackendBearer.
References
See Also
Other AuthBackend:
AuthBackendBasic,
AuthBackendBearer,
AuthMiddleware
Basic authorization backend
Description
Creates AuthBackendBasic class object.
Super class
RestRserve::AuthBackend -> AuthBackendBasic
Methods
Public methods
Method new()
Creates AuthBackendBasic class object.
Usage
AuthBackendBasic$new(FUN)
Arguments
FUNFunction to perform authentication which takes two arguments -
userandpassword. Returns boolean - whether access is allowed for a requesteduseror not.
Method authenticate()
Provide authentication for the given request.
Usage
AuthBackendBasic$authenticate(request, response)
Arguments
Returns
Boolean - whether access is allowed for a requested user or not.
Method clone()
The objects of this class are cloneable with this method.
Usage
AuthBackendBasic$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
References
See Also
AuthMiddleware Request Response
Other AuthBackend:
AuthBackend,
AuthBackendBearer,
AuthMiddleware
Examples
# init users database
user_db = list(
"user-1" = "password-1",
"user-2" = "password-2"
)
# define authentication handler
auth_fun = function(user, password) {
if (is.null(user_db[[user]])) return(FALSE) # not found
if (!identical(user_db[[user]], password)) return(FALSE) # incorrect
return(TRUE)
}
# init backend
auth_backend = AuthBackendBasic$new(FUN = auth_fun)
# test backend
# define credentials (see RFC)
creds = jsonlite::base64_enc("user-1:password-1")
# generate request headers
h = list("Authorization" = sprintf("Basic %s", creds))
# simulate request
rq = Request$new(path = "/", headers = h)
# init response object
rs = Response$new()
# perform authentication
auth_backend$authenticate(rq, rs) # TRUE
Bearer token authorization backend
Description
Creates AuthBackendBearer class object.
Super class
RestRserve::AuthBackend -> AuthBackendBearer
Methods
Public methods
Method new()
Creates AuthBackendBearer class object.
Usage
AuthBackendBearer$new(FUN)
Arguments
FUNFunction to perform authentication which takes one arguments -
token. Returns boolean - whether access is allowed for a requestedtokenor not.
Method authenticate()
Provide authentication for the given request.
Usage
AuthBackendBearer$authenticate(request, response)
Arguments
Returns
Boolean - whether access is allowed for a requested user or not.
Method clone()
The objects of this class are cloneable with this method.
Usage
AuthBackendBearer$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
References
See Also
AuthMiddleware Request Response
Other AuthBackend:
AuthBackend,
AuthBackendBasic,
AuthMiddleware
Examples
token_db = list(
"valid-token" = as.POSIXct("2099-12-31", tz = "GMT"),
"expired-token" = as.POSIXct("1900-01-01", tz = "GMT")
)
auth_fun = function(token) {
if (is.null(token_db[[token]])) return(FALSE) # not found
if (Sys.time() > token_db[[token]]) return(FALSE) # expired
return(TRUE)
}
# init backend
auth_backend = AuthBackendBearer$new(FUN = auth_fun)
# test backend
# define credentials (see RFC)
token = "valid-token"
# generate request headers
h = list("Authorization" = sprintf("Bearer %s", token))
# simulate request
rq = Request$new(path = "/", headers = h)
# init response object
rs = Response$new()
# perform authentication
auth_backend$authenticate(rq, rs) # TRUE
Creates authorization middleware object
Description
Adds various authorizations to Application.
Super class
RestRserve::Middleware -> AuthMiddleware
Methods
Public methods
Method new()
Creeates AuthMiddleware object.
Usage
AuthMiddleware$new( auth_backend, routes, match = "exact", id = "AuthMiddleware" )
Arguments
auth_backendAuthentication backend.
routesRoutes paths to protect.
matchHow routes will be matched:
"exact"or"partial"(as prefix).idMiddleware id.
Method clone()
The objects of this class are cloneable with this method.
Usage
AuthMiddleware$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
Other AuthBackend:
AuthBackend,
AuthBackendBasic,
AuthBackendBearer
Creates Backend object
Description
Creates Backend object.
Methods
Public methods
Method new()
Creates Backend object.
Usage
Backend$new()
Method start()
Starts backend.
Usage
Backend$start(app, port, ...)
Arguments
appApplication object.
portHTTP port.
...Passed to backend.
Method clone()
The objects of this class are cloneable with this method.
Usage
Backend$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Creates Rserve backend for processing HTTP requests
Description
Creates BackendRserve object which can start Application using Rserve backend.
Super class
RestRserve::Backend -> BackendRserve
Methods
Public methods
Method new()
Creates BackendRserve object.
Usage
BackendRserve$new(..., jit_level = 0L, precompile = FALSE)
Arguments
...Not used at the moment.
jit_levelchanges R's byte compiler level to this value before app start.
precompiletry to use R's byte compiler to pre-compile
Method start()
Starts RestRserve application from current R session.
Usage
BackendRserve$start(app, http_port = 8080, ..., background = FALSE)
Arguments
appApplication object.
http_portHTTP port for application. Negative values (such as -1) means not to expose plain http.
...Key-value pairs of the Rserve configuration. If contains
"http.port"thenhttp_portwill be silently replaced with its value.backgroundWhether to try to launch in background process on UNIX.
Returns
ApplicationProcess object when background = TRUE.
Method set_request()
Parse request and set to it fields.
Usage
BackendRserve$set_request( request, path = "/", parameters_query = NULL, headers = NULL, body = NULL )
Arguments
requestRequest object.
pathCharacter with requested path. Always starts with
/.parameters_queryA named character vector with URL decoded query parameters.
headersRequest HTTP headers.
bodyRequest body. Can be
NULL, raw vector or named character vector for the URL encoded form (like aparameters_queryparameter).
Returns
request modified object.
Method convert_response()
Convert self object to Rserve compatible structure.
Usage
BackendRserve$convert_response(response)
Arguments
responseResponse object.
Returns
List with the following structure:
-
body: can be a character vector of length one or a raw vector. if the character vector is named "file" then the content of a file of that name is the body. If the character vector is named "tmpfile" then the content of a temporary file of that name is the body. -
content-type: must be a character vector of length one or NULL (if present, else default is"text/plain"). -
headers: must be a character vector - the elements will have CRLF appended and neitherContent-typenorContent-lengthmay be used. -
status-code: must be an integer if present (default is 200).
Method clone()
The objects of this class are cloneable with this method.
Usage
BackendRserve$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
References
Creates CORS middleware object
Description
Adds CORS to Application. CORS Middleware out of the box in RestRserve to turn on/off the CORS
Headers on preflight validation from the browser.
Cross Origin Resource Sharing is an additional security check done by moderns
browsers to avoid request between different domains. To allow it RestRserve
has easy way to enable your CORS policies. By default CORS policies are disabled.
So if any request is coming from a different domain will be blocked
by the browser as default because RestRserve will not send the headers required
by the browser to allow cross site resource sharing. You can change this easy
just by providing CORSMiddleware as middleware to the Application.
Super class
RestRserve::Middleware -> CORSMiddleware
Methods
Public methods
Method new()
Creates CORS middleware object
Usage
CORSMiddleware$new(routes = "/", match = "partial", id = "CORSMiddleware")
Arguments
routesRoutes paths to protect.
matchHow routes will be matched: exact or partial (as prefix).
idMiddleware id.
Method clone()
The objects of this class are cloneable with this method.
Usage
CORSMiddleware$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
References
See Also
Examples
app = Application$new(middleware = list(CORSMiddleware$new()))
app$add_post(path = "/hello", FUN = function(req, res) {
res$set_body("Hello from RestRserve!")
})
app$add_route("/hello", method = "OPTIONS", FUN = function(req, res) {
res$set_header("Allow", "POST, OPTIONS")
})
req = Request$new(
path = "/hello",
headers = list("Access-Control-Request-Method" = "POST"),
method = "OPTIONS"
)
app$process_request(req)
Content handlers collection
Description
Controls how RestRserve encodes and decodes different content types. Designed to work jointly with EncodeDecodeMiddleware
Public fields
handlersHandlers storage environment.
Methods
Public methods
Method new()
Creates ContentHandlersFactory object.
Usage
ContentHandlersFactory$new()
Method set_encode()
Set handler to encode body for the specific content type.
Usage
ContentHandlersFactory$set_encode(content_type, FUN)
Arguments
content_typeMIME type.
FUNFunction to encode response body.
Method get_encode()
Get encoder function for the specific content type.
Usage
ContentHandlersFactory$get_encode(content_type)
Arguments
content_typeMIME type.
Method set_decode()
Set handler to decode body for the specific content type.
Usage
ContentHandlersFactory$set_decode(content_type, FUN)
Arguments
content_typeMIME type.
FUNFunction to decode request body.
Method get_decode()
Get decoder function for the specific content type.
Usage
ContentHandlersFactory$get_decode(content_type)
Arguments
content_typeMIME type.
Method list()
Convert handlers to list.
Usage
ContentHandlersFactory$list()
Returns
List of handlers.
Method reset()
Resets all the content handlers to RestRserve defaults.
Usage
ContentHandlersFactory$reset()
Method clone()
The objects of this class are cloneable with this method.
Usage
ContentHandlersFactory$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
Application EncodeDecodeMiddleware
Creates ETag middleware object
Description
Adds ETag to an Application.
ETags are header information that enable the caching of content.
If enabled, RestRserve will return an ETag (eg a hash of a file) alongside
the last time it was modified.
When a request is sent, additional headers such as
If-None-Match,
If-Match,
If-Modified-Since,
and
If-Unmodified-Since,
can be passed to the server as well.
If the conditions are met (different hash in case of a If-None-Match header
or a later file modification in case of a given If-Modified-Since header),
the server does not send the requested file but returns a
304 status
code, indicating, that the data on the requesting device is up-to-date.
Note that if both headers are provided, the If-None-Match header takes
precedence.
Furthermore, the middleware also supports the headers If-Match, which
returns the object if the hash matches (it also supports "*" to always return
the file), as well as If-Unmodified-Since, which returns the object if it
has not been modified since a certain time.
If the conditions are not met, a
412 status
code is returned (Precondition Failed).
See examples below.
Super class
RestRserve::Middleware -> EtagMiddleware
Public fields
hash_functionFunction that takes an object or file and computes the hash of it
last_modified_functionFunction that takes an object or file and computes the last time it was modified
Methods
Public methods
Method new()
Creates ETag middleware object
Usage
ETagMiddleware$new(
routes = "/",
match = "partial",
id = "ETagMiddleware",
hash_function = function(body) {
if ("file" %in% names(body)) {
digest::digest(file = body[["file"]], algo = "crc32")
}
else {
digest::digest(body, algo = "crc32")
}
},
last_modified_function = function(body) {
if ("file" %in% names(body)) {
as.POSIXlt(file.info(body[["file"]])[["mtime"]], tz = "GMT")
}
else {
as.POSIXlt(Sys.time(), tz = "GMT")
}
}
)Arguments
routesRoutes paths to protect.
matchHow routes will be matched: exact or partial (as prefix).
idMiddleware id.
hash_functiona function that generates the ETag hash. The function takes the body of the response and returns a single character. Default is crc32 using digest::digest.
last_modified_functiona function that takes the body of the response and returns the last time this was changed. The default is to take the mtime (last time the file was modified) if its a file, if the body does not contain a file, the current time is returned ( resulting in no caching)
Method clone()
The objects of this class are cloneable with this method.
Usage
ETagMiddleware$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
References
See Also
Examples
#############################################################################
# setup a static directory with ETag caching
static_dir = file.path(tempdir(), "static")
if (!dir.exists(static_dir)) dir.create(static_dir)
file_path = file.path(static_dir, "example.txt")
writeLines("Hello World", file_path)
# get the time the file was last modified in UTC time
last_modified = as.POSIXlt(file.info(file_path)[["mtime"]], tz = "UTC")
file_hash = digest::digest(file = file_path, algo = "crc32")
time_fmt = "%a, %d %b %Y %H:%M:%S GMT"
#############################################################################
# setup the Application with the ETag Middleware
app = Application$new()
app$append_middleware(ETagMiddleware$new())
app$add_static(path = "/", static_dir)
#############################################################################
# Example Requests
# Request the file returns the file with ETag headers
req = Request$new(path = "/example.txt")
# note that it also returns the Last-Modified and ETag headers
app$process_request(req)
# provide matching hash of the file in the If-None-Match header to check Etag
# => 304 Not Modified (Can be cached)
req = Request$new(path = "/example.txt",
headers = list("If-None-Match" = file_hash))
# note status_code 304 Not Modified
app$process_request(req)
# provide a wrong hash, returns the file normally
req = Request$new(path = "/example.txt",
headers = list("If-None-Match" = "WRONG HASH"))
app$process_request(req)
# alternatively, you can provide a timestamp in the If-Modified-Since header
# => 304 Not Modified (Can be cached)
modified_since = format(last_modified + 1, time_fmt)
req = Request$new(path = "/example.txt",
headers = list("If-Modified-Since" = modified_since))
app$process_request(req)
# provide both headers: If-None-Match takes precedence
# in this case:
# - if none match => modified (No cache)
# - if modified since => NOT MODIFIED (cached)
# => Overall: modified = no cache
modified_since = format(last_modified + 1, time_fmt)
req = Request$new(path = "/example.txt",
headers = list("If-None-Match" = "CLEARLY WRONG",
"If-Modified-Since" = modified_since))
app$process_request(req)
# provide matching hash of the file in the If-Match header to check Etag
# => 412 Precondition Failed
req = Request$new(path = "/example.txt",
headers = list("If-Match" = "OTHER HASH"))
# note status_code 412 Precondition Failed
app$process_request(req)
# Use If-Unmodified-Since
unmodified_since = format(last_modified - 1, time_fmt)
req = Request$new(path = "/example.txt",
headers = list("If-Unmodified-Since" = unmodified_since)
)
# note status_code 412 Precondition Failed
app$process_request(req)
#############################################################################
# use an alternative hash function (use name of the file)
hash_on_filename = function(x) x
# also use an alternate last_modified time function
always_1900 = function(x) as.POSIXlt("1900-01-01 12:34:56", tz = "GMT")
# setup the app again
app = Application$new(middleware = list(
ETagMiddleware$new(hash_function = hash_on_filename,
last_modified_function = always_1900)
))
app$add_static(path = "/", file_path = static_dir)
# test the requests
req = Request$new(path = "/example.txt")
(res = app$process_request(req))
filename = res$body[["file"]]
req = Request$new(path = "/example.txt",
headers = list("If-None-Match" = filename))
app$process_request(req)
Creates EncodeDecodeMiddleware middleware object
Description
Controls how RestRserve encodes and decodes different content types. This middleware is passed by default to the Application constructor.
Super class
RestRserve::Middleware -> EncodeDecodeMiddleware
Public fields
ContentHandlersClass which controls how RestRserve encodes and decodes different content types. See ContentHandlers for documentation. User can add new encoding and decoding methods for new content types using
set_encodeandset_decodemethods.
In theory user can replace it with his own class (seeRestRserve:::ContentHandlersFactory). However we believe that in the majority of the cases using ContentHandlers will be enough.
Methods
Public methods
Method new()
Creates EncodeDecodeMiddleware middleware object.
Usage
EncodeDecodeMiddleware$new(id = "EncodeDecodeMiddleware")
Arguments
idMiddleware id.
Method clone()
The objects of this class are cloneable with this method.
Usage
EncodeDecodeMiddleware$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
Middleware Application ContentHandlers
HTTP Date class
Description
Conversions between POSIXct to HTTP Date objects.
Arguments
from |
|
References
Examples
# convert POSIXct to HTTP date string
as(0, "HTTPDate") # Thu, 01 Jan 1970 00:00:00 GMT
as(Sys.time(), "HTTPDate")
# parse HTTP date string to POSIXct
dt = "Thu, 01 Jan 1970 00:00:00 GMT"
class(dt) = "HTTPDate"
as(dt, "POSIXct")
Helps to generate HTTP error responses
Description
Global Object which holds functions to raise common http error responses.
Most of the time this class is used jointly with raise.
For example calling
raise(HTTPError$bad_request(body = "request is invalid")) from any place in the user code will
interrupt request processing and return response with status code = 404 and body = "request is invalid".
Class to generate HTTP error responses.
Usage
HTTPError
Format
An object of class HTTPError (inherits from R6) of length 39.
Functions
-
HTTPErrorFactory:
Public fields
content_typeType of the error response.
encodeFunction to encode response body.
Methods
Public methods
Method new()
Creates HTTPError object.
Usage
HTTPErrorFactory$new(content_type = "text/plain", encode = as.character)
Arguments
content_typeType of the error response.
encodeFunction to encode response body.
Method set_content_type()
Set content type of response.
Usage
HTTPErrorFactory$set_content_type(content_type)
Arguments
content_typeType of the error response.
Details
Modifying HTTPError will have global impact on RestRserve functionality.
By default HTTPError is used by Application in order to produce http
errors (404, 500, etc). Hence changing HTTPError with
HTTPErrorFactory$set_content_type() will impact not only user code, but
also the errors format produced by RestRserve. Same holds for
HTTPErrorFactory$set_encode() method below.
Method set_encode()
Set encode for the given content type.
Usage
HTTPErrorFactory$set_encode(encode)
Arguments
encodeFunction to encode response body.
Method reset()
Resets HTTPError to the default RestRserve state.
Usage
HTTPErrorFactory$reset()
Method error()
Generate HTTP error response with a given status code and body.
Usage
HTTPErrorFactory$error(status_code, body = NULL, ...)
Arguments
status_codeHTTP status code.
bodyResponse body.
...Additional named arguments which will be passed to
Response$new().headersmay be particularly useful.
Returns
Response object.
Method bad_request()
Generates corresponding http error.
Usage
HTTPErrorFactory$bad_request(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method unauthorized()
Generates corresponding http error.
Usage
HTTPErrorFactory$unauthorized(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method forbidden()
Generates corresponding http error.
Usage
HTTPErrorFactory$forbidden(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method not_found()
Generates corresponding http error.
Usage
HTTPErrorFactory$not_found(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method method_not_allowed()
Generates corresponding http error.
Usage
HTTPErrorFactory$method_not_allowed(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method not_acceptable()
Generates corresponding http error.
Usage
HTTPErrorFactory$not_acceptable(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method conflict()
Generates corresponding http error.
Usage
HTTPErrorFactory$conflict(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method gone()
Generates corresponding http error.
Usage
HTTPErrorFactory$gone(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method length_required()
Generates corresponding http error.
Usage
HTTPErrorFactory$length_required(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method precondition_failed()
Generates corresponding http error.
Usage
HTTPErrorFactory$precondition_failed(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method payload_too_large()
Generates corresponding http error.
Usage
HTTPErrorFactory$payload_too_large(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method uri_too_long()
Generates corresponding http error.
Usage
HTTPErrorFactory$uri_too_long(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method unsupported_media_type()
Generates corresponding http error.
Usage
HTTPErrorFactory$unsupported_media_type(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method range_not_satisfiable()
Generates corresponding http error.
Usage
HTTPErrorFactory$range_not_satisfiable(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method unprocessable_entity()
Generates corresponding http error.
Usage
HTTPErrorFactory$unprocessable_entity(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method locked()
Generates corresponding http error.
Usage
HTTPErrorFactory$locked(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method failed_dependency()
Generates corresponding http error.
Usage
HTTPErrorFactory$failed_dependency(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method precondition_required()
Generates corresponding http error.
Usage
HTTPErrorFactory$precondition_required(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method too_many_requests()
Generates corresponding http error.
Usage
HTTPErrorFactory$too_many_requests(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method request_header_fields_too_large()
Generates corresponding http error.
Usage
HTTPErrorFactory$request_header_fields_too_large(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method unavailable_for_legal_reasons()
Generates corresponding http error.
Usage
HTTPErrorFactory$unavailable_for_legal_reasons(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method internal_server_error()
Generates corresponding http error.
Usage
HTTPErrorFactory$internal_server_error(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method not_implemented()
Generates corresponding http error.
Usage
HTTPErrorFactory$not_implemented(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method bad_gateway()
Generates corresponding http error.
Usage
HTTPErrorFactory$bad_gateway(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method service_unavailable()
Generates corresponding http error.
Usage
HTTPErrorFactory$service_unavailable(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method gateway_timeout()
Generates corresponding http error.
Usage
HTTPErrorFactory$gateway_timeout(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method version_not_supported()
Generates corresponding http error.
Usage
HTTPErrorFactory$version_not_supported(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method insufficient_storage()
Generates corresponding http error.
Usage
HTTPErrorFactory$insufficient_storage(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method loop_detected()
Generates corresponding http error.
Usage
HTTPErrorFactory$loop_detected(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method network_authentication_required()
Generates corresponding http error.
Usage
HTTPErrorFactory$network_authentication_required(...)
Arguments
...Additional named arguments which will be passed to
Response$new().
Returns
Response object.
Method clone()
The objects of this class are cloneable with this method.
Usage
HTTPErrorFactory$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
Examples
check_list = function(x) {
if (!is.list(x)) raise(HTTPError$bad_request())
invisible(TRUE)
}
check_list(list())
try(check_list(1), silent = TRUE)
request and reponse placeholders for IDE hints
Description
request and reponse placeholders for IDE hints
Usage
.req
.res
Format
An object of class Request (inherits from R6) of length 28.
An object of class Response (inherits from R6) of length 26.
See Also
Examples
library(RestRserve)
app = Application$new()
app$add_get("/foo", FUN = function(.req, .res) {
# since .res is a dummy instance of Response class
# exported by RestRserve
# IDE facilitates with autocompletion!
.res$set_body("bar")
# in the same time all the modifications happen with local objects
# so you get right results in the end
})
response = app$process_request(Request$new(path = "/foo"))
response$body
Simple logging utility
Description
Creates Logger object which can be used for logging with different level of verbosity. Log messages are in JSON format.
Methods
Public methods
Method new()
Creates Logger object.
Usage
Logger$new(
level = c("info", "fatal", "error", "warn", "debug", "trace", "off", "all"),
name = "ROOT",
printer = NULL
)Arguments
levelLog level. Allowed values: info, fatal, error, warn, debug, trace, off, all.
nameLogger name.
printerLogger with sink defined by
printerfunction. It should have signaturefunction(timestamp, level, logger_name, pid, message). By default whenprinter = NULLlogger writes message in JSON format tostdout.
Method set_name()
Sets logger name.
Usage
Logger$set_name(name = "ROOT")
Arguments
nameLogger name.
Method set_log_level()
Sets log level.
Usage
Logger$set_log_level(
level = c("info", "fatal", "error", "warn", "debug", "trace", "off", "all")
)Arguments
levelLog level. Allowed values: info, fatal, error, warn, debug, trace, off, all.
Method set_printer()
Sets function which defines how to print logs.
Usage
Logger$set_printer(FUN = NULL)
Arguments
FUNPrinter function. Should be a function with 6 formal arguments: timestamp, level, logger_name, pid, message.
Method trace()
Write trace message.
Usage
Logger$trace(msg, ...)
Arguments
msgLog message.
...Additionals params.
Method debug()
Write debug message.
Usage
Logger$debug(msg, ...)
Arguments
msgLog message.
...Additionals params.
Method info()
Write information message.
Usage
Logger$info(msg, ...)
Arguments
msgLog message.
...Additionals params.
Method warn()
Write warning message.
Usage
Logger$warn(msg, ...)
Arguments
msgLog message.
...Additionals params.
Method error()
Write error message.
Usage
Logger$error(msg, ...)
Arguments
msgLog message.
...Additionals params.
Method fatal()
Write fatal error message.
Usage
Logger$fatal(msg, ...)
Arguments
msgLog message.
...Additionals params.
Method clone()
The objects of this class are cloneable with this method.
Usage
Logger$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
Examples
# init logger
logger = Logger$new("info")
# write info message
logger$info("hello world")
# write extended log entry
logger$info("", context = list(message = "hello world", code = 0L))
Creates middleware object
Description
Creates Middleware object.
Middleware is a very useful concept which allows to perform
preprocessing of requests and post-processing of responses. Middleware has
an access to both request and response objects and can modify them.
This way each request can be checked/modified before passing handler and
response can be post processed (for example this way we developer can set up
custom error messages).
Public fields
process_requestFunction which takes 2 arguments -
requestandresponseobjects (class Request and Response correspondingly) and modifyrequestandresponseor throw exception using HTTPError helper.
Function is called before request is routed to handler.
Usuallyprocess_requestis used to perform logging, check authorization, etc.process_responseFunction which takes 2 arguments -
requestandresponseobjects (class Request and Response correspondingly) and modifyrequestandresponseor throw exception using HTTPError helper.
Function is called after request is processed by handler. Usuallyprocess_responseis used to perform logging, custom error handling, etc.idMiddleware id.
Methods
Public methods
Method new()
Creates middleware object
Usage
Middleware$new( process_request = function(request, response) TRUE, process_response = function(request, response) TRUE, id = "Middleware" )
Arguments
process_requestModify
requestorresponseobjects or throw exception using[HTTPError]helper. This function evaluate before router handler called.process_responseModify
requestorresponseobjects or throw exception using[HTTPError]helper. This function evaluate after router handler called.idMiddleware id.
Method clone()
The objects of this class are cloneable with this method.
Usage
Middleware$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
Creates Request object
Description
Called internally for handling incoming requests from Rserve side. Also useful for testing.
Public fields
pathRequest path.
methodRequest HTTP method.
headersRequest headers.
cookiesRequest cookies.
contextEnvironment to store any data. Can be used in middlewares.
content_typeRequest body content type.
bodyRequest body.
parameters_queryRequest query parameters.
parameters_bodyRequest body parameters.
parameters_pathList of parameters extracted from templated path after routing. For example if we have some handler listening at
/job/{job_id}and we are receiving request at/job/1thenparameters_pathwill belist(job_id = "1").
It is important to understand thatparameters_pathwill be available (not empty) only after request will reach handler.
This effectively means thatparameters_pathcan be used inside handler and response middleware (but not request middleware!).filesStructure which contains positions and lengths of files for the multipart body.
decodeFunction to decode body for the specific content type.
Active bindings
idAutomatically generated UUID for each request. Read only.
dateRequest
Dateheader converted toPOSIXct.acceptSplitted
Acceptrequest header.accept_jsonRequest accepts JSON response.
accept_xmlRequest accepts XML response.
Methods
Public methods
Method new()
Creates Request object
Usage
Request$new(
path = "/",
method = c("GET", "HEAD", "POST", "PUT", "DELETE", "CONNECT", "OPTIONS", "TRACE",
"PATCH"),
parameters_query = list(),
parameters_body = list(),
headers = list(),
body = NULL,
cookies = list(),
content_type = NULL,
decode = NULL,
...
)Arguments
pathCharacter with requested path. Always starts with
/.methodRequest HTTP method.
parameters_queryA named list with URL decoded query parameters.
parameters_bodyA named list with URL decoded body parameters. This field is helpful when request is a urlencoded form or a multipart form.
headersRequest HTTP headers represented as named list.
bodyRequest body. Can be anything and in conjunction with
content_typedefines how HTTP body will be represented.cookiesCookies represented as named list. Note that cookies should be provided explicitly - they won't be derived from
headers.content_typeHTTP content type. Note that
content_typeshould be provided explicitly - it won't be derived fromheaders.decodeFunction to decode body for the specific content type.
...Not used at this moment.
Method set_id()
Set request id.
Usage
Request$set_id(id = uuid::UUIDgenerate(TRUE))
Arguments
idRequest id.
Method reset()
Resets request object. This is not useful for end user, but useful for RestRserve internals - resetting R6 class is much faster then initialize it.
Usage
Request$reset()
Method get_header()
Get HTTP response header value. If requested header is empty returns default.
Usage
Request$get_header(name, default = NULL)
Arguments
nameHeader field name.
defaultDefault value if header does not exists.
Returns
Header field values (character string).
Method get_param_query()
Get request query parameter by name.
Usage
Request$get_param_query(name)
Arguments
nameQuery parameter name.
Returns
Query parameter value (character string).
Method get_param_body()
Get request body parameter by name.
Usage
Request$get_param_body(name)
Arguments
nameBody field name.
Returns
Body field value.
Method get_param_path()
Get templated path parameter by name.
Usage
Request$get_param_path(name)
Arguments
namePath parameter name.
Returns
Path parameter value.
Method get_file()
Extract specific file from multipart body.
Usage
Request$get_file(name)
Arguments
nameBody file name.
Returns
Raw vector with filname and content-type attributes.
Method print()
Print method.
Usage
Request$print()
Method clone()
The objects of this class are cloneable with this method.
Usage
Request$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
Examples
# init simply request
rq = Request$new(
path = "/",
parameters_query = list(
"param1" = "value1",
"param2" = "value2"
),
headers = list(
"Content-encoding" = "identity",
"Custom-field" = "value"
),
cookies = list(
"sessionId" = "1"
)
)
# get request UUID
rq$id
# get content accept
rq$accept
# get request content type
rq$content_type
# get header by name (lower case)
rq$get_header("custom-field")
# get query param by name
rq$get_param_query("param1")
# print request
rq
Creates Response object
Description
Creates response object.
Public fields
bodyResponse body.
If it is a named character with a namefileortmpfilethen the value is considered as a path to a file and content oh this file is served as body. The latter will be deleted once served.content_typeResponse body content (media) type. Will be translated to
Content-typeheader.headersResponse headers.
status_codeResponse HTTP status code.
cookiesResponse cookies. Will be translated to
Set-Cookieheaders.contextEnvironment to store any data. Can be used in middlewares.
encodeFunction to encode body for specific content.
Active bindings
statusPaste together status code and description.
Methods
Public methods
Method new()
Creates Response object
Usage
Response$new(
body = NULL,
content_type = "text/plain",
headers = list(Server = getOption("RestRserve.headers.server")),
status_code = 200L,
encode = NULL,
...
)Arguments
bodyResponse body.
content_typeResponse body content (media) type.
headersResponse headers.
status_codeResponse status code.
encodeFunction to encode body for specific content.
...Not used at this moment.
Method reset()
Resets response object. This is not useful for end user, but useful for RestRserve internals - resetting R6 class is much faster then initialize it.
Usage
Response$reset()
Method set_content_type()
Set content type for response body.
Usage
Response$set_content_type(content_type = "text/plain")
Arguments
content_typeResponse body content (media) type.
Method set_status_code()
Set HTTP status code for response. See docs on MDN.
Usage
Response$set_status_code(code)
Arguments
codeStatus code as integer number.
Method has_header()
Determine whether or not the response header exists.
Usage
Response$has_header(name)
Arguments
nameHeader field name.
Returns
Logical value.
Method get_header()
Get HTTP response header value. If requested header is empty returns default.
Usage
Response$get_header(name, default = NULL)
Arguments
nameHeader field name.
defaultDefault value if header does not exists.
Returns
Header field values (character string).
Method set_header()
Set HTTP response header. Content-type and Content-length headers not
allowed (use content_type field instead).
Usage
Response$set_header(name, value)
Arguments
nameHeader field name.
valueHeader field value.
Method delete_header()
Unset HTTP response header.
Usage
Response$delete_header(name)
Arguments
nameHeader field name.
Returns
Logical value.
Method append_header()
Append HTTP response header. If header exists , separator will be used.
Don't use this method to set cookie (use set_cookie method instead).
Usage
Response$append_header(name, value)
Arguments
nameHeader field name.
valueHeader field value.
Method set_date()
Set Date HTTP header. See docs on MDN.
Usage
Response$set_date(dtm = Sys.time())
Arguments
dtmPOSIXct value.
Method unset_date()
Unset Date HTTP header.
Usage
Response$unset_date()
Returns
Logical value.
Method set_cookie()
Set cookie. See docs on MDN.
Usage
Response$set_cookie( name, value, expires = NULL, max_age = NULL, domain = NULL, path = NULL, secure = NULL, http_only = NULL )
Arguments
nameCookie name.
valueCookie value.
expiresCookie expires date and time (POSIXct).
max_ageMax cookie age (integer).
domainCookie domain.
pathCookie path.
secureCookie secure flag.
http_onlyCookie HTTP only flag.
Method unset_cookie()
Unset cookie with given name.
Usage
Response$unset_cookie(name)
Arguments
nameCookie name.
Returns
Logical value.
Method set_body()
Set response body.
Usage
Response$set_body(body)
Arguments
bodyResponse body.
Method set_response()
Set response fields.
Usage
Response$set_response( status_code, body = NULL, content_type = self$content_type )
Arguments
status_codeResponse HTTP status code.
bodyResponse body.
content_typecontent_type Response body content (media) type.
Method print()
Print method.
Usage
Response$print()
Method clone()
The objects of this class are cloneable with this method.
Usage
Response$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
See Also
Examples
# init response
rs = Response$new()
# set body media type
rs$set_content_type("text/plain")
# set body content
rs$set_body("OK")
# set response status code
rs$set_status_code(200L)
# print response
rs
# init response
rs = Response$new()
# static file path
file_path = system.file("DESCRIPTION", package = "RestRserve")
# get last file modification timestamp
file_mtime = file.mtime(file_path)
# set body
rs$set_body(c("file" = file_path))
# set content type
rs$set_content_type("text/plain")
# set current timestamp
rs$set_date()
# set 'last-modified' header
rs$set_header("Last-Modified", as(file_mtime, "HTTPDate"))
# print response
rs
Creates Router object.
Description
Creates Router object.
Public fields
pathsAll added paths as is (with templates placeholders).
Methods
Public methods
Method new()
Creates Router object.
Usage
Router$new()
Method size()
Returns number of paths added before.
Usage
Router$size()
Returns
Number of paths.
Method add_path()
Add path with their id.
Usage
Router$add_path(path, match = c("exact", "partial", "regex"), id)Arguments
pathPath to handle.
matchDefines how route will be processed. Allowed values:
-
exact- match route as is. Returns 404 if route is not matched. -
partial- match route as prefix. Returns 404 if prefix are not matched. -
regex- match route as template. Returns 404 if template pattern not matched.
-
idPath handler id.
Method match_path()
Find path within paths added before. Returns NULL if path not matched.
Usage
Router$match_path(path, extract_vars = TRUE)
Arguments
pathPath endpoint.
extract_varsExtart path parameters (when handler matches regex).
Returns
Handler id.
Method clone()
The objects of this class are cloneable with this method.
Usage
Router$clone(deep = FALSE)
Arguments
deepWhether to make a deep clone.
Examples
r = RestRserve:::Router$new()
r$add_path("/test", "exact", "testid")
r$add_path("/area", "partial", "areaid")
r$add_path("/template/{variable}", "regex", "templateid")
r$match_path("/test") # testid
r$match_path("/area/entry") # areaid
r$match_path("/template/12345") # templateid
attr(r$match_path("/template/12345"), "parameters_path") # variables values
Builds OpenAPI objects
Description
Facilitates in building OpenAPI description document by creating objects described in https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md
Usage
openapi_create(
openapi = openapi_openapi_version(),
info = openapi_info(),
servers = openapi_servers(),
...
)
openapi_openapi_version(openapi_version = "3.0.1")
openapi_info(
title = "RestRserve OpenAPI",
version = "1.0",
description = NULL,
termsOfService = NULL,
contact = openapi_contact(),
license = openapi_license()
)
openapi_servers(servers = list(openapi_server()))
openapi_server(url = "/", description = NULL, variables = NULL)
openapi_contact(name = NULL, url = NULL, email = NULL)
openapi_license(name = NULL, url = NULL)
Arguments
openapi |
string, version of open api. For example |
info |
infoObject - https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#infoObject. See openapi_info |
servers |
serverObject - https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#serverObject See openapi_servers |
... |
other parameters - see https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#oasObject |
openapi_version |
version on OpenAPI |
title |
the title of the application |
version |
version of the application |
description |
description |
termsOfService |
termsOfService of the application |
contact |
contact of the maintainer - see openapi_contact |
license |
license of the api |
url |
url |
variables |
a map between a variable name and its value. #The value is used for substitution in the server's URL template. |
name |
name |
email |
contact email |
Details
https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.1.md#infoObject
Interrupts request processing
Description
Interrupts request processing and signals RestRserve to return HTTPError
Usage
raise(x)
Arguments
x |
instance of Response. Can be created using HTTPError. see examples. |
Value
None - stops execution of the current expression and executes an error action.
See Also
Examples
# catch exception
res = try(raise(HTTPError$bad_request()), silent = TRUE)
cond = attr(res, "condition")
# response is a valid Response instace
identical(cond$response$body$error, "400 Bad Request")
Simple JSON encoder
Description
Encode R objects as JSON. Wrapper around jsonlite::toJSON with
default parameters set to following values:
dataframe = 'columns', auto_unbox = unbox, null = 'null', na = 'null'.
Usage
to_json(x, unbox = TRUE)
Arguments
x |
the object to be encoded |
unbox |
|
Value
JSON string
Examples
to_json(NULL)
to_json(list(name = "value"))