2012-07-11 14 views
5

compiti fatto:URL nel Node.js

The Node Beginner Book

How do I get started with Node.js [closed]

Structuring handlers in Node

Backstory: Ho voluto provare a scrivere il mio quadro, ma sono in esecuzione in alcuni problemi , molto probabilmente a causa di non comprenderlo completamente.

Quello che voglio raggiungere è una sintassi che assomiglia a questo:

var app = require('./app'); //this part is understood and it works in my current code. 
app.get('/someUrl', function(){ //do stuff here }); 
app.post('/someOtherUrl', function(){ //do stuff here }); 

So del Express-quadro che ha questa stessa sintassi ma leggendo il loro codice sorgente ancora mi sfugge.

Questo potrebbe essere un compito banale da raggiungere, ma semplicemente non posso ancora produrlo.

Provare a require('./app'); in un file più profondo nell'applicazione produce un oggetto non definito, quindi suppongo che un server sia un oggetto singleton.

Quindi cosa ho provato?

Il mio codice attuale sembra così, e in qualche modo mi sembra che questa sia la strada da percorrere, ma a quanto pare non posso farlo in questo modo.

Sto omettendo tutte le istruzioni require(); per renderlo più leggibile.

server.js:

var app = module.exports = { 
    preProcess: function onRequest(request, response){ 
     processor.preRequest(request); //this object adds methods on the request object 
     var path = urllib.parse(request.url).pathname; 
     router.route(urls, path, request, response); 
    }, 
    createServer: function() { 
     console.log("Server start up done."); 
     return this.server = http.createServer(this.preProcess); 
    } 
}; 

exports.app = app; 

Al momento della scrittura sto sperimentando estendere questo oggetto con un metodo get().

index.js:

var app = require('./server'); 
app.createServer().listen('1337'); 

il bit router.route() e che sono inviati in pratica la richiesta avanti nell'applicazione e all'interno del router.js-file fare un po 'di magia e indirizzare la richiesta in poi a una funzione che mappa (finora) al/urlThatWasRequested

Questo è il comportamento che mi piacerebbe lasciare alle spalle. So che questo potrebbe essere un ordine piuttosto alto ma tutto il mio codice è facilmente scartato e non ho paura di riscrivere l'intero codice base in quanto questo è il mio progetto.

Spero che questo sia sufficiente per spiegare diversamente la mia domanda, per favore dì ciò che dovrei aggiungere per rendere questo un po 'più chiaro.

Grazie in anticipo!

risposta

11

Non sono esattamente sicuro di quello che la tua domanda è, ma ecco alcune riflessioni:

1) si sta creando un riferimento circolare qui:

var app = module.exports = { 
    // some other code 
} 
exports.app = app; 

si aggiunge app come una proprietà di app. Non c'è bisogno dell'ultima riga.

2) È necessario tenere gli handler in app. Si può provare qualcosa di simile:

var app = module.exports = { 
    handlers : [], 
    route : function(url, fn) { 
     this.handlers.push({ url: url, fn: fn }); 
    }, 
    preProcess: function onRequest(request, response){ 
     processor.preRequest(request); 
     var path = urllib.parse(request.url).pathname; 
     var l = this.handlers.length, handler; 
     for (var i = 0; i < l; i++) { 
      handler = this.handlers[i]; 
      if (handler.url == path) 
       return handler.fn(request, response); 
     } 
     throw new Error('404 - route does not exist!'); 
    }, 
    // some other code 
} 

Si noti che si può alterare questa linea: if (handler.url == path) in modo tale che handler.url è un'espressione regolare e si prova path contro di essa. Naturalmente è possibile implementare le varianti .get e .post, ma dalla mia esperienza è più facile verificare se una richiesta è GET o POSTall'interno del gestore. Ora è possibile utilizzare il codice precedente come questo:

app.route('/someUrl', function(req, res){ //do stuff here }); 

L'altra cosa è che il codice che ti ho mostrato spara solo il primo gestore per un determinato URL corrisponde. Probabilmente vorresti fare rotte più complesse che coinvolgono molti handler (cioè i middleware). L'architettura sarebbe un po 'diverso in quel caso, ad esempio:

preProcess: function onRequest(request, response){ 
    var self = this; 
    processor.preRequest(request); 
    var path = urllib.parse(request.url).pathname; 
    var l = self.handlers.length, 
     index = 0, 
     handler; 
    var call_handler = function() { 
     var matched_handler; 
     while (index < l) { 
      handler = self.handlers[index]; 
      if (handler.url == path) { 
       matched_handler = handler; 
       break; 
      } 
      index++; 
     } 
     if (matched_handler) 
      matched_handler.fn(request, response, function() { 
       // Use process.nextTick to make it a bit more scalable. 
       process.nextTick(call_handler); 
      }); 
     else 
      throw new Error('404: no route matching URL!'); 
    }; 
    call_handler(); 
}, 

Ora dentro il percorso è possibile utilizzare

app.route('/someUrl', function(req, res, next){ 
    //do stuff here 
    next(); // <--- this will take you to the next handler 
}); 

, che vi porterà a un altro gestore (o gettare un'eccezione se non ci sono più gestori).

3) A proposito di queste parole:

Cercando di richiedere ('./ app'); in un file più profondo nell'applicazione produce un oggetto non definito , quindi suppongo che un server sia un oggetto singleton.

Non è vero. require restituisce sempre il riferimento all'oggetto modulo. Se vedi undefined, hai incasinato qualcos'altro (alterato il modulo stesso?).

Nota finale: Spero che sia d'aiuto. Scrivere il proprio framework può essere un compito difficile, soprattutto perché esistono già framework eccellenti come Express. Buona fortuna però!

EDIT

Implementazione .get e .set metodi non è in realtà difficile. Hai solo bisogno di modificare route funzione come questa:

route : function(url, fn, type) { 
    this.handlers.push({ url: url, fn: fn, type: type }); 
}, 
get : function(url, fn) { 
    this.route(url, fn, 'GET'); 
}, 
post : function(url, fn) { 
    this.route(url, fn, 'POST'); 
}, 

e poi in algoritmo di routing di verificare se type proprietà è definita.In caso contrario, utilizzare tale percorso (tipo undefined: sempre percorso). Altrimenti controlla anche se il metodo di una richiesta corrisponde al tipo. E hai finito!

+0

Grazie per la risposta! :) La mia domanda era "Come produrre una sintassi .get(), .post()". Potrei dover modificare la domanda. Il motivo per cui mi piacerebbe astenermi dal controllare l'inserimento/inserimento nella funzione stessa è solo dovuto alla preferenza in questo progetto. Grazie per avermi indicato nella giusta direzione! :) Inoltre ho un file di gestori in cui aggiungo molti gestori che eseguono il mapping di funzioni con lo stesso nome, non sono sicuro che ciò sia stato reso chiaro. –

+0

@limelights vedo. Ho aggiornato la risposta! – freakish

+0

questa potrebbe essere una domanda totalmente idiota ma la proprietà dei gestori non è istallata, è solo indefinita. –