Почему h.response возвращает строку вместо объекта в HapiJS?

#javascript #node.js #http #hapi

Вопрос:

Я создаю API с помощью HapiJS, используя TDD, я получаю сообщение об ошибке, потому что тест проверяет полезную нагрузку запроса, любопытно, что я получаю строку вместо объекта, как указано в документации.

Это мой тест, написанный с помощью @hapi /lab:

 it('payload should be a json object', async () => {
    const res = await server.inject({
      method: 'GET',
      url: '/users'
    })
    console.log(res)
    expect(res.payload).to.be.object()
  })
 

и это мой маршрут:

 server.route({
  method: 'GET',
  path: '/users',
  handler: (request, h) => {
    const data = {
      message: 'App'
    }

    const response = h
      .response(data)
      .type('application/json')
      .header('content-type', 'application/json')
      .code(200)
    
    return response
  }
})
 

Кстати, эта консоль.войдите в систему тест предназначен для подтверждения содержимого res.payload и проверки того, что он получал строку вместо объекта.

Это конкретная ошибка, которую я получаю из теста: Expected '{"message":"App"}' to be an object but got 'string'

Комментарии:

1. Согласно документации, это строка: «полезная нагрузка — строка полезной нагрузки ответа «.. Возможно, вы смотрели на определение payload inject() параметров, которое является «полезная нагрузка — (необязательно) строка, буфер или объект, содержащий полезную нагрузку запроса «.

2. Вы правы. Итак, если inject может содержать строку, буфер или объект, как я могу установить объект с помощью маршрута HapiJS?

Ответ №1:

Свойство, которое вы ищете, находится result в response объекте, который вы получаете из inject метода.

payload это данные из конечной точки, hapi которые будут отправлены клиенту, что означает, что они были сериализованы. Вот почему вы получаете строку. Вместо result этого свойство представляет собой необработанные данные, возвращаемые из конечной точки перед сериализацией. Более подробную информацию вы можете найти в документации в этом return разделе.

Вот фрагмент кода, демонстрирующий это:

 const Hapi = require("@hapi/hapi");

const server = Hapi.Server();

server.route({
  method: "GET",
  path: "/test",
  options: {
    handler(req, h) {
      return { result: 1 };
    },
  },
});

(async function () {
  await server.start();

  console.log("server started");

  const res = await server.inject({
    method: "GET",
    url: "/test",
  });

  console.log(res.payload); // ==> '{"result": 1}'
  console.log(res.result); // ==> { result: 1 }
})();
 

Кроме того, чтобы ответить на один из сделанных вами комментариев, вы фактически уже отправили объект со своего hapi сервера. Просто данные были сериализованы. Вам нужно будет десериализовать его в любом контексте, в котором вы будете вызывать свою конечную точку, JSON.parse() например, с помощью, прежде чем вы сможете его использовать.