2017-02-20 47 views
0

Я построил, используя express(), различные методы. для простоты позвольте мне предположить, что я построил 2 функции POST(), и я хочу иметь возможность использовать их самостоятельно, а также объединить их через промежуточное программное обеспечение для использования в комбайне.NODEJS как подключить несколько express.method() через промежуточное программное обеспечение

app.post('/create_obj_1' , function (req,res) { 
    //create Object_type_1 
    // send Object_type_1 via EXTERNAL API to somewhere 
    res.json({{ "statusCode": 200, "message": "OK" } 
} 
app.post('/create_obj_2' , function (req,res) { 
    //create Object_type_2 
    // send Object_type_2 via EXTERNAL API to somewhere 
    res.json({{ "statusCode": 200, "message": "OK" } 
} 

Я хочу иметь новый пост(), который может вызвать оба 2 других (но по-прежнему поддерживать автономный производит вызов оригинальной 2 я думаю, что это возможно с помощью промежуточного слоя, но я не знаю, как - это то, как я думал, что новый POST() должен выглядеть -

app.post('/create_obj_all' , function (req,res) { 
    //I want to invoke the create_obj_1 & create_obj_2 , check all OK, and finish 
    res.json({{ "statusCode": 200, "message": "OK" } 
} 

Я не уверен, как подходить к использованию промежуточного слоя в таком случае

сверху -. как я могу подключить их использовать по одному другие res? скажем, EXTERNAL API возвращает некоторое значение из obj_1 создание, которое я хочу использовать в obj_2 пост() функции ..

псевдокэлеровой код моей попытки использовать запрос() внутри middlware_1 -

var middle_1 = function (req, res, next) { 
     req.middle_1_output = { 
      statusCode : 404, 
      message : "fail_1" 
     } 
     var options = { 
       method: 'PUT', url: `EXTERNAL_API`, headers: 
       { 
        'cache-control': 'no-cache', 
        'content-type': 'application/x-www-form-urlencoded', 
        apikey: `KEY` 
       } 
      }; 
     request(options, function (error, response, body) { 
      if (error) throw new Error(error); 

      // CODE THAT DO SOMETHING AND GET INFORMATION 

      // OLD WAY OF res.send here , to allow using in post.POST() was - res.status(200).send(body); 

      //res.status(200).send(body); 
      req.middle_1_output.statusCode = 200; 
      req.middle_1_output.message = "hello world"; 
     }); 
    next(); // trigger next middleware 
} 
+0

Вы должны вызвать 'next' из обратного вызова, как это было сделано в моем втором примере. В вашем случае следующее промежуточное программное обеспечение вызывается перед завершением 'request'. –

+0

Hey Blaze, я думаю, что он начинает работать, но у меня возникла проблема с этим, так как я использую 2 request() внутри своего middleware_1 (один за другим), поэтому я думаю, что называть next() в конце 1-го request() создает проблему для второго запроса(), так как я получаю сообщение об ошибке req.middle_1_output.statuscode is undefined, когда я пытаюсь присвоить ему значение в конце второго запроса(). Могу ли я включить свой первый запрос() в middleware_1 также в промежуточное ПО? –

+0

Обновите свой вопрос, я отвечу, отредактировав свой последний ответ. –

ответ

0

Учитывая текущий пример, я не думаю, что вы можете сделать это, если вы не подправить промежуточное программное для первых двух маршрутов немного:

var middleware1 = function(req, res, next) { 
    //create Object_type_1 
    // send Object_type_1 via EXTERNAL API to somewhere 

    next(); // calling next() triggers the next middleware 
}; 

var middleware2 = function(req, res, next) { 
    //create Object_type_2 
    // send Object_type_2 via EXTERNAL API to somewhere 

    next(); // calling next() triggers the next middleware 
}; 

/** 
* This middleware is only used to send success response 
*/ 
var response_success = function(req, res) { 

    res.json({ "statusCode": 200, "message": "OK" }); 
} 

app.post('/create_obj_1', middleware1, response_success); 

app.post('/create_obj_2', middleware2, response_success); 

app.post('/create_obj_all', middleware1, middleware2, response_success); 

Примечание, что это очень упрощенно решение, которое я сделал из вашего примера. Фактическая реализация будет зависеть от того, какой вклад ожидает каждое промежуточное ПО и какой результат они генерируют. Кроме того, в отличие от здесь, могут быть разные посредники для отправки ответа.

второй части Обращаясь к второй части вашего вопроса, если я правильно вас есть вы хотите передать выход из middleware1 в middleware2. Вы можете просто присоединить вывод к объекту req перед вызовом next();. Как так:

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

    // do something 

    some_external_api_call(function(error, data) { 

    if (error) { 
     // handle the error yourself or call next(error); 
    } else { 

     req.middleware1_output = data; // set the output of the external api call into a property of req 
     next(); 
    } 
    }); 
}; 

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

    // check to see if the middleware1_output has been set 
    // (meaning that the middleware has been called from /create_obj_all) 
    if (req.middleware1_output) { 

    // do something with the data 

    } else { 

    // handle scenario when /create_obj_2 is called by itself 

    } 

    next(); // calling next() triggers the next middleware 
}; 

Обратите внимание, как вы должны учитывать для обоих сценариев, где middleware2 вызывается из POST /create_obj_all или непосредственно из POST /create_obj_2.

3-я часть Вы можете позвонить по телефону next из обратного вызова. См. Мой пример выше. Это связано с асинхронным/неблокирующим характером javascript.

function middleware(req, res, next) { 

    // do something 

    call_1st_external_api(some_options, function(error, data) { 

     // executed after call_1st_external_api completes 

     req.output_of_1st_external_api = data; // store the data of this api call for access from next middleware 

     next(); // calls the next middleware 

     // nothing here will be executed as next has already been called 
    }); 

    // anything here will be executed before call_1st_external_api is completed 
    next(); // this will call the next middleware before call_1st_external_api completes 
} 

Для обработки два внешних API, в одних и том же промежуточном программных вы должны вкладывать их (или использовать асинхра или обещание):

function middleware(req, res, next) { 

    // do something 

    call_1st_external_api(some_options, function(error1, data1) { 

     // executed after call_1st_external_api completes 

     req.output_of_1st_external_api = data1; // store the data of this api call for access from next middleware 

     // executed after call_2nd_external_api completes 

     call_2nd_external_api(some_options, function(error2, data2) { 

      req.output_of_2nd_external_api = data2; // store the data of this api call for access from next middleware 

      next(); 
     }); 

     // anything here will be executed before call_2nd_external_api is completed 
    }); 

    // anything here will be executed before call_1st_external_api is completed 
} 

Вы должны обработать все ошибки выше, как я показал в 2-я часть, которую я не показал в приведенном выше примере для простоты.

+0

Эй, пылайте, большое спасибо. Я буду стараться как можно скорее. –

+0

Уверенный Блейз, я сделаю. в любом случае, я пробовал это решение, но получаю ошибку, которую я предполагаю из-за дескриптора ошибки res.send в каждом промежуточном программном обеспечении. Это ошибка, которую я получаю - throw new Error ('Can \' t установить заголовки после их отправки. '); Проблема заключается в том, что: 1. Внутри каждого моего моего промежуточного программного обеспечения используется модуль request() для вызова внешнего API. 2. В конце функции обратного вызова запроса у меня есть эта строка: res.status (200) .send (body); \t Вопрос в том, как мне его изменить? Есть идеи? –

+0

Вместо вызова 'res.send' из каждого промежуточного программного обеспечения, вызовите' next'. Создайте отдельное промежуточное программное обеспечение только для вызова 'res.send' и присоедините его, как в приведенных выше примерах. –