2012-07-11 18 views
5

deberes hechos:URL en Node.js

The Node Beginner Book

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

Structuring handlers in Node

Historia: quería probar y escribir mi propio marco, pero estoy corriendo en dificultades , muy probablemente debido a que no se entiende completamente.

Lo que queremos lograr es una sintaxis que tiene este aspecto:

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 }); 

que sé del Express-marco que tiene esta misma sintaxis, pero la lectura de su código fuente todavía me elude.

Esto podría ser una tarea trivial pero todavía no puedo producirlo.

Intentando require('./app'); en un archivo más profundo en la aplicación produce un objeto indefinido, así que supongo que un servidor es un objeto singleton.

¿Qué he probado?

Mi código actual se ve así, y de alguna manera siento que este es el camino a seguir, pero aparentemente no puedo hacerlo así.

Estoy omitiendo todas las declaraciones require(); para que sea más legible.

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; 

En el momento de la escritura que estoy experiencias de prolongación de este objeto con un método get().

index.js:

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

el bit router.route() envía la solicitud básicamente en adelante en la aplicación y en el interior del router.js-archivo que hago un poco de magia y enrutar la solicitud hacia adelante a una función que mapea (hasta ahora) para/urlThatWesRequested

Este es el comportamiento que me gustaría dejar atrás. Sé que esto puede ser un pedido bastante difícil, pero todo mi código es fácilmente descartable y no tengo miedo de volver a escribir todo el código, ya que este es mi propio proyecto.

Espero que esto sea suficiente para explicar mi pregunta, de lo contrario, indique lo que debería agregar para que quede un poco más claro.

¡Gracias de antemano!

Respuesta

11

No estoy exactamente seguro de lo que su pregunta es, pero aquí hay algunas ideas:

1) va a crear una referencia circular aquí:

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

añades app como una propiedad de app. No hay necesidad de la última línea.

2) Necesita manipular controladores en app. Usted puede intentar algo como esto:

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 
} 

Tenga en cuenta que puede alterar esta línea: if (handler.url == path) de tal manera que handler.url es una expresión regular y se prueba path contra ella. Por supuesto, puede implementar las variantes .get y .post, pero desde mi experiencia es más fácil comprobar si una solicitud es GET o POSTdentro del controlador. Ahora puede utilizar el código anterior como esto:

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

La otra cosa es que el código que le he mostrado sólo dispara el primera controlador para una determinada URL coincide. Probablemente desee hacer rutas más complejas que involucren a muchos manejadores (es decir, middlewares). La arquitectura sería un poco diferente en ese caso, por ejemplo:

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(); 
}, 

Ahora dentro de su recorrido se pueden utilizar

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

que le llevará a otro controlador (o lanzar una excepción si no hay más controladores).

3) Sobre estas palabras:

Tratando de require ('./ aplicación'); en un archivo más profundo en la aplicación produce un objeto indefinido , así que supongo que un servidor es un objeto singleton.

No es cierto. require siempre devuelve la referencia al objeto del módulo. Si ve undefined, entonces ha arruinado otra cosa (¿ha alterado el módulo?).

Nota final: Espero que ayude un poco. Escribir su propio marco puede ser un trabajo difícil, especialmente porque ya hay marcos excelentes como Express. Buena suerte!

EDITAR

La implementación .get y .set métodos no es realmente difícil. Sólo tiene que alterar route función como esta:

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'); 
}, 

y luego en el algoritmo de encaminamiento que comprobar si type propiedad se define.Si no es así, utilice esa ruta (undefined mecanografíe significa: siempre ruta). De lo contrario, compruebe también si el método de una solicitud coincide con el tipo. ¡Y tu estas listo!

+0

¡Gracias por la respuesta! :) Mi pregunta fue "Cómo producir una sintaxis .get(), .post()". Podría tener que alterar la pregunta. La razón por la cual me gustaría abstenerme de verificar para obtener/publicar en la función en sí es solo por preferencia en este proyecto. ¡Gracias por señalarme en la dirección correcta! :) También tengo un archivo de controladores donde agrego muchos manejadores que se asignan a funciones con el mismo nombre. No estoy seguro si eso quedó claro. –

+0

@limelights Veo. ¡He actualizado la respuesta! – freakish

+0

esto podría ser una pregunta totalmente idiota pero la propiedad de controladores no está instalada, no está definida. –