Scopri il Framework Connect

I neofiti di NodeJS in genere trovano difficile comprendere la propria API. Fortunatamente, molti sviluppatori hanno creato framework che rendono più semplice lavorare con Node. Connect è uno di questi framework. Si trova in cima alle API di Node e traccia la linea tra comfort e controllo.

Pensa a Connect come a una pila di middleware. Con ogni richiesta, connetti i filtri attraverso i livelli del middleware, ognuno con l'opportunità di elaborare la richiesta HTTP. Quando T.J. Holowaychuk ha annunciato Connect, ha detto che c'erano due tipi di middleware. Il primo è a filtro.

I filtri elaborano la richiesta, ma non rispondono (si pensi alla registrazione del server).

L'altro tipo è a fornitore, che risponde alla richiesta. Puoi incorporare tutti gli strati di middleware che vuoi; la richiesta passa attraverso ogni livello fino a quando uno dei middleware risponde alla richiesta.


Sintassi di base

Innanzitutto, è necessario installare il pacchetto Connect tramite npm:

npm install connect

Ora crea un server.js file e aggiungi il seguente codice:

var connect = require ("connect");

Il Collegare variabile è una funzione che restituisce una nuova applicazione Connect. Quindi, il nostro prossimo passo è creare quell'app:

var app = connect ();

Non è necessario creare un App variabile per la maggior parte delle tue applicazioni. Le funzioni coinvolte nella creazione di un'applicazione (Collegare() e uso()) sono concatenabili:

connect () .use (/ * middleware * /) .use (/ * middleware * /) .listen (3000);

Il uso() la funzione aggiunge uno strato di middleware all'applicazione e il ascolta() la funzione dice alla nostra applicazione di iniziare ad accettare le connessioni sulla porta specificata (3000 in questo esempio).

Iniziamo con qualcosa di semplice: la registrazione. Il codice per un'applicazione Connect che utilizza solo il middleware di registrazione è piuttosto semplice:

connect () .use (connect.logger ()) .listen (3000);

Per impostazione predefinita, il nodo analizza molto poco della richiesta in arrivo.

Aggiungi quel codice al tuo file e avvia il server eseguendo nodo server.js. Passare a qualsiasi percorso nel browser e ignorare i risultati "Impossibile ottenere ...". Non siamo interessati a ciò che il server ha restituito al browser; siamo interessati al registro del server. Guarda il terminale e vedrai il registro delle tue richieste. Assicurati di controllare la documentazione del logger per informazioni sulle sue altre funzionalità e personalizzazioni.

Quello era un filtro; ora diamo un'occhiata a un fornitore. Il provider più semplice è il provider statico; serve i file statici da una cartella specificata. Ecco la sua sintassi:

