Recite
An object oriented HTTP library for javascript
Installation
Use npm to install recite in your project.
npm install --save recite
Then require it with
var Http = ;
Browserify
Recite is compatible with browserify for use in the browser.
For sake of size, the NodeDriver
is not included in the browserify bundle. If you wish to use it,
you can require it explicitly with:
var NodeDriver = ;
Configuring Promise
Recite requires a promise library. By default it uses global.Promise (window.Promise in the browser)
but if you're using recite in node (< 0.12) or older browsers, you'll need to set it manually.
To set it, just set Http.Promise
.
HttpPromise = Promise;
In node < 0.12, Recite is tested against the es6-promise module.
Getting Started
First, create a new instance of Http
var http = ;
Now we're going to use our Http
instance to create a GET
request.
var request = http;
So far, we've just created a request object. It hasn't been sent yet. Now we'll send it.
request;
We called the send()
method on the request object. This submits the request to our driver (we'll learn about those later). When the response comes back, our callback function will be called
with a response object. Here we're simply logging the contents of that response to the console.
Creating Requests
The Http request()
method creates a new Request
object (see below). It takes the following arguments:
method (string)
: The HTTP request method (GET, POST, etc.)url (string)
: The url to send the request tocontents (mixed)
: Optional. The body of the requestheaders (object)
: Optional. An object of header name/value pairs
var request = http;
GET
The Http get()
method is a helper method for creating GET requests.
It works like the request()
method, but it sets the HTTP method and automatically
encodes url attributes. It takes the arguments:
url (string)
: The url to send the request toattributes (object)
: Optional. GET attributes to append the the urlheaders (object)
: Optional. An object of header name/value pairs
var request = http;
This will result in a GET request to http://www.example.com/api/person?id=123
.
POST
The Http.post
method is a helper method for creating POST requests.
It works like the request()
method, but it sets the HTTP method to POST.
It takes the arguments:
url (string)
: The url to send the request tocontents (mixed)
: Optional. The body of the requestheaders (object)
: Optional. An object of header name/value pairs
Sending Requests
With Http
Creating a request is the first step, but it doesn't do anything unless you send it.
The Http send()
method does this step.
var request = http;http;
The send()
method accepts two callbacks, the first is called if our request is
successful. The second is called if the request fails. Both the callbacks are passed
a Response
object (see below).
Promises
Although you can pass callbacks to the send()
method as illustrated above,
you can also use promises to handle responses. Let's redo our example from
above, but using a promise instead.
var request = http;http;
We called the send()
method on the request object. This returns a promise.'
Promises have a then
method that gets called when our response comes back from
the driver. The promise is resolved (or rejected) with a Response object.
If you're not familiar with promises, you may not see the benefit of using them from this example. Just use whichever technique you prefer. The examples below will use promises rather than passing callbacks.
With Request
The Request
object has a send()
method as well. This is simply a shortcut to
avoid having to send requests in two steps.
http;
As with Http.send()
, Request.send()
can also take resolve and reject
callbacks.
Unsuccessful Requests
If a request is unsuccessful (it has a non-200 response code). The promise will be rejected instead of resolved. You can handle this with the second argument to Promise.then
.
http;
The Request Object
The objects returned from request()
(and get()
/post()
) are instances of Http.Request
.
You can manually create a new Request
object using the constructor.
The arguments for the constructor are the same as the arguments for Http.request
.
var request = 'GET' 'http://example.com' contents headers;http;
Request
objects have several methods:
getMethod
/setMethod
: gets/sets the HTTP methodgetUrl
/setUrl
: gets/sets the request URLgetContents
/setContents
: gets/sets the request body contentgetHeaders
/setHeaders
: gets/sets theHeaders
object (seeHeaders
below)send
: sends the request and returns a PromisesetHttp
: sets theHttp
instance to send with
var request = 'GET' 'http://example.com' contents headers;var method = request; // 'GET'request;
Note the send()
method. As explained above, this is a shortcut to avoid having to save the
request in a variable before sending it. However to use it, the setHttp
method must be called
first to set the instance of Http
you want to send the request. This is done
automatically if you use one of the Http
request methods instead of creating a Request
object manually. If you manually instantiate a request, its usually easier to use the Http.send
method
instead of the Request.send
method.
var http = ;var request = 'GET' 'http://example.com' contents headers; // You can either set the http instancerequest;request; // or just use Http.send()http;
The Response Object
As mentioned, the send()
method returns a Promise
object. This promise resolves to a Response
object. This object is similar to the Request
object with some differences.
The constructor takes the following arguments:
request
: the request object this is a response tostatus
: the HTTP status codecontents
: the response bodyheaders
: an object of response header name/value pairs
Methods:
getRequest
: gets theRequest
object for this responsegetStatus
/setStatus
: gets/sets the HTTP response status codegetContents
/setContents
: gets/sets the response body contentgetHeaders
/setHeaders
: gets/sets theHeaders
object (see "The Headers Object" below)isSuccessful
: Checks if the response status code is in the 200 range
http;
The Headers Object
The Headers
class is used by Request
and Response
. To get the object, call the getHeaders
method.
var headers = request;
Headers
objects have the following methods:
get(name)
: Gets the value for the given header. Returnsundefined
if the header is not set.set(name, value)
: Sets the value for the given header name.all()
: Returns a plain object of header name/value pairs.clear()
: Empties the headers.setObject(object)
: Adds all the given name/value pairs inobject
. Does not clear existing headers.getContentType
: Gets the content-type of the message if it is set.
Header case is always maintained when stored, but the get
method searches case-insensitively.
This means you don't have to worry about case when using the get
method, but the object returned
from all()
will have its keys in the case you specified.
A Headers
instance can also be created manually with the constructor and passed in anywhere that accepts a headers argument. The constructor takes a single argument, a plain object of header name/value pairs.
var headers = 'Content-type': 'application/json';var request = http;
Events
The Http
instance has two events:
http.request
: Fired when a request is senthttp.response
: Fired when a response is returned
To subscribe to these events, you must get the dispatcher object:
var dispatcher = http;
The dispatcher is an instance of Hoopla. You can subscribe to an event with the addListener
method. See the Hoopla documentation for more details.
The event objects are instances of Hoopla.Event
with the addition of methods to get/set the request or response object.
http.request
This event allows listeners to handle and modify requests before they are sent to the driver. The event object is a Hoopla.Event
instance with the addition of two methods:
getRequest
: Gets the request objectsetRequest
: Overrides the request object to be sent
dispatcher;
This handler converts all request contents to JSON before sending them. At a basic level, this is how the JsonExtension works (see Extensions below).
http.response
This event allows listeners to handle and modify responses before they get passed back to the caller. The event object is a Hoopla.Event
instance with the addition of two methods:
getResponse
: Gets the response objectsetResponse
: Overrides the response object to be returned
dispatcher;
Setting the dispatcher
By default, Http
constructs a dispatcher object for you. However, if you are using recite as part of a larger application, you may want to use your own dispatcher. You can construct your Http
instance with a custom version of the dispatcher by specifying it as a second argument.
var dispatcher = ; // The first argument is the driver. Read about those belowvar http = null dispatcher;
Drivers
Drivers are the back-end of Recite. They do the actual communication over HTTP. Recite can use different drivers depending on your environment or preference.
Drivers can be set by passing them as the first argument when constructing your Http instance.
The default driver
You may have noticed that we didn't pass any drivers to the Http constructor in some of the examples above. That is because Recite tries to automatically choose the best driver for your environment. In the browser, that is the XmlHttpRequestDriver. In node, it's the NodeDriver. If that is right for your use-case, you never need to construct a driver manually.
XmlHttpRequestDriver
This driver is for use in browsers and sends requests with AJAX. To use it simply create
an instance of Http.drivers.XmlHttpRequestDriver
.
var driver = ;var http = driver;
That's it! Now your requests will be sent with AJAX.
NodeHttpDriver
This driver uses the built-in http
and https
modules in node.js.
var driver = ;var http = driver;
Custom Drivers
Recite is implementation agnostic. That means the back-end can use any HTTP library you want.
XmlHttpRequestDriver
and NodeDriver
are provided, however if you use a different library,
it is easy to hook into Recite. All you have to do is implement the send(request, callback)
method.
Recite will call your driver's send
method when the user calls Http.send
.
The driver send
method takes two arguments. The first, request
, is the Request
object to be sent.
The second is a callback that you need to call when your driver gets a response. The callback takes
a Response
instance as an argument.
Here, we construct a very simple driver that always returns a successful response.
var driver = { var response = request 200; ; };var http = driver;
We could also use a constructor function and a prototype to do the same thing.
{} OkDriverprototype { var response = request 200; ;}; var http = ;
Extensions
You can extend Recite's functionality by adding extensions. To add an extension, use the
Http.addExtension
method.
var jsonExtension = ;http;
JsonExtension
The built-in JsonExtension
adds shortcuts for sending JSON requests. If the content-type
of a request or response is application/json
, the body of the request will be converted to/from JSON automatically.
http;
That's a bit wordy, so the extension also adds the getJson
, postJson
, and requestJson
methods for you. These
set the 'content-type' and 'accepts' headers of your request to 'application/json'. Let's use the
postJson
method to send the above request.
http;
FormExtension
The FormExtension
adds multipart/form-data
encoding. If the content-type
of a request is set, the body of the request will be automatically encoded.
http;
Also, like JsonExtension
, there are shortcuts for postForm
and
requestForm
.
http;http;
You can also build a FormData
instance manually and send that. In the browser,
use the native FormData
class, in node, use the form-data
npm package.
// If you're in node, require the form-data package// In the browser FormData is available globallyvar FormData = ; var form = ;form;http;
UrlPrefixExtension
The UrlPrefixExtension
simply allows you to prefix all request URLs with a given string.
You could use this to prepend your domain name or application path to your API requests to
avoid duplicating it throughout your application.
var http = ;http; http;// this sends a request to http://example.com/api/person
Custom Extensions
It's easy to create your own extensions. Extensions only require one method,
the register(http)
method. We're going to implement an extension that logs unsuccessful
requests.
var logExtension = { http; };http;
We can also use a constructor function and prototype to do the same thing.
{} LogExtensionprototype { http;};http;
Check out the built-in JsonExtension
for a more complete example.