2012-06-09 14 views
7

Estoy trabajando en la reescritura de un sitio web existente utilizando Node.js con Express.Configure rutas REST en Express JS para Ajax solo para usar con Backbone

El front-end del sitio utilizará Backbone JS y, por lo tanto, necesito que todas las rutas necesarias cumplan con la sincronización Backbone nativa. Ahora la mayoría de las URL del cliente y de la sincronización de Backbone serán las mismas. Pero no funcionarán para GET regular ya que tendrían que devolver JSON.

Así que estoy pensando, ¿sería una buena idea añadir la extensión al modelo URL/Colección en la espina dorsal, como .json, y en Express para tener esto para cada ruta:

app.get('/p/:topCategory/:category/:product.:format', function(req, res) { ... }); 

Dónde if (req.params.id == 'json') de enviamos JSON, de lo contrario, renderizamos HTML?

¿O hay un mejor enfoque? Por favor ayuda.

Respuesta

12

La mejor forma de hacer esto sería utilizar la función de negociación de contenido in exprés 3.x, a saber res.format:

https://github.com/visionmedia/express/blob/master/lib/response.js#L299-378

res.format({ 
    text: function(){ 
    res.send('hey'); 
    }, 

    html: function(){ 
    res.send('<p>hey</p>'); 
    }, 

    json: function(){ 
    res.send({ message: 'hey' }); 
    } 
}); 

enfoque que es también aceptable, Yammer por ej. utiliza el mismo enfoque: http://developer.yammer.com/api/#message-viewing

+0

Gracias por responder. Sin embargo, no encontré res.format() en documentos Express. Pero encontré req.is ('html') o req.is ('json'). Supongo que cualquiera de las dos debería funcionar, pero res.format() se ve mejor como su función y no es necesario usar if/else para res.is(). –

+0

Todavía no figura en la documentación porque Express 3.x es nuevo y el sitio debe actualizarse (eso sucederá muy pronto, hasta donde yo sé). – alessioalex

+0

voilà: http://expressjs.com/api.html#res.format – UpTheCreek

6

Use Accept encabezados en sus solicitudes: Accept: application/json si desea recibir JSON, Accept: text/HTML si desea HTML.

+0

¿Y cómo configuro esto en el lado del nodo? –

+0

Utiliza técnicas estándar de análisis de texto de JavaScript (expresiones regulares, etc.) para buscar en 'req.headers' cualquier cosa que comience por' Aceptar ::. La forma en que lo haría sería enviar una respuesta JSON si alguno de ellos está pidiendo JSON, y una respuesta HTML si ninguno de ellos es. – ebohlman

2

Una alternativa que también verifica que el encabezado "X-Solicitado-Con" esté configurado para jQuery et al.

var onlyAllowJsonRequests = function (req, res, next) { 

    var acceptJson = (req.accepted.length && _.any(req.accepted, function (acc) { return acc.value.indexOf("json") !== -1 })); 

    // also check that "X-Requested-With": "XMLHttpRequest" header is set 
    if (acceptJson && (req.xhr === true)) { 
     next(); 
    } else { 
     res.send(406, "Not Acceptable"); 
    } 
}; 

app.use(onlyAllowJsonRequests); 

NB underscore es una dependencia.

2

Creo que la forma correcta de hacerlo es implementar negociación de contenido en su aplicación. Sí, Express 3.x es una forma de hacerlo y proporciona una respuesta directa a su pregunta, pero no creo que sea la mejor manera de hacerlo, ya que coloca la responsabilidad de negociación de contenido en la lógica de enrutamiento. No creo que sea un buen lugar para ello porque no sigue el principio single responsibility, después de poner negociación de contenido en lógica de enrutamiento.

He tomado una puñalada en la implementación de negociación de contenido en mi blog engine; revisar eso podría ayudarlo a orientarse en una buena dirección. La esencia es que el código determina la extensión del archivo a través de negociación de contenido lógica. Luego, con la extensión de archivo, quiere encontrar el archivo de vista correspondiente, lo convierte en una respuesta y lo envía de vuelta al cliente. La idea es que responda con el recurso solicitado en la representación solicitada según la negociación de contenido. El routing logic solo especifica una vista, pero no tiene idea sobre la negociación de contenido. Eso ocurre fuera de la lógica de enrutamiento, lo que permite un diseño más flexible.

El resultado de este diseño es la posibilidad de pedir una representación específica del recurso como:

http://blog.joeyguerra.com/index.json y obtener una representación JSON http://blog.joeyguerra.com/index.phtml y obtener parcial (o un fragmento de HTML) HTML representación http://blog.joeyguerra.com/index.xml y obtener una representación XML.

Cuestiones relacionadas