Requests
1 Requesters
requester
requester?
get
put
post
delete
2 Extending and Wrapping Requesters
wrap-requester
wrap-requester-location
wrap-requester-body
wrap-requester-response
add-requester-headers
3 HTTP Requests and Requester
http-requester
http-response
4 HTTP Status Code Exception Throwing
exn:  fail:  network:  http:  code
requester-http-exn
http-requester/  exn
http-exn-of-code?
5 HTTP Requester Location Wrappers
make-domain-requester
make-host+  port-requester
make-https-requester
6 Parameterized Requests
current-requester
with-requester
get
put
post
delete
7 Rack  Unit Requester Integration Testing
check-get
check-put
check-post
check-delete
check-get-exn
check-get-not-exn
check-put-exn
check-put-not-exn
check-post-exn
check-post-not-exn
check-delete-exn
check-delete-not-exn
7.0

Requests

Jack Firth <[email protected]>

 (require request) package: request

This library includes functions and forms for working with requests and requesters. A request is either a GET request, a PUT request, a POST request, or a DELETE request. A requester is a value that can be used to perform these types of requests. This library provides several requesters built on top of the HTTP protocol, however in principle these functions work with any requester that can be constructed to perform each of the types of requests.

source code: https://github.com/jackfirth/racket-request

1 Requesters

procedure

