Passando o controle de rota com parâmetro opcional após root em express?

87

Estou trabalhando em um aplicativo simples de encurtamento de url e tenho as seguintes rotas expressas:

app.get('/', function(req, res){
  res.render('index', {
    link: null
  });
});

app.post('/', function(req, res){
  function makeRandom(){
    var text = "";
    var possible = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";

    for( var i=0; i < 3 /*y u looking at me <33??*/; i++ )
      text += possible.charAt(Math.floor(Math.random() * possible.length));
    return text;
  }
  var url = req.body.user.url;
  var key = makeRandom();
  client.set(key, url);
  var link = 'http://50.22.248.74/l/' + key;
  res.render('index', {
    link: link
  });
  console.log(url);
  console.log(key);
});

app.get('/l/:key', function(req, res){
  client.get(req.params.key, function(err, reply){
    if(client.get(reply)){
      res.redirect(reply);
    }
    else{
      res.render('index', {
        link: null
      });
    }
  });
});

Eu gostaria de remover o /l/da minha rota (para tornar o meu url mais curto) e tornar o parâmetro: key opcional. Esta seria a maneira correta de fazer isso:

app.get('/:key?', function(req, res, next){
  client.get(req.params.key, function(err, reply){
    if(client.get(reply)){
      res.redirect(reply);
    }
    else{
      next();
    }
  });
});

app.get('/', function(req, res){
  res.render('index, {
    link: null
  });
});

Não tenho certeza se preciso especificar que minha /rota será a "próxima". Mas como minha única outra rota seria minha /rota de postagem atualizada , imagino que funcionaria bem.

Qcom
fonte

Respostas:

193

Isso funcionaria dependendo do que client.get faz quando passado undefined como seu primeiro parâmetro.

Algo assim seria mais seguro:

app.get('/:key?', function(req, res, next) {
    var key = req.params.key;
    if (!key) {
        next();
        return;
    }
    client.get(key, function(err, reply) {
        if(client.get(reply)) {
            res.redirect(reply);
        }
        else {
            res.render('index', {
                link: null
            });
        }
    });
});

Não há problema em chamar next () dentro do retorno de chamada.

De acordo com isso , os manipuladores são chamados na ordem em que são adicionados, portanto, desde que sua próxima rota seja app.get ('/', ...), ela será chamada se não houver chave.

Ernesto Badillo
fonte
Obrigado, cara. Sua alternativa também é apreciada. Infelizmente, tenho outro problema, mas acho que, como você apontou, é o resultado do que foi retornado por client.get. Eu recebo um cannot call method 'indexOf' of nullerro.
Qcom
Além disso, seria possível ligar next()para o else{}?
Qcom
Desculpem o commentfest lol. Consertou, mas está super jank xD
Qcom
1

Versão Express:

"dependencies": {
    "body-parser": "^1.19.0",
    "express": "^4.17.1"
  }

Parâmetros opcionais são muito úteis, você pode declará-los e usá-los facilmente usando express:

app.get('/api/v1/tours/:cId/:pId/:batchNo?', (req, res)=>{
    console.log("category Id: "+req.params.cId);
    console.log("product ID: "+req.params.pId);
    if (req.params.batchNo){
        console.log("Batch No: "+req.params.batchNo);
    }
});

No código acima, batchNo é opcional. O Express contará como opcional porque após a construção da URL, eu dei um '?' símbolo após batchNo '/: batchNo?'

Agora posso chamar apenas com categoryId e productId ou com todos os três parâmetros.

http://127.0.0.1:3000/api/v1/tours/5/10
//or
http://127.0.0.1:3000/api/v1/tours/5/10/8987

insira a descrição da imagem aqui insira a descrição da imagem aqui

senhor
fonte