REST Protocol

From the Rebol Console:

do http://reb4.me/r/rest-curl

read [
scheme: 'rest
url: http://rebol.com/
]

The REST Scheme offers an exchange-oriented implementation of HTTP. The REST Scheme differs from the Rebol HTTP Scheme in that it returns the whole response including headers and does not return errors for 4xx/5xx response codes. Additionally, the REST Scheme signs OAuth 1.x requests where necessary (tested against a number of third-party APIs).

Requests

Minimal

A minimal request requires only a valid URL:

read [
scheme: 'rest
url: http://rebol.info/
]

Caveat: due to limitations in Rebol 2 port semantics, building the request block dynamically is best achieved using COMPOSE:

target: http://rebol.info/

read compose [
scheme: 'rest
url: (target)
]

It is possible to use GET-WORD! so long as the value isn’t referred to by a word currently used by the port model:

; these words can only be referenced using COMPOSE
probe words-of system/standard/port

; other words are fine
my-target: http://rebol.info/

read [
scheme: 'rest
url: :my-target
]

Posting Content

A POST request uses TYPE and CONTENT values. Content can be specified using STRING!

read [
scheme: 'rest
url: https://example.com/upload
action: 'post
type: 'text/json
content: {["some", "json"]}
]

Or by BINARY!

read [
scheme: 'rest
url: https://example.com/upload
action: 'post
type: 'image/raw
content: #{DECAFBAD}
]

Simulating WebForms

The REST Scheme uses a READ/CUSTOM block to simulate the way browsers generate requests via form submissions:

read/custom [
scheme: 'rest
url: https://example.com/upload
action: 'post
][
param1: "This"
param2: "That"
]

For GET requests, the form will be appended to the URL as a Query String, for POST requests, the form will be sent as the CONTENT parameter. For multipart submissions, set the MULTIPART flag to TRUE

read/custom [
scheme: 'rest
url: https://example.com/upload
action: 'post
multipart: true
][
param1: "This"
param2: "That"
]

OAuth Requests

The REST scheme supports OAuth requests via a block containing relevant OAuth credentials:

read [
scheme: 'rest
url: https://api.twitter.com/1.1/account/settings.json
oauth: [
Consumer-Key: "--App Key--"
Consumer-Secret: "--App Secret--"
OAuth-Token: "--User Token--"
OAuth-Token-Secret: "--User Secret--"
]
]

Currently signing requires that parameters are added as per the WebForm simulation method above:

read/custom [
scheme: 'rest
url: https://example.com/upload
action: 'post
oauth: :my-oauth-settings
][
param1: "This"
param2: "That"
]

Short-Form Requests

A URL short-form is available:

read rest://rebol.com

Caveat: the short-form only corresponds to HTTP URLs, not HTTPS

Responses

The Response object gives you immediate access to the HTTP status code and headers:

>> page: read rest://rebol.com
>> ? page
PAGE is an object of value:
status integer! 200
message string! "OK"
http-headers block! length: 14
headers object! [Date Server Last-Modified Accept-...
content string! {<!doctype html> <html><head> <met...
binary binary! #{ 3C21646F63747970652068746D6C3E0...
type path! length: 2
length integer! 9379

Notes

  • This version of the REST Protocol does not use Rebol’s built-in TCP Ports, rather uses the cURL shell command. cURL is available by default on most Unix/Linux/Mac OS X installations, and is generally available for most platforms. cURL is used to allow HTTPS support from the Rebol/Core interpreter.
  • This should work within most Shell environments, I have tested on CSH, BASH and SH.
  • A version of this script that uses Rebol’s internal TCP protocol is available at:
    Rebol REST; though has caveats and limitations too numerous to list here.
  • Please direct any questions/suggestions for now to my Twitter account: @rgrebol