Skip to content

Content negotiation

mde edited this page Feb 17, 2012 · 10 revisions

Actions in Geddy controllers can perform automatic content-negotiation.

This means the controller can automatically serve the right kind of content for a request, based on the file-extension for the path on the request, and for the formats the controller knows about.

Using respondsWith

You set this up using the respondsWith property. This is the list of formats the controller can respond with (in the preferred order for when a client doesn’t say what it wants). Geddy will use this list, combined with file extension for the request-path and the Accepts header from the cilent, to decide what format to serve.

You pass a data object to the respond method on the controller, and Geddy’s content-negotiation will attempt to format that object appropriately for the response.

Simple example

Here’s a very simple controller as an example:

var MovingPictures = function () {
  this.respondsWith = ['html', 'json', 'xml', 'js', 'text'];

  this.foo = function (params) {
    this.respond({params: params});
  }; 

};

exports.MovingPictures = MovingPictures;

Built-in formats

The formatting code for Geddy is pretty simple. There are some basic formats built in to Geddy. Formats are the same as the file extension.

1. Text (‘txt’) (.txt extension)

Geddy will look for a toString method on the data object. If there is one, Geddy will return the result of that function call.

If there is no toString method defined, Geddy will return the results of JSON.stringify called on the object.

2. JSON (‘json’) (.json extension)

Geddy will look for a toJson or toJSON method on the data object. If there is one, Geddy will return the result of that function call. If that function doesn’t exist, Geddy will return the result of JSON.stringify called on the object.

3. XML (‘xml’) (.xml extension)

Geddy will look for a toXml or toXML method on the data object. If there is one, Geddy will return the result of that function call. If that function doesn’t exist, Geddy will return the result of geddy.XML.stringify (a utility function always available in Geddy) called on the object.

4. JavaScript/JSONP (‘js’) (.js extension) + callback parameter

Geddy will return the result of JSON.stringify called on the object, wrapped in the method specified in the ‘callback’ parameter.

5. HTML (‘html’) (.html extension)

Geddy will try to render a template, looking in app/views/[controller_name] (in this case, “moving_pictures”) for a template with the name of the action being called. Geddy will pass the data object to the template to use as its render-context (i.e., properties on the object become local variables in the template).

Default format

If the client includes no extension for the request-path, Geddy will try to use the first available format that the client’s Accepts will allow.

Setting respondsWith per-action

You can set respondsWith per-action by setting it inside a specific action’s method call:

var MovingPictures = function () {
  this.respondsWith = ['html', 'json', 'js', 'text'];

  this.foo = function (params) {
    this.respond({params: params});
  };  

  this.bar = function (params) {
    this.respondsWith = ['json', 'js'];
    this.respond({params: params});
  }; 

};

exports.MovingPictures = MovingPictures;

Explicitly setting format

You can also set the format for a response specifically by passing it to respond, like this:

this.respond({params: params}, 'json');