simple-http
1 Requesters
requester
html-requester
json-requester
text-requester
xml-requester
update-host
update-port
update-ssl
update-headers
authenticate-basic
2 Making requests
get
post
put
patch
delete
3 Responses
html-response
json-response
text-response
xml-response
get-status
get-status-code
get-response-type
get-headers
4 Exceptions
exn:  fail:  network:  http:  read
exn:  fail:  network:  http:  error
8.12

simple-http🔗ℹ

Darren Newton <info@v25media.com>

 (require simple-http) package: simple-http

Very small library for making HTTP requests. Attempts to handle the server response and convert into the correct data type based on Content-Type headers. Heavily inspired and influenced by racket-request.

The general use case for this is when you want to make repeated requests to an API. You can setup a requester with the relevant auth headers and base URL, then make requests using the available procedures, get, put, etc.

Responses are parsed into jsexpr?, xexpr?, or string? depending on which requester? is used.

Example JSON request and response:

; Setup a json-request using SSL and pointed at httpbin.org
(define httpbin-org
  (update-headers
    (update-ssl
      (update-host json-requester "httpbin.org") #t)
   '("Authorization: 8675309")))
 
; Query params for the request
(define params '((foo . "12") (bar . "hello")))
 
; Make a GET to https://httpbin.org/get?foo=12&bar=hello
(define response (get httpbin-org "/get" #:params params))

Response:

(json-response
 "HTTP/1.1 200 OK"
 '#hasheq((X-Powered-By . ("Flask"))
          (Access-Control-Allow-Credentials . ("true"))
          (Connection . ("close"))
          (Content-Type . ("application/json"))
          (Via . ("1.1 vegur"))
          (Date . ("Sun, 14 May 2017 00:18:16 GMT"))
          (X-Processed-Time . ("0.000797033309937"))
          (Access-Control-Allow-Origin . ("*"))
          (Server . ("meinheld/0.6.1"))
          (Content-Length . ("408")))
 '#hasheq((url . "https://httpbin.org/get?foo=12&bar=hello")
          (headers . #hasheq(
                             (Host . "httpbin.org")
                             (Connection . "close")
                             (Content-Type . "application/json")
                             (Accept . "application/json"). #<forced-pair> .
                             (Accept-Encoding . "gzip")
                             (User-Agent . "Racket/6.8 (net/http-client)")))
          (origin . "255.255.255.255")
          (args . #hasheq((bar . "hello") (foo . "12")))))

1 Requesters🔗ℹ

Requests are made by creating requesters and using functions to update them with relevant data such as base url, use SSL, etc.

struct

(struct requester (host headers port ssl type)
    #:extra-constructor-name make-requester
    #:transparent)
  host : string?
  headers : hash?
  port : integer?
  ssl : boolean?
  type : symbol?
Stores information about the types of requests to make (headers). You usually don’t need to use this directly, pre-loaded requesters are provided for you.

Pre-made requesters for requesting specific formats. Requests made with these will send the appropriate Accept and Content-Type headers. Responses will also be parsed according to their request type.

procedure

(update-host requester host)  requester?

  requester : requester?
  host : string?
Change the host string in a requester. Returns the updated requester.

procedure

(update-port requester port)  requester?

  requester : requester?
  port : integer?
Change the port in a requester. This overrides the default port, which is 443 for SSL requests or 80 otherwise. Returns the updated requester.

procedure

(update-ssl requester ssl)  requester?

  requester : requester?
  ssl : boolean?
Change whether the requester should make SSL requests or not. When set to #t requests will be changed to https. Returns the updated requester.

procedure

(update-headers requester headers)  requester?

  requester : requester?
  headers : (listof string?)
Merges headers into the existing headers in the requester and returns the requester. Any headers passed to the function will overwrite any existing headers in the requester? with the same header key.

(update-headers req '("Authorization: 8675309" "x-foo: oof"))

procedure

(authenticate-basic requester    
  username    
  password)  requester?
  requester : requester?
  username : string?
  password : string?
Constructs an http-basic header from username and password, and then merges that header into the headers of the requester using update-headers.

(authenticate-basic req "sam@example.com" "opensesame")

2 Making requests🔗ℹ

Requests are made using requesters to determine how data should be sent and received. Responses are returned as structs with their data encoded based on the requester used. If the server returns an error code a exn:fail:network:http:error? will be raised. If the data returned from the server is in a different format than requested or cannot be properly parsed then a exn:fail:network:http:read? will be raised.

procedure

(get requester uri [#:params params])

  (or/c html-response? json-response? text-response? xml-response?)
  requester : requester?
  uri : string?
  params : (listof pair?) = '()
Makes a GET request using the provided requester. #:params will be combined onto the URL as query parameters. Responses are structs.

(get
 (update-host json-requester "httpbin.org")
 "/get" #:params '((foo . "12") (bar . "quux")))

procedure

(post requester 
  uri 
  [#:data data 
  #:params params]) 
  (or/c html-response? json-response? text-response? xml-response?)
  requester : requester?
  uri : string?
  data : any/c = #f
  params : (listof pair?) = '()
Makes a POST request using the provided requester. #:params will be combined onto the URL as query parameters. #:data is sent to the server in the body of the request. Responses are structs.

(post
 (update-host json-requester "httpbin.org")
 "/post"
 #:data (jsexpr->string (hasheq 'colossal-squid "drumbones"))
 #:params '((sort . "asc") (filter . "hits")))

procedure

(put requester 
  uri 
  [#:data data 
  #:params params]) 
  (or/c html-response? json-response? text-response? xml-response?)
  requester : requester?
  uri : string?
  data : any/c = #f
  params : (listof pair?) = '()
Makes a PUT request using the provided requester. #:params will be combined onto the URL as query parameters. #:data is sent to the server in the body of the request. Responses are structs.

(put
 (update-host json-requester "httpbin.org")
 "/put"
 #:data (jsexpr->string (hasheq 'white-zombie "thunderkiss"))
 #:params '((sort . "asc")))

procedure

(patch requester 
  uri 
  [#:data data 
  #:params params]) 
  (or/c html-response? json-response? text-response? xml-response?)
  requester : requester?
  uri : string?
  data : any/c = #f
  params : (listof pair?) = '()
Makes a PATCH request using the provided requester. #:params will be combined onto the URL as query parameters. #:data is sent to the server in the body of the request. Responses are structs.

(patch
 (update-host json-requester "httpbin.org")
 "/patch"
 #:data (jsexpr->string (hasheq 'white-zombie "thunderkiss"))
 #:params '((sort . "asc")))

procedure

(delete requester uri [#:params params])

  (or/c html-response? json-response? text-response? xml-response?)
  requester : requester?
  uri : string?
  params : (listof pair?) = '()
Makes a DELETE request using the provided requester. #:params will be combined onto the URL as query parameters. Responses are structs.

(delete
 (update-host json-requester "httpbin.org")
 "/delete"
 #:params '((sort . "asc")))

3 Responses🔗ℹ

struct

(struct html-response (status headers body)
    #:extra-constructor-name make-html-response
    #:transparent)
  status : string?
  headers : hash?
  body : xexpr?

struct

(struct json-response (status headers body)
    #:extra-constructor-name make-json-response
    #:transparent)
  status : string?
  headers : hash?
  body : jsexpr?

struct

(struct text-response (status headers body)
    #:extra-constructor-name make-text-response
    #:transparent)
  status : string?
  headers : hash?
  body : string?

struct

(struct xml-response (status headers body)
    #:extra-constructor-name make-xml-response
    #:transparent)
  status : string?
  headers : hash?
  body : xexpr?
Response bodies are decoded into a form determined by the requester used to make requests. If the response comes back in a form that can’t be processed or throws an error duing processing then a exn:fail:network:http:read? exception will be raised.

status is a string? such as "HTTP/1.1 200 OK". headers are a key value representation of the response headers:
#hasheq((Host . "httpbin.org")
        (Connection . "close")
        (Content-Type . "application/json")
        (Accept . "application/json"))

procedure

(get-status resp)  (or/c string? void?)

  resp : (or/c html-response? json-response? text-response? xml-response?)

procedure

(get-status-code resp)  (or/c number? void?)

  resp : (or/c html-response? json-response? text-response? xml-response?)

procedure

(get-response-type resp)  (or/c "html" "json" "text" "xml")

  resp : (or/c html-response? json-response? text-response? xml-response?)

procedure

(get-headers resp)  (hash/c symbol? (listof string?))

  resp : (or/c html-response? json-response? text-response? xml-response?)
These helper functions extract parts of responses based on their type.

4 Exceptions🔗ℹ

struct

(struct exn:fail:network:http:read (message
    continuation-marks
    type)
    #:extra-constructor-name make-exn:fail:network:http:read
    #:transparent)
  message : string?
  continuation-marks : continuation-mark-set?
  type : symbol?
Raised when a response is either the wrong format (ex: HTML returned for a JSON request) or malformed and cannot be parsed by the relevant reader. type is a symbol to let you know which requester made the request, such as 'json, etc.

struct

(struct exn:fail:network:http:error (message
    continuation-marks
    code
    type)
    #:extra-constructor-name make-exn:fail:network:http:error
    #:transparent)
  message : string?
  continuation-marks : continuation-mark-set?
  code : number?
  type : symbol?
Raised when the server responds with an error code. code is the numeric error code returned by the server. type is a symbol? letting you know which requester made the request (ex: 'json).