6

Корректный способ вернуть JSON с использованием Node.js или Express

30

Я пытаюсь извлечь следующий 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"
}
$

Возможно ли получить точно такой же ответ от сервера, используя Node.js или Express? Очевидно, что можно установить заголовки и указать, что content-type ответа будет "application/json", но существует несколько способов передачи объекта. Наиболее распространенный способ, который я видел, это использование команды:

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

Однако здесь есть два момента, которые можно назвать "проблемами":

  1. Мы отправляем строку.
  2. Кроме того, в конце отсутствует символ новой строки.

Другой возможный подход — использовать команду:

response.send(anObject);

Кажется, что это отправляет JSON-объект, который по своему выходу аналогичен первому примеру. Однако при повторном выполнении curl в терминале также не появляется символа новой строки в конце тела ответа. Как можно добиться такого же результата с добавленным символом новой строки в конце, используя Node.js или Express?

5 ответ(ов)

5

Начиная с версии Express.js 3.x, объект ответа (response object) имеет метод json(), который автоматически устанавливает все необходимые заголовки и возвращает ответ в формате JSON.

Пример использования:

res.json({"foo": "bar"});

Этот метод упрощает процесс отправки JSON-ответов и обеспечивает корректную настройку заголовков, таких как Content-Type: application/json.

0

Если вы используете Express, вы можете сделать это следующим образом:

res.setHeader('Content-Type', 'application/json');
res.send(JSON.stringify({key: "value"}));

или просто так:

res.json({key: "value"});

Второй способ более предпочтителен, так как res.json автоматически устанавливает заголовок Content-Type и преобразует объект в JSON.

0

Если вы пытаетесь отправить JSON-файл, вы можете использовать потоки. Вот пример:

var fs = require('fs');
var path = require('path');

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

apiRouter.get('/users', function(req, res){
    var readable = fs.createReadStream(usersFilePath);
    readable.pipe(res);
});

В этом коде создается читаемый поток из файла users.min.json, и затем этот поток передается напрямую в ответ (res). Таким образом, данные JSON будут отправлены клиенту.

0

Вы можете создать вспомогательную функцию для этого, чтобы использовать её везде в приложении. Вот пример такой функции:

function getStandardResponse(status, message, data) {
    return {
        status: status,
        message: message,
        data: data
    }
}

Вот маршрут для получения всех тем:

router.get('/', async (req, res) => {
    const topics = await Topic.find().sort('name');
    return res.json(getStandardResponse(true, "", topics));
});

Ответ, который мы получаем, будет выглядеть следующим образом:

{
    "status": true,
    "message": "",
    "data": [
        {
            "description": "sqswqswqs",
            "timestamp": "2019-11-29T12:46:21.633Z",
            "_id": "5de1131d8f7be5395080f7b9",
            "name": "topics test xqxq",
            "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575031579309.jpg",
            "category_id": "5de0fe0b4f76c22ebce2b70a",
            "__v": 0
        },
        {
            "description": "sqswqswqs",
            "timestamp": "2019-11-29T12:50:35.627Z",
            "_id": "5de1141bc902041b58377218",
            "name": "topics test xqxq",
            "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575031835605.jpg",
            "category_id": "5de0fe0b4f76c22ebce2b70a",
            "__v": 0
        },
        {
            "description": " ",
            "timestamp": "2019-11-30T06:51:18.936Z",
            "_id": "5de211665c3f2c26c00fe64f",
            "name": "topics test xqxq",
            "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575096678917.jpg",
            "category_id": "5de0fe0b4f76c22ebce2b70a",
            "__v": 0
        },
        {
            "description": "null",
            "timestamp": "2019-11-30T06:51:41.060Z",
            "_id": "5de2117d5c3f2c26c00fe650",
            "name": "topics test xqxq",
            "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575096701051.jpg",
            "category_id": "5de0fe0b4f76c22ebce2b70a",
            "__v": 0
        },
        {
            "description": "swqdwqd wwwwdwq",
            "timestamp": "2019-11-30T07:05:22.398Z",
            "_id": "5de214b2964be62d78358f87",
            "name": "topics test xqxq",
            "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575097522372.jpg",
            "category_id": "5de0fe0b4f76c22ebce2b70a",
            "__v": 0
        },
        {
            "description": "swqdwqd wwwwdwq",
            "timestamp": "2019-11-30T07:36:48.894Z",
            "_id": "5de21c1006f2b81790276f6a",
            "name": "topics test xqxq",
            "thumbnail": "waterfall-or-agile-inforgraphics-thumbnail-1575099408870.jpg",
            "category_id": "5de0fe0b4f76c22ebce2b70a",
            "__v": 0
        }
    ]
}

Таким образом, вы можете удобно обрабатывать стандартные ответы в вашем приложении, что обеспечивает стандартизацию и упрощает код.

0

Вы можете просто отформатировать вывод с помощью pipe и одного из многих процессоров. Ваше приложение должно всегда возвращать ответ с минимальной нагрузкой.

Вот пример команды, которую можно использовать:

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

Ссылка на инструмент: underscore-cli на GitHub.

Чтобы ответить на вопрос, пожалуйста, войдите или зарегистрируйтесь