Forma correcta de devolver JSON usando node o Express


Por lo tanto, uno puede intentar obtener el siguiente objeto JSON:

$ curl -i -X GET http://echo.jsontest.com/key/value/anotherKey/anotherValue
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Content-Type: application/json; charset=ISO-8859-1
Date: Wed, 30 Oct 2013 22:19:10 GMT
Server: Google Frontend
Cache-Control: private
Alternate-Protocol: 80:quic,80:quic
Transfer-Encoding: chunked

{
   "anotherKey": "anotherValue",
   "key": "value"
}
$

¿Hay alguna forma de producir exactamente el mismo cuerpo en una respuesta de un servidor usando node o express? Claramente, uno puede establecer los encabezados e indicar que el tipo de contenido de la respuesta va a ser "application / json", pero entonces hay diferentes formas de escribir/enviar el objeto. El que he visto comúnmente se utiliza es mediante el uso de un comando de la forma:

response.write(JSON.stringify(anObject));

Sin embargo, esto tiene dos puntos donde uno podría argumentar como si fueran "problemas":

  • Estamos enviando una cadena.
  • Además, no hay un nuevo carácter de línea al final.

Otra idea es usar el comando:

response.send(anObject);

Esto parece estar enviando un objeto JSON basado en la salida de curl similar al primer ejemplo anterior. Sin embargo, no hay un nuevo carácter de línea en el final del cuerpo cuando curl se está utilizando de nuevo en un terminal. Entonces, ¿cómo se puede realmente escribir algo como esto con una nuevo carácter de línea añadido al final usando node o node / express?

Author: MightyMouse, 2013-10-31

5 answers

Esa respuesta también es una cadena, si desea enviar la respuesta embellecida, por alguna razón incómoda, podría usar algo como JSON.stringify(anObject, null, 3)

También es importante que establezcas el encabezado Content-Type en application/json.

var http = require('http');

var app = http.createServer(function(req,res){
    res.setHeader('Content-Type', 'application/json');
    res.send(JSON.stringify({ a: 1 }));
});
app.listen(3000);

// > {"a":1}

Embellecido:

var http = require('http');

var app = http.createServer(function(req,res){
    res.setHeader('Content-Type', 'application/json');
    res.send(JSON.stringify({ a: 1 }, null, 3));
});
app.listen(3000);

// >  {
// >     "a": 1
// >  }

No estoy exactamente seguro de por qué quieres terminarlo con una nueva línea, pero podrías hacer JSON.stringify(...) + '\n' para lograrlo.

Express

En express puedes hacer esto cambiando las opciones en cambio .

'json replacer' JSON replacer callback, null por defecto

'json spaces' Espacios de respuesta JSON para formatear, por defecto 2 en desarrollo, 0 en producción

No se recomienda establecer en 40

app.set('json spaces', 40);

Entonces podrías responder con un poco de json.

res.json({ a: 1 });

Usará la configuración 'json spaces' para embellecerla.

 433
Author: bevacqua,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-18 17:46:41

Desde Express.js 3x el objeto response tiene un método json () que establece todas las cabeceras correctamente y devuelve la respuesta en formato JSON.

Ejemplo:

res.json({"foo": "bar"});
 304
Author: JamieL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-05-07 12:17:52

Si está intentando enviar un archivo json, puede usar streams

var usersFilePath = path.join(__dirname, 'users.min.json');

apiRouter.get('/users', function(req, res){
    var readable = fs.createReadStream(usersFilePath);
    readable.pipe(res);
});
 16
Author: Connor Leech,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-08-26 20:19:59

Simplemente puede embellecerlo usando pipe y uno de los muchos procesadores. Tu app siempre debe responder con la menor carga posible.

$ curl -i -X GET http://echo.jsontest.com/key/value/anotherKey/anotherValue | underscore print

Https://github.com/ddopson/underscore-cli

 4
Author: pawelzny,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-07-06 07:10:03

Puede usar un middleware para establecer el Tipo de contenido predeterminado y establecer el tipo de contenido de manera diferente para determinadas API. He aquí un ejemplo:

const express = require('express');
const app = express();

const port = process.env.PORT || 3000;

const server = app.listen(port);

server.timeout = 1000 * 60 * 10; // 10 minutes

// Use middleware to set the default Content-Type
app.use(function (req, res, next) {
    res.header('Content-Type', 'application/json');
    next();
});

app.get('/api/endpoint1', (req, res) => {
    res.send(JSON.stringify({value: 1}));
})

app.get('/api/endpoint2', (req, res) => {
    // Set Content-Type differently for this particular API
    res.set({'Content-Type': 'application/xml'});
    res.send(`<note>
        <to>Tove</to>
        <from>Jani</from>
        <heading>Reminder</heading>
        <body>Don't forget me this weekend!</body>
        </note>`);
})
 0
Author: Yuci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-22 16:20:51