.utilizzare (connect.static (__ dirname + "/ public")

Probabilmente puoi indovinare lo scopo di Node __dirname variabile: è il percorso della directory corrente. Questo middleware serve in modo statico qualsiasi cosa a partire da a pubblico cartella nella directory corrente. Quindi, crea pubblico / page.html e aggiungere un

elemento. Riavvia il server (nodo server.js), e vai a localhost: 3000 / page.html nel tuo browser. Dovresti page.html reso nel browser.

Diamo ora un'occhiata ad alcune delle altre opzioni di middleware di Connect.


Parsing Request Bodies

Per impostazione predefinita, il nodo analizza molto poco la richiesta in arrivo, ma è possibile incorporare diversi filtri diversi per analizzare la richiesta se è necessario gestire una maggiore complessità. Ci sono quattro filtri:

  • connect.json () analizza i corpi delle richieste JSON (dove il tipo di contenuto è application / json).
  • connect.urlencoded () analizza x-ww-form-urlencoded richiesta di corpi.
  • connect.multipart () analizza / Form-data multipart richiesta di corpi.
  • connect.bodyParser () è una scorciatoia per abilitare tutti e tre i precedenti.

L'utilizzo di uno qualsiasi di questi filtri ti dà la possibilità di accedere al tuo corpo analizzato tramite request.body (parleremo di come ottenerlo richiesta oggetto presto).

Penso che questi filtri siano un buon esempio di come perfezionare il tuo controllo con Connect. È possibile utilizzare pochissime elaborazioni per semplificare l'applicazione.


Parsing Cookies and Sessions

I cookie e le sessioni sono una parte importante di qualsiasi applicazione web e ci sono diversi middleware che aiutano a gestirli. Il connect.cookieParser () analizza i cookie per te e puoi recuperare i cookie e i loro valori tramite il Request.Cookies oggetto. Questo è più utile se aggiungi il connect.session () filtrare sulla tua app. Questo filtro richiede che il parser dei cookie sia già presente. Ecco un piccolo esempio:

connect () .use (connect.cookieParser ()) .use (connect.session (secret: 'some secret text', cookie: maxAge: 30000)) .use (function (req, res) var sess = req.session, url = req.url.split ("/"); if (url [1] == "nome" && url [2]) sess.name = url [2]; res.end (" nome salvato: "+ url [2]); else if (sess.name) res.write (" nome di sessione memorizzato: "+ sess.name); res.end (" memorizzato per un altro: "+ (sess .cookie.maxAge / 1000) + "seconds"); else res.end ("nessun nome memorizzato; vai a / nome / nome per salvare un nome");). ascolta (3000);

Ogni funzione middleware che scrivi deve passare la richiesta a Il prossimo strato o rispondere alla richiesta.

Dopo il cookieParser, includiamo il sessione filtrare e passargli due opzioni:

  • Il segreto crea un cookie firmato che tiene traccia della sessione.
  • Il cookie.maxAge definisce la sua durata in millisecondi; il 30000 in questo codice è di 30 secondi.

Nel finale uso() chiama, passiamo una funzione che risponde alla richiesta. Usiamo due proprietà dal richiesta oggetto: req.session per i dati di sessione, e req.url per l'URL della richiesta.

Se l'applicazione riceve una richiesta per / Nome / some_name, quindi memorizza il valore some_name nel req.session.name. Tutto ciò che è memorizzato all'interno di una sessione può essere recuperato in richieste successive per la durata della nostra sessione. Qualsiasi richiesta fatta per / Nome / altro sostituisce la variabile di sessione e qualsiasi richiesta ad altri URL restituisce il valore della variabile di sessione e il tempo rimanente per la sessione.

Quindi, puoi navigare localhost: 3000 / nome / your_name, e poi andare a localhost: 3000 vedere il tuo nome. Aggiorna la pagina alcune volte e osserva il conto alla rovescia dei secondi. Alla scadenza della sessione, verrà visualizzato il messaggio predefinito "nessun nome memorizzato".

Ho detto che il cookieParser il filtro deve venire prima sessione.

L'ordine di inclusione è importante con il middleware perché la richiesta viene passata, in ordine, da un livello all'altro.

Perché sessione ha bisogno dei dati dei cookie analizzati, la richiesta deve passare cookieParser prima sessione.

Potrei spiegare ogni altro pezzo di middleware incorporato, ma ne citerò qualche altro prima di scrivere il nostro codice per interfacciarlo con Connect.

  • comprimere: middleware di compressione Gzip
  • basicAuth: autenticazione HTTP di base
  • directory: directory che elenca il middleware
  • errorHandler: gestore di errori flessibile

Scrivere il tuo stesso middleware

Hai appena imparato a scrivere il tuo codice con Connect. Ecco di nuovo la sintassi di base:

.use (funzione (req, res, next) )

I tre parametri della funzione sono importanti; forniscono accesso al mondo esterno. Il req parametro è, ovviamente, l'oggetto richiesta, e res è la risposta. Il terzo parametro, Il prossimo, è la chiave per creare funzioni che funzionano bene nello stack middleware. È una funzione che passa la richiesta al middleware successivo nello stack. Vedi questo esempio:

connect () .use (function (req, res, next) if (req.method === 'POST') res.end ("Questa è una richiesta POST"); else next (); ) .use (function (req, res) res.end ("Questa non è una richiesta POST (probabilmente una richiesta GET)");). listen (3000);

Questo codice utilizza due funzioni middleware. La prima funzione controlla il metodo di richiesta per vedere se si tratta di una richiesta POST. Se lo è, risponde dicendo così. Altrimenti, chiamiamo Il prossimo() e passare la richiesta alla funzione successiva, che risponde a prescindere da cosa. Uso arricciare per testare entrambi i livelli nel terminale:

$ curl http: // localhost: 3000 Questa non è una richiesta POST (probabilmente una richiesta GET) $ curl -X POST http: // localhost: 3000 Questa è una richiesta POST

Se non ti piace il terminale, prova questo utile plugin di Chrome.

È importante ricordare che ogni funzione middleware che scrivi deve passare la richiesta a Il prossimo strato o rispondere alla richiesta. Se la tua funzione si dirama (tramite se dichiarazioni o altri condizionali), devi assicurarti che ogni filiale superi la richiesta o risponda ad essa. Se la tua app si blocca nel browser, è probabilmente perché ti sei dimenticato di chiamare Il prossimo() ad un certo punto.

Ora, che dire di quelli richiesta e risposta parametri? Questi sono gli stessi oggetti di richiesta e risposta che si ricevono quando si utilizza un server del nodo "raw":

require ("http"). createServer (function (req, res) // ...). listen (3000);

Se non hai mai utilizzato l'API del server di Node, lascia che ti mostri cosa puoi fare con esso.


L'oggetto della richiesta

Il richiesta l'oggetto è in realtà un http.IncomingMessage oggetto e le sue importanti proprietà sono elencate di seguito ::

  • req.method ti dice quale metodo HTTP è stato utilizzato.
  • req.url ti dice quale URL è stato richiesto.
  • req.headers è un oggetto con i nomi e i valori dell'intestazione.
  • req.query è un oggetto con qualsiasi dato in una stringa di query (per analizzarlo, avrai bisogno di connect.query () middleware in atto).
  • req.body è un oggetto dei dati del modulo (avrete bisogno di un po 'di body parsing del middleware in atto).
  • req.cookies è un oggetto dei dati del cookie (richiede l'analisi dei cookie).
  • req.session è un oggetto dei dati di sessione (di nuovo, avrete bisogno di analisi dei cookie e middleware di sessione in atto)

Puoi vedere tutto questo al lavoro con il seguente codice:

connect () .use (connect.query ()) // ci fornisce req.query .use (connect.bodyParser ()) // ci fornisce req.body .use (connect.cookieParser ()) // per sessione .use (connect.session (secret: "asdf")) // ci fornisce req.session .use (function (req, res) res.write ("req.url:" + req.url + "\ n \ n "); res.write (" req.method: "+ req.method +" \ n \ n "); res.write (" req.headers: "+ JSON.stringify (req.headers) +" \ n \ n "); res.write (" req.query: "+ JSON.stringify (req.query) +" \ n \ n "); res.write (" req.body: "+ JSON.stringify (rich. body) + "\ n \ n"); res.write ("req.cookies:" + JSON.stringify (req.cookies) + "\ n \ n"); res.write ("req.session:" + JSON.stringify (req.session)); res.end ();). Listen (3000);

Per visualizzare qualcosa per ciascuno di questi valori, è necessario pubblicare alcuni dati in un URL con una stringa di query. Il seguente dovrebbe essere sufficiente:

curl -X POST -d "name = YourName" "http: // localhost: 3000 / some / url? some = data"

Con queste sette proprietà, puoi gestire quasi tutte le richieste che riceverai. Non penso che i trailer siano usati spesso (non li ho mai visti nella mia esperienza), ma puoi usarli req.trailers se li aspetti nelle tue richieste (i trailer sono come le intestazioni, ma dopo il corpo).

Quindi, per quanto riguarda la tua risposta?


L'oggetto risposta

L'oggetto risposta grezza non fornisce i lussi che le librerie (come Express) ti offrono. Ad esempio, non è possibile rispondere con una semplice chiamata di rendering a un modello premade, almeno, non per impostazione predefinita. Nella risposta si assume molto poco, quindi è necessario inserire tutti i piccoli dettagli.

Inizieremo con il codice di stato e le intestazioni di risposta. È possibile impostare tutto in una volta utilizzando il writeHead () metodo. Ecco un esempio dei documenti Node:

var body = 'ciao mondo'; response.writeHead (200, 'Content-Length': body.length, 'Content-Type': 'text / plain');

Se è necessario impostare singolarmente le intestazioni, è possibile utilizzare il SetHeader () metodo:

connect () .use (function (req, res) var accept = req.headers.accept.split (","), body, type; console.log (accept); if (accept.indexOf ("application / json ")> -1) type =" application / json "; body = JSON.stringify (message:" ciao "); else if (accept.indexOf (" text / html ")> -1) tipo = "text / html"; body = "

Ciao!

"; else type =" text / plain "; body =" ciao! "; res.statusCode = 200; res.setHeader (" Content-Type ", type); res.end (body);). ascoltare (3000);

Aggiungi questo codice a un file, avvia il server e richiedilo dal browser. Hai l'HTML! Ora esegui:

curl http: // localhost: 3000

E riceverai un testo normale. Per JSON, prova questo:

curl -H "accetta: application / json" http: // localhost: 3000

Tutto dallo stesso URL!

Uso res.getHeader (nome) se hai bisogno di sapere quali intestazioni sono già state impostate. Puoi anche usare res.removeHeader (nome) rimuovere un'intestazione.

Certo, una risposta è inutile senza un corpo. Come hai visto in questo tutorial, puoi scrivere blocchi di dati sul corpo con il res.write () metodo. Questo accetta una stringa o un oggetto buffer come argomento. Se si tratta di una stringa, il secondo parametro è il tipo di codifica (per impostazione predefinita utf8).

Il res.end () il metodo chiude il corpo, ma è possibile passare i dati ad esso per scrivere nel flusso di risposta. Questo è utile in situazioni in cui è necessario produrre solo una linea.


Middleware di terze parti

È un po 'difficile rispondere con corpi HTML più grandi nei normali nodi Node e Connect. Questo è un buon posto per mettere in mezzo il middleware di terze parti. È possibile trovare un elenco di middleware di terze parti nel wiki Connect Github. Ad esempio, useremo il pacchetto connect-jade, che ci consente di visualizzare le viste di giada.

Innanzitutto, installa connect-giada:

npm installa connect-jade

Successivamente, richiedere e aggiungerlo come middleware. Ti consigliamo di impostare alcuni valori predefiniti:

var connect = require ("connect"), connectJade = require ("connect-jade"); connect () .use (connectJade (root: __dirname + "/ views", default: title: "MyApp")) .use (function (req, res) res.render ("index", heading : "Benvenuto nella mia app");). Listen (3000);

Imposta la radice come directory che contiene i file di visualizzazione. Puoi anche impostare default; queste sono variabili disponibili all'interno di ogni vista, a meno che non vengano sovrascritte più tardi durante la chiamata render ().

La funzione finale in questo codice effettua una chiamata a res.render (). Questo metodo è fornito dal connect-giada pacchetto.

Il primo argomento che accetta è il nome della vista da renderizzare.

È il percorso per la vista, sans il percorso che abbiamo definito durante l'aggiunta del middleware, sans l'estensione del file jade. Per questo codice, abbiamo bisogno di a views / index.jade modello per il rendering. Lo manterremo semplice:

html head title = titolo body h1 = heading

Se non hai familiarità con jade, indichiamo i nomi dei tag per creare una struttura HTML. Il segno di uguale recupera il valore di una variabile JavaScript. Quelle variabili vengono dal default abbiamo impostato, oltre al (secondo) oggetto parametro secondario passato a res.render ().

Ci sono molti altri middleware di terze parti, ma funzionano in modo simile tra loro. Li si installa tramite npm, li richiede e li mette in azione.


Moduli come middleware

Se analizzi come funziona Connect, scoprirai che ogni livello è in realtà un modulo Node, un design molto intelligente. Se si utilizza Connect per applicazioni dimensionali, sarebbe ideale scrivere il proprio codice nel formato del modulo Node. Potresti avere un app.js file come questo:

// app.js module.exports = function (req, res, next) res.end ("questo proviene da un modulo"); ;

E nel tuo server.js:

var connect = require ("connect"), app = require ("./ app"); connect () .use (app) .listen (3000);

Conclusione

Se si desidera una libreria per principianti che faciliti la creazione di app Web di grandi dimensioni, Connect non è la soluzione. Connect è pensato per essere un sottile strato sulla parte superiore dell'API del nodo che ti dà il controllo completo sull'applicazione server. Se vuoi un po 'di più, ti consiglio Express (dalle stesse persone, incidentalmente). Altrimenti, Connect è una fantastica libreria estensibile per le applicazioni web Node.