(requester get put post delete)  requester?

  get : (->* (any/c) (#:headers list?) any/c)
  put : (->* (any/c any/c) (#:headers list?) any/c)
  post : (->* (any/c any/c) (#:headers list?) any/c)
  delete : (->* (any/c) (#:headers list?) any/c)
Constructs a requester. A requester is defined on a location type, a body type, a header type, and a response type. A requester is composed of four procedures, each of which may take an optional list of headers to modify the request or add additional information.
  • GET - Given a location, returns a response. Should be safe - calling GET on a location should never modify the resource at the location, and the GET should be invisible to anyone else viewing or modifying that resource.

  • PUT - Given a location and a body, returns a response. Should be idempotent - doing a PUT twice at the same location with the same body should be exactly the same as doing it once. Additionally, for a location that can be PUT to, a GET response should contain what was last PUT there.

  • POST - Given a location and a body, returns a response. A post need not be either safe or idempotent, it may perform arbitrary modification of the resource at the location or other resources related to that resource. A location that is POST-ed to should contain a resource - that is, a GET at that location should not return a resource not found response.

  • DELETE - Given a location, returns a response. In the event of a successful response, later GETs (and DELETEs) at that location should be unsuccessful.

Provided the four provided procedures behave according to the specifications outlined above, the constructed requester defines a REST-ful interface.

value

requester? : predicate/c

Predicate identifying requesters

procedure

(get requester location [#:headers headers])  any/c

  requester : requester?
  location : any/c
  headers : list? = '()
Performs a GET request for the resource at location with the supplied headers using the given requester and returns a response from the requester.

procedure

(put requester    
  location    
  body    
  [#:headers headers])  any/c
  requester : requester?
  location : any/c
  body : any/c
  headers : list? = '()
Performs a PUT request for the resource at location with the supplied body and headers using the given requester and returns a response from the requester.

procedure

(post requester    
  location    
  body    
  [#:headers headers])  any/c
  requester : requester?
  location : any/c
  body : any/c
  headers : list? = '()
Performs a POST request for the resource at location with the supplied body and headers using the given requester and returns a response from the requester.

procedure

(delete requester    
  location    
  body    
  [#:headers headers])  any/c
  requester : requester?
  location : any/c
  body : any/c
  headers : list? = '()
Performs a DELETE request for the resource at location with the supplied headers using the given requester and returns a response from the requester.

2 Extending and Wrapping Requesters

procedure

(wrap-requester wrapper requester)  requester?

  wrapper : 
(or/c (-> (->* (any/c) (#:headers list?) any/c)
          (->* (any/c) (#:headers list?) any/c))
      (-> (->* (any/c any/c) (#:headers list?) any/c)
          (->* (any/c any/c) (#:headers list?) any/c)))
  requester : requester?
Constructs a new requester by wrapping each procedure of the old requester with wrapper. (wrap-requester f (requester get put post delete)) is equivalent to (requester (f get) (f put) (f post) (f delete)).

procedure

(wrap-requester-location location-wrapper    
  requester)  requester?
  location-wrapper : (-> any/c any/c)
  requester : requester?
Constructs a new requester which is identical to requester except that any locations it’s given are first transformed with location-wrapper and then passed on to requester.

procedure

(wrap-requester-body body-wrapper    
  requester)  requester?
  body-wrapper : (-> any/c any/c)
  requester : requester?
Constructs a new requester which is identical to requester except that any request bodies it’s given are first transformed with body-wrapper and then passed on to reqeuster.

procedure

(wrap-requester-response response-wrapper    
  requester)  requester?
  response-wrapper : (-> any/c any/c)
  requester : requester?
Constructs a new requester which is identical to requester except that any responses it returns are transformed with response-wrapper after being received from requester.

procedure

(add-requester-headers headers requester)  requester?

  headers : list?
  requester : requester?
Constructs a new requester which is identical to requester except that it includes headers with every request. If individual requests are given a header with the same name as any of the base headers, the individual header overwrites the base headers. This can be used to construct an HTTP requester that sends authorization headers on every request or always requests a certain content type, for example.

3 HTTP Requests and Requester

value

http-requester : requester?

A simple requester for the HTTP protocol built with get-impure-port, put-impure-port, post-impure-port, and delete-impure-port. Locations are url?s, headers are string?s as in the impure port functions, bodies are bytes?, and responses are instances of the http-response struct.

struct

(struct http-response (code headers body))

  code : exact-positive-integer?
  headers : 
(hash/c string? string?
        #:immutable? #t)
  body : string?
A structure type for HTTP responses. Contains a status code, a hash of headers, and a raw body string. http-requester responds with instances of this structure type. This is distinct from the response structure type in the web server package, as that response is for sending responses while this struct is used when receiving them.

4 HTTP Status Code Exception Throwing

An exception structure type for non-success HTTP error codes. All codes in the range (<= 400 code 599) are defined as error cases. This exception is thrown by http-requesters wrapped by requester-http-exn.

procedure

(requester-http-exn requester)  requester?

  requester : requester?
Given a requester whose responses are http-responses, returns a requester whose responses are the only the response bodies of requester. In the event of failure error codes in the response, an exn:fail:network:http:code exception is thrown which contains the code and response body.

value

http-requester/exn : requester?

Like http-requester, but throws exceptions for failure codes and returns the http response body as it’s response. Equivalent to (requester-http-exn http-requester).

procedure

(http-exn-of-code? code v)  boolean?

  code : exact-positive-integer?
  v : any/c
Returns #t if v is an instance of exn:fail:network:http:code whose status code is code, and returns #f otherwise.

5 HTTP Requester Location Wrappers

Usually an http requester is constructed for a single REST API at a particular domain. These functions allow the construction of requesters that operate at only one domain and accept relative paths as locations.

procedure

(make-domain-requester domain requester)  requester?

  domain : string?
  requester : requester?
Given a requester that accepts url?s as locations, returns a requester that accepts strings representing relative paths as locations. Each path is combined with the given domain to construct a full http url, which is then passed to the underlying requester. The relative path should not begin with a slash.
(define foo-com-requester
  (make-domain-requester "foo.com" http-requester))
; request to http://foo.com/some/sort/of/path
(get foo-com-requester "some/sort/of/path")

procedure

(make-host+port-requester host    
  port    
  requester)  requester?
  host : string?
  port : exact-nonnegative-integer?
  requester : requester?
Like make-domain-requester, except combines the host and port into a domain string. (make-host+port-requester "foo.com" 8080 some-requester) is equivalent to (make-domain-requester "foo.com:8080" some-requester)

procedure

(make-https-requester requester)  requester?

  requester : requester?
Given a requester that accepts url?s as locations, returns a requester that accepts a url and converts it to use an https scheme before being passed to the underlying requester.
(define foo-https-requester
  (make-domain-requester "foo.com" (make-https-requester http-requester)))
; request to https://foo.com/some/sort/of/path
(get foo-https-requester "some/sort/of/path")

6 Parameterized Requests

 (require request/param) package: request

When using requesters, it is usually the case that first a requester is constructed, then all requests are made with it. This makes specifying the requester in each request verbose and redundant. This module provides request functions that operate using a current-requester parameter which can be modified using with-requester.

parameter

(current-requester)  requester?

(current-requester requester)  void?
  requester : requester?
 = http-requester
The current requester. Defaults to the simple http-requester.

syntax

(with-requester requester-expr body ...)

 
  requester-expr : requester?
parameterizes the current-requester to the result of requester-expr in body ....

procedure

(get location [#:headers headers])  any/c

  location : any/c
  headers : list? = '()

procedure

(put location body [#:headers headers])  any/c

  location : any/c
  body : any/c
  headers : list? = '()

procedure

(post location body [#:headers headers])  any/c

  location : any/c
  body : any/c
  headers : list? = '()

procedure

(delete location [#:headers headers])  any/c

  location : any/c
  headers : list? = '()
Equivalent to those defined in request, but using the current-requester to make requests.

7 RackUnit Requester Integration Testing

 (require request/check) package: request

This module provides rackunit checks that test requests using the current-requester from request/param. This can be used as a lightweight HTTP API integration testing framework. Note that none of these checks accept headers. Use with-requester and add-requester-headers to add headers to the current requester for a set of checks. This module also re-provides everything in request/param.

procedure

(check-get location expected-response)  void?

  location : any/c
  expected-response : any/c
Checks that the result of (get location) is equal? to expected-response.

procedure

(check-put location body expected-response)  void?

  location : any/c
  body : any/c
  expected-response : any/c
Checks that the result of (put location body) is equal? to expected-response.

procedure

(check-post location body expected-response)  void?

  location : any/c
  body : any/c
  expected-response : any/c
Checks that the result of (post location body) is equal? to expected-response.

procedure

(check-delete location expected-response)  void?

  location : any/c
  expected-response : any/c
Checks that the result of (delete location body) is equal? to expected-response.

procedure

(check-get-exn exn-pred location)  void?

  exn-pred : predicate/c
  location : any/c
Checks that evaluating (get location) raises an exception satisfying exn-pred.

procedure

(check-get-not-exn location)  void?

  location : any/c
Checks that evaluating (get location) raises no exceptions.

procedure

(check-put-exn exn-pred location body)  void?

  exn-pred : predicate/c
  location : any/c
  body : any/c
Checks that evaluating (put location body) raises an exception satisfying exn-pred.

procedure

(check-put-not-exn location body)  void?

  location : any/c
  body : any/c
Checks that evaluating (put location body) raises no exceptions.

procedure

(check-post-exn exn-pred location body)  void?

  exn-pred : predicate/c
  location : any/c
  body : any/c
Checks that evaluating (post location body) raises an exception satisfying exn-pred.

procedure

(check-post-not-exn location body)  void?

  location : any/c
  body : any/c
Checks that evaluating (post location body) raises no exceptions.

procedure

(check-delete-exn exn-pred location)  void?

  exn-pred : predicate/c
  location : any/c
Checks that evaluating (delete location) raises an exception satisfying exn-pred.

procedure

(check-delete-not-exn location)  void?

  location : any/c
Checks that evaluating (delete location) raises no exceptions.