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 -
request
andresponse
as an input.request
andresponse
are instances ofRestRserve::Request
andRestRserve::Response
. It is important to remember that bothrequest
andresponse
are mutable objects.should modify
response
in 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
logger
Logger object which records events during request processing. Alternatively user can use loggers from lgr package as a drop-in replacement -
Logger
methods and loggers created bylgr
share function signatures.content_type
Default response body content type.
HTTPError
Class 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
endpoints
Prints 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
middleware
List of Middleware objects.
content_type
Default 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
path
Endpoint path.
method
HTTP method. Allowed methods at the moment:
GET
,HEAD
,POST
,PUT
,DELETE
,OPTIONS
,PATCH
.FUN
User function to handle requests.
FUN
must take two arguments: first isrequest
(Request) and second isresponse
(Response).
The goal of the user function is to modifyresponse
or throw exception (callraise()
orstop()
).
Bothresponse
andrequest
objects modified in-place and internally passed further to RestRserve execution pipeline.match
Defines 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
path
Endpoint path.
FUN
User function to handle requests.
FUN
must take two arguments: first isrequest
(Request) and second isresponse
(Response).
The goal of the user function is to modifyresponse
or throw exception (callraise()
orstop()
).
Bothresponse
andrequest
objects modified in-place and internally passed further to RestRserve execution pipeline.match
Defines 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_head
Adds 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
path
Endpoint path.
FUN
User function to handle requests.
FUN
must take two arguments: first isrequest
(Request) and second isresponse
(Response).
The goal of the user function is to modifyresponse
or throw exception (callraise()
orstop()
).
Bothresponse
andrequest
objects modified in-place and internally passed further to RestRserve execution pipeline.match
Defines 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
path
Endpoint path.
file_path
Path file or directory.
content_type
MIME-type for the content.
Ifcontent_type = NULL
then MIME codecontent_type
will be inferred automatically (from file extension).
If it will be impossible to guess about file type thencontent_type
will 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
path
path Endpoint path.
file_path
Path 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
path
path Endpoint path.
path_openapi
Path to the OpenAPI specification file.
use_cdn
Use CDN to load Swagger UI libraries.
path_swagger_assets
Swagger UI asstes endpoint.
file_path
Path to Swagger UI HTML file.
Method append_middleware()
Appends middleware to handlers pipeline.
Usage
Application$append_middleware(mw)
Arguments
mw
Middleware object.
Method process_request()
Process incoming request and generate Response object.
Usage
Application$process_request(request = NULL)
Arguments
request
Request 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
deep
Whether 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
pid
Process identificator.
Methods
Public methods
Method new()
Creates ApplicationProcess object
Usage
ApplicationProcess$new(pid)
Arguments
pid
Process identificator.
Method kill()
Send signal to process.
Usage
ApplicationProcess$kill(signal = 15L)
Arguments
signal
Signal code.
Method clone()
The objects of this class are cloneable with this method.
Usage
ApplicationProcess$clone(deep = FALSE)
Arguments
deep
Whether to make a deep clone.
Create AuthBackend
Description
Creates AuthBackend class object.
Public fields
HTTPError
Class which raises HTTP errors.
Methods
Public methods
Method new()
Creates AuthBackend class object.
Usage
AuthBackend$new(FUN, auth_header_prefix)
Arguments
FUN
Authentication handler function.
auth_header_prefix
Authentication 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
deep
Whether 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
FUN
Function to perform authentication which takes two arguments -
user
andpassword
. Returns boolean - whether access is allowed for a requesteduser
or 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
deep
Whether 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
FUN
Function to perform authentication which takes one arguments -
token
. Returns boolean - whether access is allowed for a requestedtoken
or 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
deep
Whether 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_backend
Authentication backend.
routes
Routes paths to protect.
match
How routes will be matched:
"exact"
or"partial"
(as prefix).id
Middleware id.
Method clone()
The objects of this class are cloneable with this method.
Usage
AuthMiddleware$clone(deep = FALSE)
Arguments
deep
Whether 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
app
Application object.
port
HTTP port.
...
Passed to backend.
Method clone()
The objects of this class are cloneable with this method.
Usage
Backend$clone(deep = FALSE)
Arguments
deep
Whether 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_level
changes R's byte compiler level to this value before app start.
precompile
try 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
app
Application object.
http_port
HTTP 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_port
will be silently replaced with its value.background
Whether 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
request
Request object.
path
Character with requested path. Always starts with
/
.parameters_query
A named character vector with URL decoded query parameters.
headers
Request HTTP headers.
body
Request body. Can be
NULL
, raw vector or named character vector for the URL encoded form (like aparameters_query
parameter).
Returns
request
modified object.
Method convert_response()
Convert self
object to Rserve compatible structure.
Usage
BackendRserve$convert_response(response)
Arguments
response
Response 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-type
norContent-length
may 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
deep
Whether 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
routes
Routes paths to protect.
match
How routes will be matched: exact or partial (as prefix).
id
Middleware id.
Method clone()
The objects of this class are cloneable with this method.
Usage
CORSMiddleware$clone(deep = FALSE)
Arguments
deep
Whether 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
handlers
Handlers 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_type
MIME type.
FUN
Function to encode response body.
Method get_encode()
Get encoder function for the specific content type.
Usage
ContentHandlersFactory$get_encode(content_type)
Arguments
content_type
MIME type.
Method set_decode()
Set handler to decode body for the specific content type.
Usage
ContentHandlersFactory$set_decode(content_type, FUN)
Arguments
content_type
MIME type.
FUN
Function to decode request body.
Method get_decode()
Get decoder function for the specific content type.
Usage
ContentHandlersFactory$get_decode(content_type)
Arguments
content_type
MIME 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
deep
Whether 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_function
Function that takes an object or file and computes the hash of it
last_modified_function
Function 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
routes
Routes paths to protect.
match
How routes will be matched: exact or partial (as prefix).
id
Middleware id.
hash_function
a 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_function
a 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
deep
Whether 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
ContentHandlers
Class 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_encode
andset_decode
methods.
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
id
Middleware id.
Method clone()
The objects of this class are cloneable with this method.
Usage
EncodeDecodeMiddleware$clone(deep = FALSE)
Arguments
deep
Whether 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_type
Type of the error response.
encode
Function to encode response body.
Methods
Public methods
Method new()
Creates HTTPError object.
Usage
HTTPErrorFactory$new(content_type = "text/plain", encode = as.character)
Arguments
content_type
Type of the error response.
encode
Function to encode response body.
Method set_content_type()
Set content type of response.
Usage
HTTPErrorFactory$set_content_type(content_type)
Arguments
content_type
Type 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
encode
Function 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_code
HTTP status code.
body
Response body.
...
Additional named arguments which will be passed to
Response$new()
.headers
may 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
deep
Whether 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
level
Log level. Allowed values: info, fatal, error, warn, debug, trace, off, all.
name
Logger name.
printer
Logger with sink defined by
printer
function. It should have signaturefunction(timestamp, level, logger_name, pid, message)
. By default whenprinter = NULL
logger writes message in JSON format tostdout
.
Method set_name()
Sets logger name.
Usage
Logger$set_name(name = "ROOT")
Arguments
name
Logger name.
Method set_log_level()
Sets log level.
Usage
Logger$set_log_level( level = c("info", "fatal", "error", "warn", "debug", "trace", "off", "all") )
Arguments
level
Log 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
FUN
Printer 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
msg
Log message.
...
Additionals params.
Method debug()
Write debug message.
Usage
Logger$debug(msg, ...)
Arguments
msg
Log message.
...
Additionals params.
Method info()
Write information message.
Usage
Logger$info(msg, ...)
Arguments
msg
Log message.
...
Additionals params.
Method warn()
Write warning message.
Usage
Logger$warn(msg, ...)
Arguments
msg
Log message.
...
Additionals params.
Method error()
Write error message.
Usage
Logger$error(msg, ...)
Arguments
msg
Log message.
...
Additionals params.
Method fatal()
Write fatal error message.
Usage
Logger$fatal(msg, ...)
Arguments
msg
Log message.
...
Additionals params.
Method clone()
The objects of this class are cloneable with this method.
Usage
Logger$clone(deep = FALSE)
Arguments
deep
Whether 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_request
Function which takes 2 arguments -
request
andresponse
objects (class Request and Response correspondingly) and modifyrequest
andresponse
or throw exception using HTTPError helper.
Function is called before request is routed to handler.
Usuallyprocess_request
is used to perform logging, check authorization, etc.process_response
Function which takes 2 arguments -
request
andresponse
objects (class Request and Response correspondingly) and modifyrequest
andresponse
or throw exception using HTTPError helper.
Function is called after request is processed by handler. Usuallyprocess_response
is used to perform logging, custom error handling, etc.id
Middleware 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_request
Modify
request
orresponse
objects or throw exception using[HTTPError]
helper. This function evaluate before router handler called.process_response
Modify
request
orresponse
objects or throw exception using[HTTPError]
helper. This function evaluate after router handler called.id
Middleware id.
Method clone()
The objects of this class are cloneable with this method.
Usage
Middleware$clone(deep = FALSE)
Arguments
deep
Whether 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
path
Request path.
method
Request HTTP method.
headers
Request headers.
cookies
Request cookies.
context
Environment to store any data. Can be used in middlewares.
content_type
Request body content type.
body
Request body.
parameters_query
Request query parameters.
parameters_body
Request body parameters.
parameters_path
List 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/1
thenparameters_path
will belist(job_id = "1")
.
It is important to understand thatparameters_path
will be available (not empty) only after request will reach handler.
This effectively means thatparameters_path
can be used inside handler and response middleware (but not request middleware!).files
Structure which contains positions and lengths of files for the multipart body.
decode
Function to decode body for the specific content type.
Active bindings
id
Automatically generated UUID for each request. Read only.
date
Request
Date
header converted toPOSIXct
.accept
Splitted
Accept
request header.accept_json
Request accepts JSON response.
accept_xml
Request 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
path
Character with requested path. Always starts with
/
.method
Request HTTP method.
parameters_query
A named list with URL decoded query parameters.
parameters_body
A named list with URL decoded body parameters. This field is helpful when request is a urlencoded form or a multipart form.
headers
Request HTTP headers represented as named list.
body
Request body. Can be anything and in conjunction with
content_type
defines how HTTP body will be represented.cookies
Cookies represented as named list. Note that cookies should be provided explicitly - they won't be derived from
headers
.content_type
HTTP content type. Note that
content_type
should be provided explicitly - it won't be derived fromheaders
.decode
Function 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
id
Request 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
name
Header field name.
default
Default 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
name
Query 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
name
Body field name.
Returns
Body field value.
Method get_param_path()
Get templated path parameter by name.
Usage
Request$get_param_path(name)
Arguments
name
Path parameter name.
Returns
Path parameter value.
Method get_file()
Extract specific file from multipart body.
Usage
Request$get_file(name)
Arguments
name
Body 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
deep
Whether 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
body
Response body.
If it is a named character with a namefile
ortmpfile
then 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_type
Response body content (media) type. Will be translated to
Content-type
header.headers
Response headers.
status_code
Response HTTP status code.
cookies
Response cookies. Will be translated to
Set-Cookie
headers.context
Environment to store any data. Can be used in middlewares.
encode
Function to encode body for specific content.
Active bindings
status
Paste 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
body
Response body.
content_type
Response body content (media) type.
headers
Response headers.
status_code
Response status code.
encode
Function 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_type
Response 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
code
Status code as integer number.
Method has_header()
Determine whether or not the response header exists.
Usage
Response$has_header(name)
Arguments
name
Header 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
name
Header field name.
default
Default 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
name
Header field name.
value
Header field value.
Method delete_header()
Unset HTTP response header.
Usage
Response$delete_header(name)
Arguments
name
Header 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
name
Header field name.
value
Header field value.
Method set_date()
Set Date
HTTP header. See docs on MDN.
Usage
Response$set_date(dtm = Sys.time())
Arguments
dtm
POSIXct 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
name
Cookie name.
value
Cookie value.
expires
Cookie expires date and time (POSIXct).
max_age
Max cookie age (integer).
domain
Cookie domain.
path
Cookie path.
secure
Cookie secure flag.
http_only
Cookie HTTP only flag.
Method unset_cookie()
Unset cookie with given name.
Usage
Response$unset_cookie(name)
Arguments
name
Cookie name.
Returns
Logical value.
Method set_body()
Set response body.
Usage
Response$set_body(body)
Arguments
body
Response body.
Method set_response()
Set response fields.
Usage
Response$set_response( status_code, body = NULL, content_type = self$content_type )
Arguments
status_code
Response HTTP status code.
body
Response body.
content_type
content_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
deep
Whether 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
paths
All 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
path
Path to handle.
match
Defines 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.
-
id
Path 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
path
Path endpoint.
extract_vars
Extart 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
deep
Whether 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"))