Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/thomasp85/reqres
Powerful classes for http requests and responses
https://github.com/thomasp85/reqres
http http-server request response rstats
Last synced: 15 days ago
JSON representation
Powerful classes for http requests and responses
- Host: GitHub
- URL: https://github.com/thomasp85/reqres
- Owner: thomasp85
- License: other
- Created: 2017-07-26T07:01:35.000Z (over 7 years ago)
- Default Branch: main
- Last Pushed: 2022-08-19T12:49:52.000Z (about 2 years ago)
- Last Synced: 2024-03-02T09:53:33.735Z (8 months ago)
- Topics: http, http-server, request, response, rstats
- Language: R
- Homepage: https://reqres.data-imaginist.com
- Size: 419 KB
- Stars: 36
- Watchers: 4
- Forks: 3
- Open Issues: 2
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
- jimsghstars - thomasp85/reqres - Powerful classes for http requests and responses (R)
README
---
output: github_document
---```{r, echo = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "README-"
)
```# reqres
[![Lifecycle: stable](https://img.shields.io/badge/lifecycle-stable-brightgreen.svg)](https://lifecycle.r-lib.org/articles/stages.html#stable)
[![R-CMD-check](https://github.com/thomasp85/reqres/actions/workflows/R-CMD-check.yaml/badge.svg)](https://github.com/thomasp85/reqres/actions/workflows/R-CMD-check.yaml)
[![CRAN_Status_Badge](http://www.r-pkg.org/badges/version-ago/reqres)](https://cran.r-project.org/package=reqres)
[![CRAN_Download_Badge](http://cranlogs.r-pkg.org/badges/reqres)](https://cran.r-project.org/package=reqres)
[![Codecov test coverage](https://codecov.io/gh/thomasp85/reqres/branch/main/graph/badge.svg)](https://app.codecov.io/gh/thomasp85/reqres?branch=main)While the http protocol is rather basic in essence, it can be a pain to work
with. `reqres` is here to soothe the pain somewhat by providing two powerful
classes for handling all parts of request and response handling during a http
exchange. *This is not a web server*, instead it focuses on making life easier
for developers of web servers by extracting the complexity of cookies, headers,
content negotiation, and the likes into neat little classes. `reqres` builds
upon the [`rook`](https://github.com/jeffreyhorner/Rook/blob/a5e45f751/README.md)
specifications and is thus well suited for
[`httpuv`-based](https://github.com/rstudio/httpuv) webservers.## Features
`reqres` draws a lot of inspiration from [express.js](https://expressjs.com) and
the `Request` and `Response` classes is aiming for feature parity with those
from express. The `Request` class provides automatic parsing of the query string
along with parsing of the body based on the `Content-Type` header (with
decompression if `Content-Encoding` is provided). Further, it provides content
negotiation based on the `Accept(-*)` headers. The `Response` class allows you
to set headers and cookies easily, assign arbitrary data for later use, and
automatically format the body based on content negotiation with the `Request`
object that it is responding to (again, it will compress automatically if the
`Accept-Encoding` header allows it). If any part of the content negotiation
fails the correct response status code will be set, making the response ready to
send.`reqres` comes with a range of parsers and formatters making it work out of the
box with json, xml, html, csv, tab, multipart, and www-form-urlencoded payloads.
It is easy to either modify these or provide your own parsers and formatters if
needed - `reqres` will take care of the content negotiation and simply call your
custom parser/formatter if chosen.## Installation
reqrescan be installed from CRAN with `install.packages('reqres')` or the
development version can be installed from github:```{r, eval=FALSE}
# install.packages('devtools')
devtools::install_github('thomasp85/reqres')
```## Demo
Below is a quick demo of some of the features in `reqres`. It uses the
`fake_request()` in `fiery` to mock a rook request so it can be used without
setting up a webserver:```{r}
library(reqres)# We start by mocking our request
rook <- fiery::fake_request(
url = 'http://www.example.com/summary?id=2347&user=Thomas+Lin+Pedersen',
content = '{"name":["Thomas Lin Pedersen"],"age":[31],"homepage":["www.data-imaginist.com","www.github.com/thomasp85"]}',
headers = list(
Content_Type = 'application/json',
Accept = 'application/json, application/xml; q=0.5, text/*; q=0.3',
Accept_Encoding = 'gzip, br'
)
)# A Request object can now be created
req <- Request$new(rook)
req# ... along with a response
res <- req$respond()
res
```### Request
A lot of information is already available, such as the query and other parts of
the url, but the body is not filled in automatically.```{r}
req$host
req$query
req$body
```The body can easily be parsed though, as long as a parser exists for the
provided content type.```{r}
req$is('json')
req$parse(json = parse_json())
req$body
```Instead of inspecting it manually you can simply provide a range of parsers and
let the object choose the correct one itself```{r}
req$set_body(NULL)
req$parse(
txt = parse_plain(),
html = parse_html(),
json = parse_json()
)
req$body
```In the case that none of the provided parsers fits the content type, the
response will automatically get updated with the correct error code```{r}
req$set_body(NULL)
req$parse(txt = parse_plain())
res
```To facilitate all this `reqres` comes with a mapping of standard mime types to
the provided parsers. This can simply be supplied to the parse method```{r}
req$set_body(NULL)
req$parse(default_parsers)
req$body
```### Response
While the request is mainly intended to be read from, the response should be
written to. The `Response` class contains a slew of methods to easily set
headers, cookies, etc.```{r}
res$set_header('Date', to_http_date(Sys.time()))
res$get_header('Date')
res$set_cookie('user', req$query$id, max_age = 9000L)
res$has_cookie('user')
```Furthermore, it contains its own data store where arbitrary information can be
stored so as to pass it between middleware etc. This data will never be part of
the actual response.```{r}
res$set_data('alphabet', letters)
res$get_data('alphabet')
```Files can be attached and marked for download, setting the relevant headers
automatically```{r}
res$attach(system.file('NEWS.md', package = 'reqres'))
res$get_header('Content-Type')
res$get_header('Content-Disposition')
```Often we need to provide a payload in the form of a body. This can be any type
of R object until the response is handed off to the server, where it should be
either a string or a raw vector.```{r}
res$remove_header('Content-Disposition')
res$body <- head(mtcars)
res$body
```Based on the `Accept` header in the request it can be formatted correctly thus
making it ready to send back to the client. As this request contains an
`Accept-Encoding` header it will be compressed as well.```{r}
res$format(json = format_json())
res$body
res$get_header('Content-Type')
res$get_header('Content-Encoding')
```The content negotiation understands wildcards as well
```{r}
res$body <- head(mtcars)
req$get_header('Accept')
res$format(csv = format_table(sep = ','), compress = FALSE)
res$body
res$get_header('Content-Type')
```A default formatter mapping exists in parallel to `default_parsers` for the
`Request$format()` method.```{r}
res$body <- head(mtcars)
res$format(default_formatters, compress = FALSE)
res$body
```It is easy to define your own formatters and add them along the defaults
```{r}
res$body <- head(mtcars)
res$format('text/yaml' = yaml::as.yaml, compress = FALSE)
res$body
```## Code of Conduct
Please note that the 'reqres' project is released with a
[Contributor Code of Conduct](https://reqres.data-imaginist.com/CODE_OF_CONDUCT.html).
By contributing to this project, you agree to abide by its terms.