| Title: | A Framework for Web API Packages |
|---|---|
| Description: | An opinionated framework for use within api-wrapping R packages. |
| Authors: | Jon Harmon [aut, cre, cph] (ORCID: <https://orcid.org/0000-0003-4781-4346>), R Consortium [fnd] |
| Maintainer: | Jon Harmon <[email protected]> |
| License: | MIT + file LICENSE |
| Version: | 0.0.0.9007 |
| Built: | 2026-05-29 17:07:05 UTC |
| Source: | https://github.com/jonthegeek/nectar |
This helper creates a reusable authentication object that can be passed to
req_prepare() via auth.
auth_api_key( parameter_name, ..., api_key = NULL, location = c("header", "query", "cookie"), call = rlang::caller_env() )auth_api_key( parameter_name, ..., api_key = NULL, location = c("header", "query", "cookie"), call = rlang::caller_env() )
parameter_name |
( |
... |
These dots are for future extensions and must be empty. |
api_key |
( |
location |
( |
call |
( |
A list with class "nectar_auth" and elements auth_fn and
auth_args.
Other opinionated auth functions:
auth_prepare(),
req_auth_api_key()
auth_api_key("X-API-Key", api_key = "my-api-key")auth_api_key("X-API-Key", api_key = "my-api-key")
This constructor stores an authentication function and arguments so the same authentication strategy can be reused across requests.
auth_prepare(auth_fn, ..., call = rlang::caller_env())auth_prepare(auth_fn, ..., call = rlang::caller_env())
auth_fn |
( |
... |
( |
call |
( |
A list with class "nectar_auth" and elements auth_fn and
auth_args.
Other opinionated auth functions:
auth_api_key(),
req_auth_api_key()
auth_prepare(req_auth_api_key, "X-API-Key", api_key = "my-api-key")auth_prepare(req_auth_api_key, "X-API-Key", api_key = "my-api-key")
If a request has a pagination policy defined by req_pagination_policy(),
extract the pagination_fn from that policy. Otherwise return NULL.
choose_pagination_fn(req)choose_pagination_fn(req)
req |
( |
The pagination function, or NULL.
req <- httr2::request("https://example.com") req <- req_pagination_policy(req, httr2::iterate_with_offset("page")) choose_pagination_fn(req)req <- httr2::request("https://example.com") req <- req_pagination_policy(req, httr2::iterate_with_offset("page")) choose_pagination_fn(req)
Discard empty elements in nested lists.
compact_nested_list(lst)compact_nested_list(lst)
lst |
A (nested) list to filter. |
The list, minus empty elements and branches.
x <- list( a = list( b = letters, c = NULL, d = 1:5 ), e = NULL, f = 1:3 ) compact_nested_list(x)x <- list( a = list( b = letters, c = NULL, d = 1:5 ), e = NULL, f = 1:3 ) compact_nested_list(x)
When constructing API calls programmatically, you may encounter situations where an upstream task should indicate which function to apply. For example, one endpoint might use a special auth function that isn't used by other endpoints. This function exists to make coding such situations easier.
do_if_fn_defined(x, fn = NULL, ..., call = rlang::caller_env())do_if_fn_defined(x, fn = NULL, ..., call = rlang::caller_env())
x |
An object to potentially modify, such as a |
fn |
A function to apply to |
... |
Additional arguments to pass to |
call |
( |
The object, potentially modified.
build_api_req <- function(endpoint, auth_fn = NULL, ...) { req <- httr2::request("https://example.com") req <- httr2::req_url_path_append(req, endpoint) do_if_fn_defined(req, auth_fn, ...) } # Most endpoints of this API do not require authentication. unsecure_req <- build_api_req("unsecure_endpoint") unsecure_req$headers # But one endpoint requires authentication. secure_req <- build_api_req( "secure_endpoint", httr2::req_auth_bearer_token, "secret-token" ) secure_req$headers$Authorizationbuild_api_req <- function(endpoint, auth_fn = NULL, ...) { req <- httr2::request("https://example.com") req <- httr2::req_url_path_append(req, endpoint) do_if_fn_defined(req, auth_fn, ...) } # Most endpoints of this API do not require authentication. unsecure_req <- build_api_req("unsecure_endpoint") unsecure_req$headers # But one endpoint requires authentication. secure_req <- build_api_req( "secure_endpoint", httr2::req_auth_bearer_token, "secret-token" ) secure_req$headers$Authorization
This function is intended as a replacement for httr2::iterate_with_cursor()
for the common situation where the response body is json, and the cursor can
be "empty" in various ways. Even within a single API, some endpoints might
return a NULL next_cursor to indicate that there are no more pages of
results, while other endpoints might return "". This function normalizes
all such results to NULL.
iterate_with_json_cursor(param_name = "cursor", next_cursor_path)iterate_with_json_cursor(param_name = "cursor", next_cursor_path)
param_name |
( |
next_cursor_path |
( |
A function that takes the response and the previous request, and returns the next request if there are more results.
# Create a cursor iterator for the Slack API response structure iterate_with_json_cursor("cursor", c("response_metadata", "next_cursor")) # Create a cursor iterator for the Crossref API iterate_xref <- iterate_with_json_cursor("cursor", c("message", "next-cursor")) ## Not run: # Use the iterator to paginate through Crossref API results. The cursor must # be set to "*" for the initial request to trigger the api to return the next # cursor. req <- httr2::request("https://api.crossref.org/works") |> httr2::req_url_query(rows = 5, cursor = "*", select = "DOI") resps <- req_perform_opinionated( req, next_req_fn = iterate_xref, max_reqs = 2 ) resps ## End(Not run)# Create a cursor iterator for the Slack API response structure iterate_with_json_cursor("cursor", c("response_metadata", "next_cursor")) # Create a cursor iterator for the Crossref API iterate_xref <- iterate_with_json_cursor("cursor", c("message", "next-cursor")) ## Not run: # Use the iterator to paginate through Crossref API results. The cursor must # be set to "*" for the initial request to trigger the api to return the next # cursor. req <- httr2::request("https://api.crossref.org/works") |> httr2::req_url_query(rows = 5, cursor = "*", select = "DOI") resps <- req_perform_opinionated( req, next_req_fn = iterate_xref, max_reqs = 2 ) resps ## End(Not run)
Many APIs provide API keys that can be used to authenticate requests (or, often, provide other information about the user). This function helps to apply those keys to requests.
req_auth_api_key( req, parameter_name, ..., api_key = NULL, location = c("header", "query", "cookie"), call = rlang::caller_env() )req_auth_api_key( req, parameter_name, ..., api_key = NULL, location = c("header", "query", "cookie"), call = rlang::caller_env() )
req |
( |
parameter_name |
( |
... |
These dots are for future extensions and must be empty. |
api_key |
( |
location |
( |
call |
( |
A httr2::request() object with additional class nectar_request.
Other opinionated auth functions:
auth_api_key(),
auth_prepare()
Other opinionated request functions:
req_init(),
req_modify(),
req_pagination_policy(),
req_prepare(),
req_tidy_policy()
req <- httr2::request("https://example.com") # Add an API key named `"X-API-Key"` as a header (default) req_auth_api_key(req, "X-API-Key", api_key = "my-api-key") # Add an API key named `"api_key"` as a query parameter req_auth_api_key(req, "api_key", api_key = "my-api-key", location = "query") # If `api_key` is NULL, the key is removed from the request req_auth_api_key(req, "X-API-Key", api_key = NULL)req <- httr2::request("https://example.com") # Add an API key named `"X-API-Key"` as a header (default) req_auth_api_key(req, "X-API-Key", api_key = "my-api-key") # Add an API key named `"api_key"` as a query parameter req_auth_api_key(req, "api_key", api_key = "my-api-key", location = "query") # If `api_key` is NULL, the key is removed from the request req_auth_api_key(req, "X-API-Key", api_key = NULL)
For a given API, the base_url and user agent will generally be the same for
every call to that API. Use this function to prepare that piece of the
request once for easy reuse.
req_init( base_url, ..., additional_user_agent = NULL, call = rlang::caller_env() )req_init( base_url, ..., additional_user_agent = NULL, call = rlang::caller_env() )
base_url |
( |
... |
These dots are for future extensions and must be empty. |
additional_user_agent |
( |
call |
( |
A httr2::request() object with additional class nectar_request.
Other opinionated request functions:
req_auth_api_key(),
req_modify(),
req_pagination_policy(),
req_prepare(),
req_tidy_policy()
req_init("https://example.com") req_init( "https://example.com", additional_user_agent = "my_api_client (https://my.api.client)" )req_init("https://example.com") req_init( "https://example.com", additional_user_agent = "my_api_client (https://my.api.client)" )
Modify the basic request for an API by adding a path and any other path-specific properties.
req_modify( req, ..., path = NULL, query = NULL, body = NULL, mime_type = NULL, method = NULL, header = NULL, cookie = NULL, call = rlang::caller_env() )req_modify( req, ..., path = NULL, query = NULL, body = NULL, mime_type = NULL, method = NULL, header = NULL, cookie = NULL, call = rlang::caller_env() )
req |
( |
... |
These dots are for future extensions and must be empty. |
path |
( |
query |
( |
body |
(multiple types) An object to use as the body of the request. If
any component of the body is a path, pass it through |
mime_type |
( |
method |
( |
header |
( |
cookie |
( |
call |
( |
A httr2::request() object with additional class nectar_request.
Other opinionated request functions:
req_auth_api_key(),
req_init(),
req_pagination_policy(),
req_prepare(),
req_tidy_policy()
req_base <- req_init("https://example.com") req_modify(req_base, path = c("specific/{path}", path = "endpoint")) req_modify(req_base, query = c("param1" = "value1", "param2" = "value2"))req_base <- req_init("https://example.com") req_modify(req_base, path = c("specific/{path}", path = "endpoint")) req_modify(req_base, query = c("param1" = "value1", "param2" = "value2"))
APIs generally have a specified method for requesting multiple pages of
results (or sometimes two or three methods). The methods are sometimes
documented within a given endpoint, and sometimes documented at the "top" of
the documentation. Use this function to attach a pagination policy to a
request, so that req_perform_opinionated() can automatically handle
pagination.
req_pagination_policy(req, pagination_fn, call = rlang::caller_env())req_pagination_policy(req, pagination_fn, call = rlang::caller_env())
req |
( |
pagination_fn |
( |
call |
( |
A httr2::request() object with additional class nectar_request.
Other opinionated request functions:
req_auth_api_key(),
req_init(),
req_modify(),
req_prepare(),
req_tidy_policy()
req <- httr2::request("https://example.com") req_pagination_policy(req, httr2::iterate_with_offset("page"))req <- httr2::request("https://example.com") req_pagination_policy(req, httr2::iterate_with_offset("page"))
This function ensures that a request has httr2::req_retry() applied, and
then performs the request, using either httr2::req_perform_iterative() (if
a next_req_fn function is supplied) or httr2::req_perform() (if not).
req_perform_opinionated( req, ..., next_req_fn = choose_pagination_fn(req), max_reqs = 2, max_tries_per_req = 3 )req_perform_opinionated( req, ..., next_req_fn = choose_pagination_fn(req), max_reqs = 2, max_tries_per_req = 3 )
req |
The first request to perform. |
... |
These dots are for future extensions and must be empty. |
next_req_fn |
( |
max_reqs |
( |
max_tries_per_req |
( |
Always returns a list of httr2::response() objects, one for each
request performed, to ensure that downstream operations are the same
regardless of the number of responses. The list has additional class
nectar_responses.
# Performs a single request and returns a list of responses req <- httr2::request("https://jsonplaceholder.typicode.com/posts") resps <- req_perform_opinionated(req) httr2::resp_status(resps[[1]]) resp_parse(resps, response_parser = resp_tidy_json)# Performs a single request and returns a list of responses req <- httr2::request("https://jsonplaceholder.typicode.com/posts") resps <- req_perform_opinionated(req) httr2::resp_status(resps[[1]]) resp_parse(resps, response_parser = resp_tidy_json)
Add information about nectar and the calling package (if called from a package) to the user agent string.
req_pkg_user_agent( req, pkg_name = get_pkg_name(call), pkg_url = NULL, call = rlang::caller_env() )req_pkg_user_agent( req, pkg_name = get_pkg_name(call), pkg_url = NULL, call = rlang::caller_env() )
req |
( |
pkg_name |
( |
pkg_url |
( |
call |
( |
A httr2::request() object with additional class nectar_request.
req <- httr2::request("https://example.com") req$options$useragent req_pkg_user_agent(req)$options$useragent req_pkg_user_agent(req, "stbl")$options$useragentreq <- httr2::request("https://example.com") req$options$useragent req_pkg_user_agent(req)$options$useragent req_pkg_user_agent(req, "stbl")$options$useragent
This function implements an opinionated framework for preparing an API
request. It is intended to be used inside an API client package. It serves as
a wrapper around the req_ family of functions, such as httr2::request().
req_prepare( base_url, ..., path = NULL, query = NULL, body = NULL, mime_type = NULL, method = NULL, header = NULL, cookie = NULL, additional_user_agent = NULL, auth = NULL, tidy_policy = tidy_policy_body_auto(), pagination_fn = NULL, call = rlang::caller_env() )req_prepare( base_url, ..., path = NULL, query = NULL, body = NULL, mime_type = NULL, method = NULL, header = NULL, cookie = NULL, additional_user_agent = NULL, auth = NULL, tidy_policy = tidy_policy_body_auto(), pagination_fn = NULL, call = rlang::caller_env() )
base_url |
( |
... |
These dots are for future extensions and must be empty. |
path |
( |
query |
( |
body |
(multiple types) An object to use as the body of the request. If
any component of the body is a path, pass it through |
mime_type |
( |
method |
( |
header |
( |
cookie |
( |
additional_user_agent |
( |
auth |
( |
tidy_policy |
( |
pagination_fn |
( |
call |
( |
A httr2::request() object with additional class nectar_request.
Other opinionated request functions:
req_auth_api_key(),
req_init(),
req_modify(),
req_pagination_policy(),
req_tidy_policy()
req_prepare("https://example.com") req_prepare( "https://example.com", path = c("users/{user_id}", user_id = "42"), query = list(format = "json") )req_prepare("https://example.com") req_prepare( "https://example.com", path = c("users/{user_id}", user_id = "42"), query = list(format = "json") )
API responses generally follow a structured format. Use this function to
define a policy that will be used by resp_tidy() to extract the relevant
portion of a response and wrangle it into a desired format.
req_tidy_policy( req, tidy_policy = tidy_policy_body_auto(), call = rlang::caller_env() )req_tidy_policy( req, tidy_policy = tidy_policy_body_auto(), call = rlang::caller_env() )
req |
( |
tidy_policy |
( |
call |
( |
A httr2::request() object with additional class nectar_request.
Other opinionated request functions:
req_auth_api_key(),
req_init(),
req_modify(),
req_pagination_policy(),
req_prepare()
Other opinionated response parsers:
resp_tidy(),
resp_tidy_json(),
resp_tidy_unknown(),
tidy_policy_body_auto(),
tidy_policy_json(),
tidy_policy_prepare(),
tidy_policy_unknown()
req <- httr2::request("https://example.com") req_tidy_policy( req, tidy_policy_json() )req <- httr2::request("https://example.com") req_tidy_policy( req, tidy_policy_json() )
Use the Content-Type header (extracted using httr2::resp_content_type())
of a response to automatically choose and apply a body parser, such as
httr2::resp_body_json() or resp_body_csv().
resp_body_auto(resp)resp_body_auto(resp)
resp |
( |
The parsed response body.
resp_json <- httr2::response_json(body = list(a = 1, b = "hello")) resp_body_auto(resp_json) resp_csv <- httr2::response( headers = list("Content-Type" = "text/csv"), body = charToRaw("a,b\n1,2\n3,4") ) resp_body_auto(resp_csv)resp_json <- httr2::response_json(body = list(a = 1, b = "hello")) resp_body_auto(resp_json) resp_csv <- httr2::response( headers = list("Content-Type" = "text/csv"), body = charToRaw("a,b\n1,2\n3,4") ) resp_body_auto(resp_csv)
Extract tabular data in comma-separated or tab-separated format from a response body.
resp_body_csv(resp, check_type = TRUE) resp_body_tsv(resp, check_type = TRUE)resp_body_csv(resp, check_type = TRUE) resp_body_tsv(resp, check_type = TRUE)
resp |
( |
check_type |
( |
The parsed response body as a data frame.
resp_csv <- httr2::response( headers = list("Content-Type" = "text/csv"), body = charToRaw("a,b\n1,2\n3,4") ) resp_body_csv(resp_csv) resp_tsv <- httr2::response( headers = list("Content-Type" = "text/tab-separated-values"), body = charToRaw("a\tb\n1\t2\n3\t4") ) resp_body_tsv(resp_tsv)resp_csv <- httr2::response( headers = list("Content-Type" = "text/csv"), body = charToRaw("a,b\n1,2\n3,4") ) resp_body_csv(resp_csv) resp_tsv <- httr2::response( headers = list("Content-Type" = "text/tab-separated-values"), body = charToRaw("a\tb\n1\t2\n3\t4") ) resp_body_tsv(resp_tsv)
Wrap the parsed response body in a list(). Unlike resp_body_auto(), this
function prevents individual response bodies from being concatenated when
combining multiple responses, which is useful for raw or otherwise
non-concatenatable types.
resp_body_separate(resp, resp_body_fn = resp_body_auto)resp_body_separate(resp, resp_body_fn = resp_body_auto)
resp |
( |
resp_body_fn |
( |
The parsed response body wrapped in a list(). This is useful for
things like raw vectors that you wish to parse with httr2::resps_data().
resp <- httr2::response_json(body = list(a = 1, b = "hello")) resp_body_separate(resp)resp <- httr2::response_json(body = list(a = 1, b = "hello")) resp_body_separate(resp)
httr2 provides two methods for performing requests: httr2::req_perform(),
which returns a single httr2::response() object, and
httr2::req_perform_iterative(), which returns a list of httr2::response()
objects. This function automatically determines whether a single response or
multiple responses have been returned, and parses the responses
appropriately.
resp_parse(resps, ...) ## Default S3 method: resp_parse( resps, ..., arg = rlang::caller_arg(resps), call = rlang::caller_env() ) ## S3 method for class 'httr2_response' resp_parse(resps, ..., response_parser = resp_tidy)resp_parse(resps, ...) ## Default S3 method: resp_parse( resps, ..., arg = rlang::caller_arg(resps), call = rlang::caller_env() ) ## S3 method for class 'httr2_response' resp_parse(resps, ..., response_parser = resp_tidy)
resps |
( |
... |
Additional arguments passed on to the |
arg |
( |
call |
( |
response_parser |
( |
The response parsed by the response_parser. If resps was a list,
the parsed responses are concatenated when possible. Unlike
httr2::resps_data, this function does not concatenate raw vector
responses.
resp <- httr2::response_json(body = list(a = 1, b = "hello")) resp_parse(resp, response_parser = httr2::resp_body_json) resps <- list( httr2::response_json(body = list(list(id = 1), list(id = 2))), httr2::response_json(body = list(list(id = 3), list(id = 4))) ) resp_parse(resps, response_parser = httr2::resp_body_json)resp <- httr2::response_json(body = list(a = 1, b = "hello")) resp_parse(resp, response_parser = httr2::resp_body_json) resps <- list( httr2::response_json(body = list(list(id = 1), list(id = 2))), httr2::response_json(body = list(list(id = 3), list(id = 4))) ) resp_parse(resps, response_parser = httr2::resp_body_json)
API responses generally follow a structured format. Use this function to
extract the relevant portion of a response, and wrangle it into a desired
format. This function is most useful when the response was fetched with a
request that includes a tidying policy defined via req_tidy_policy().
resp_tidy(resp)resp_tidy(resp)
resp |
( |
The extracted and cleaned response, or NULL if resp is NULL.
By default, the response is processed with resp_body_auto(). If the
request includes a resp_tidy policy (set via req_tidy_policy()), that
policy's function and arguments are used instead.
Other opinionated response parsers:
req_tidy_policy(),
resp_tidy_json(),
resp_tidy_unknown(),
tidy_policy_body_auto(),
tidy_policy_json(),
tidy_policy_prepare(),
tidy_policy_unknown()
# Without a tidy policy, resp_tidy() uses resp_body_auto() resp <- httr2::response_json(body = list(a = 1, b = "hello")) resp_tidy(resp) # With a tidy policy, resp_tidy() uses the policy's tidy function. req <- req_tidy_policy( httr2::request("https://example.com"), tidy_policy_prepare(httr2::resp_body_json) ) # In practice, the request is attached automatically when the response is # fetched with httr2::req_perform() or req_perform_opinionated(). resp$request <- req resp_tidy(resp)# Without a tidy policy, resp_tidy() uses resp_body_auto() resp <- httr2::response_json(body = list(a = 1, b = "hello")) resp_tidy(resp) # With a tidy policy, resp_tidy() uses the policy's tidy function. req <- req_tidy_policy( httr2::request("https://example.com"), tidy_policy_prepare(httr2::resp_body_json) ) # In practice, the request is attached automatically when the response is # fetched with httr2::req_perform() or req_perform_opinionated(). resp$request <- req resp_tidy(resp)
Parse the body of a response with httr2::resp_body_json(), extract a named
subset of that body, and tidy the result with tibblify::tibblify().
resp_tidy_json(resp, spec = NULL, unspecified = "list", subset_path = NULL)resp_tidy_json(resp, spec = NULL, unspecified = "list", subset_path = NULL)
resp |
( |
spec |
( |
unspecified |
( |
subset_path |
( |
The tibblified response body.
Other opinionated response parsers:
req_tidy_policy(),
resp_tidy(),
resp_tidy_unknown(),
tidy_policy_body_auto(),
tidy_policy_json(),
tidy_policy_prepare(),
tidy_policy_unknown()
resp <- httr2::response_json( body = list(list(id = 1, name = "Alice"), list(id = 2, name = "Bob")) ) resp_tidy_json(resp) # Extract a nested subset of the response body resp_nested <- httr2::response_json( body = list(data = list(list(id = 1), list(id = 2))) ) resp_tidy_json(resp_nested, subset_path = "data")resp <- httr2::response_json( body = list(list(id = 1, name = "Alice"), list(id = 2, name = "Bob")) ) resp_tidy_json(resp) # Extract a nested subset of the response body resp_nested <- httr2::response_json( body = list(data = list(list(id = 1), list(id = 2))) ) resp_tidy_json(resp_nested, subset_path = "data")
If you have not defined a parser for a response type, use this function to return useful information to help construct a parser.
resp_tidy_unknown(resp, call = rlang::caller_env())resp_tidy_unknown(resp, call = rlang::caller_env())
resp |
( |
call |
( |
This function always throws an error. The error lists the names of
the response pieces after parsing with resp_body_auto().
Other opinionated response parsers:
req_tidy_policy(),
resp_tidy(),
resp_tidy_json(),
tidy_policy_body_auto(),
tidy_policy_json(),
tidy_policy_prepare(),
tidy_policy_unknown()
resp <- httr2::response_json(body = list(status = "ok", data = list(id = 1))) try( resp_tidy_unknown(resp) )resp <- httr2::response_json(body = list(status = "ok", data = list(id = 1))) try( resp_tidy_unknown(resp) )
Create a reusable tidy policy that applies resp_body_auto().
tidy_policy_body_auto()tidy_policy_body_auto()
A list with class "nectar_tidy_policy" and elements tidy_fn and
tidy_args.
Other opinionated response parsers:
req_tidy_policy(),
resp_tidy(),
resp_tidy_json(),
resp_tidy_unknown(),
tidy_policy_json(),
tidy_policy_prepare(),
tidy_policy_unknown()
tidy_policy_body_auto()tidy_policy_body_auto()
Create a reusable tidy policy that applies resp_tidy_json().
tidy_policy_json(spec = NULL, unspecified = "list", subset_path = NULL)tidy_policy_json(spec = NULL, unspecified = "list", subset_path = NULL)
spec |
( |
unspecified |
( |
subset_path |
( |
A list with class "nectar_tidy_policy" and elements tidy_fn and
tidy_args.
Other opinionated response parsers:
req_tidy_policy(),
resp_tidy(),
resp_tidy_json(),
resp_tidy_unknown(),
tidy_policy_body_auto(),
tidy_policy_prepare(),
tidy_policy_unknown()
tidy_policy_json(subset_path = "data")tidy_policy_json(subset_path = "data")
This constructor stores a response tidying function and arguments so the same tidying strategy can be reused across requests.
tidy_policy_prepare(tidy_fn, ...)tidy_policy_prepare(tidy_fn, ...)
tidy_fn |
( |
... |
( |
A list with class "nectar_tidy_policy" and elements tidy_fn and
tidy_args.
Other opinionated response parsers:
req_tidy_policy(),
resp_tidy(),
resp_tidy_json(),
resp_tidy_unknown(),
tidy_policy_body_auto(),
tidy_policy_json(),
tidy_policy_unknown()
tidy_policy_prepare(httr2::resp_body_json, simplifyVector = TRUE)tidy_policy_prepare(httr2::resp_body_json, simplifyVector = TRUE)
Create a reusable tidy policy that applies resp_tidy_unknown(), signaling
an informative error.
tidy_policy_unknown()tidy_policy_unknown()
A list with class "nectar_tidy_policy" and elements tidy_fn and
tidy_args.
Other opinionated response parsers:
req_tidy_policy(),
resp_tidy(),
resp_tidy_json(),
resp_tidy_unknown(),
tidy_policy_body_auto(),
tidy_policy_json(),
tidy_policy_prepare()
tidy_policy_unknown()tidy_policy_unknown()
This function normalizes a URL by adding a trailing slash to the base if it is missing. It is mainly for testing and other comparisons.
url_normalize(url)url_normalize(url)
url |
A URL to normalize. |
A normalized URL
identical( url_normalize("https://example.com"), url_normalize("https://example.com/") ) identical( url_normalize("https://example.com?param=value"), url_normalize("https://example.com/?param=value") )identical( url_normalize("https://example.com"), url_normalize("https://example.com/") ) identical( url_normalize("https://example.com?param=value"), url_normalize("https://example.com/?param=value") )
Append zero or more path elements to a URL without duplicating "/"
characters. Based on httr2::req_url_path_append().
url_path_append(url, ...)url_path_append(url, ...)
url |
A URL to modify. |
... |
Path elements to append, as strings. |
A modified URL.
url_path_append("https://example.com", "api", "v1", "users") url_path_append("https://example.com/", "/api", "/v1", "/users") url_path_append("https://example.com/", "/api/v1/users")url_path_append("https://example.com", "api", "v1", "users") url_path_append("https://example.com/", "/api", "/v1", "/users") url_path_append("https://example.com/", "/api/v1/users")