Avevamo già sviluppato un server API REST completo
usando Express e MongoDB come parte di questo corso.
Affinché quel server sia in grado di comunicare in modo significativo con il nostro cliente,
faremo alcune piccole modifiche ad esso in
modo che restituisca il giusto tipo di dati in modo che la
nostra implementazione client possa funzionare
in modo più efficiente con i dati restituiti dal nostro sito server.
Quindi, per farlo,
lavoriamo su alcune modifiche al nostro sito server in questo esercizio.
Prima di iniziare questo esercizio,
presumo che non hai fatto
la lezione precedente sull'integrazione del client angolare e
del server perché stai facendo questa lezione passando dalla specializzazione React.
Quindi, le modifiche che apporterò al server assumeranno che
la versione del server che stai modificando sia prima della lezione precedente.
Nel caso in cui tu abbia fatto quella lezione sul client angolare,
alcune delle modifiche apportate al tuo server verranno ripetute nuovamente
in questo esercizio in modo da poter saltare quella parte delle modifiche.
Entra nel nostro server nell'editor.
Prima di iniziare a lavorare sul server,
suggerirei di scaricare tutte le immagini che ho
fornito come file zip nelle risorse di esercizio chiamate images.zip.
Decomprimere il file e quindi ottenere tutte le immagini da lì e poi copiare quelle immagini
nella cartella immagini pubbliche nel nostro server.
Quindi, vedi che qui ho copiato tutte le immagini nella mia cartella di immagini pubbliche qui
già perché il nostro server è quello che
servirà tutte queste immagini per la nostra applicazione client.
Successivamente, andiamo al CORS e aggiustiamo la whitelist qui.
Quindi, per la nostra applicazione client React,
se abbiamo iniziato con il comando di avvio del
filato, viene eseguito al nome del computer: 3001.
Quindi, qualsiasi richiesta proveniente dalla nostra posizione
al server porterà quella come origine lì.
Ecco perché ho intenzione di aggiungerlo nella mia whitelist in modo che
tutti i problemi CORS vengano risolti automaticamente.
Quindi, andando nel file cors.js nella mia whitelist qui,
lasciami aggiungere il
nome del computer http://my: 3001 e questa è
l'origine da cui il mio client
originerà le richieste che arrivano a questo server.
Quindi, in questo modo il mio CORS non causerebbe problemi al mio cliente.
Successivamente, abbiamo bisogno di aggiornare alcuni dei percorsi per
gestire i parametri di query e anche alcuni piccoli altri aggiustamenti.
Permettetemi di iniziare con il file promoRouter.js.
Questo è semplice da aggiornare.
Quindi, andando nel file promoRouter.js,
nel file PromorOuter per la richiesta get che arriviamo
qui invece di fare promozioni trovare con un oggetto JavaScript vuoto,
qui vorrei fornire il req.query come parametro per le promozioni trovare qui,
stessa cosa con il router leader anche.
Quindi, lasciami andare al file leaderRouter.js.
Nel router leader anche,
qui dove trovi leaders.find con l'oggetto JavaScript vuoto invece
sostituirlo con il req.query in modo che i parametri di query vengano passati.
Quindi, questo è dove passeremo nella caratteristica: true come parametro di query qui.
Ora, dopo aver regolato questi due,
lavoriamo ora sul router piatto.
Quindi, vai nel file dishRouter.js,
anche nel router piatto anche lo stesso aggiornamento qui.
Quindi, vai in questo piatti.Trova nel metodo get qui,
cambialo in req.query.
Quindi, con questo, il mio aggiornamento del router piatto è stato completato.
Quindi, ora abbiamo aggiornato il router promozionale, il leader
e il router piatto,
quindi passeremo per aggiornare il router preferito.
Ora, avresti implementato il router preferito come parte del tuo quarto incarico.
Ora, nel router preferito,
vedrai che per il router preferito,
non ti sto mostrando la parte rimanente perché
avresti dovuto fare come parte del tuo incarico.
Innanzitutto, permettetemi di attirare la vostra attenzione sul metodo get per FavoriteRouter.Rout:dishID.
Ora userò questo metodo get per verificare che
il piatto specifico con il piatto Id sia già uno dei preferiti per l'utente.
Quindi, invece di dire semplicemente getoperation.supported,
sto solo andando a sfruttare la presenza di questa operazione get e poi diremo,
favorites.Findone e diremo utente: req.user. _id.
Quindi, troveremo i preferiti per quel particolare utente e poi diremo poi
preferiti e cattura errore prossimo.
Quindi allo stesso modo qui, aggiungeremo l'err qui, il prossimo err qui.
Quindi, all'interno di questo allora,
quando otteniamo i preferiti,
allora controlleremo se non i preferiti.
Quindi, se non ci sono preferiti per
questo utente, ovviamente il piatto che stiamo controllando non esiste,
quindi restituiremo res.statusCode 200,
setHeader, Content-Type,
application/json e poi torneremo dicendo esiste false.
Quello che stiamo specificando qui è che se ottengono è fatto a questo punto finale con un Id piatto,
questa bandiera esiste qui sarà impostata su true se questo piatto fa parte dei miei preferiti.
Se questo piatto non fa parte dei miei preferiti,
Io impostare là esiste bandiera su false.
Quindi qui, vedi che dal momento che non ho alcun favorito, quindi
esiste dovrebbe essere automaticamente falso a questo punto.
Quindi, diremo esiste falso e poi restituiremo i preferiti qui.
Beh, ovviamente, in questo caso i favoriti sarebbero nulli a questo punto.
Altrimenti, il che significa che i preferiti non è nullo,
quindi diremo se favorites.dishes.indexOf.
Quindi, stiamo andando a cercare Req.params.dishID.
Quindi, stiamo andando a cercare questo array piatti preferiti per
vedere se questo piatto esiste lì e se non esiste,
ovviamente questo restituirà un indice negativo qui.
Anche in questo caso,
restituirò esattamente lo stesso di qui.
Quindi, se restituisce un indice negativo significa che anche
se questo particolare utente ha un insieme di preferiti,
questo piatto specifico non esiste
nella lista dei suoi preferiti, quindi è per questo che restituirà esiste falso qui.
Ora, altrimenti ciò significa che il piatto esiste nella lista dei preferiti.
Quindi, in questo caso,
restituirò il codice di stato 200 esiste è vero.
In questo modo, quando l'utente esegue un'operazione get su questo endpoint con
il/favorites/dishId dove viene fornito l'Id piatto
come parametro qui, come parametro di richiesta qui,
allora controlleremo per vedere se quel piatto esiste nei preferiti.
Se nessuno dei preferiti esiste per questo utente, allora restituiremo un falso esiste.
Allo stesso modo, se i preferiti esiste ma
quel piatto particolare non esiste nei preferiti allora restituiremo false,
altrimenti restituiremo true.
Quindi questa bandiera esiste può essere utilizzata dal mio cliente per verificare se questo piatto fa
parte della lista dei piatti preferiti per questo utente o meno.
Anche mentre siamo in preferiti,
ogni volta che apportiamo modifiche ai preferiti,
vogliamo essere in grado di popolare le informazioni utente e piatti,
i preferiti, prima di tornare.
Ad esempio, nel post che facciamo,
quando salviamo i preferiti allora a questo punto,
vorremmo prima fare i preferiti.
FindById, quindi perché abbiamo appena apportato le modifiche diremo favorite_id
e popoleremo sia l'utente che anche
i piatti nei preferiti.
Poi, quando i preferiti vengono restituiti,
restituiremo quei preferiti invece.
Quindi, lasciatemi fare questo cambiamento qui.
Quindi, taglieremo questo fuori da qui e poi all'interno del poi,
restituiremo i preferiti.
Dopo aver salvato i preferiti,
allora cercheremo per esso,
per il FavoriteById e poi restituire
quel preferito qui così diremo poi ritorno preferito e codice di stato.
Questo cambiamento che dovremmo fare.
Se lo hai già implementato nei tuoi preferiti
, non è necessario apportare questa modifica.
Ma quello che stiamo facendo è ogni volta che apportiamo modifiche ai preferiti,
popoleremo sia le informazioni utente che i piatti e quindi restituiremo questo valore
perché il nostro client React si aspetta che questo sia lì.
Ora, lo stesso tipo di cambiamento,
avremo bisogno di fare la variabile b, salvare le modifiche.
Quindi nel post qui,
faremo una modifica a questo,
quindi diremo favorites.save e poi faremo favorites.FindById e fare quel cambiamento.
Allo stesso modo, sotto l'id
del piatto, anche nel post,
sarai allo stesso modo, ogni volta che
apporterai modifiche ai preferiti, lo cercherai prima e poi popolerai sia l'utente che i piatti e poi lo restituirai,
e poi similmente nella parte else.
Quindi, devi averlo implementato nel tuo quarto incarico.
Quindi, apporta questa modifica aggiuntiva in cui popolerai
l'utente e i piatti prima di restituire il valore.
Anche con l'eliminazione,
faremo le stesse modifiche qui.
Quindi, noti che nella cancellazione,
ho già fatto questo cambiamento qui.
Quindi, dopo aver salvato le modifiche ai preferiti,
cercheremo i preferiti e
torneremo dopo aver popolato sia l'utente che i piatti e i preferiti.
Questo è ciò che il nostro cliente React si aspetta da noi.
Quindi, anche per l'eliminazione,
faremo le stesse modifiche.
Ora, con questo, il mio router preferito viene aggiornato,
quindi procederemo avanti all'aggiornamento di users.js successivo.
Infine, aggiorneremo il file users.js.
Ora, nel file users.js dobbiamo aggiungere
un altro campo router.options qui,
perché a volte una richiesta di post come hai visto
con il login invierà prima le opzioni per verificare,
specialmente con le auto, se la richiesta di post sarà consentita.
Ecco perché controlleremo il corso con le opzioni qui e poi
restituiremo semplicemente
un messaggio
di stato di 200 in risposta a questo.
Per qualsiasi endpoint sotto gli utenti se riceviamo le opzioni,
restituiremo semplicemente uno stato 200 qui.
Ora la funzione di login che avevamo implementato in precedenza,
avevamo semplicemente fatto passport.authenticate
locale qui e abbiamo controllato i valori rimanenti qui.
Ora, questo passport.authenticate locale,
se l'utente non viene autenticato,
restituisce semplicemente un non autorizzato nel messaggio di risposta.
Ora questo potrebbe non essere molto significativo per il lato client per visualizzare queste informazioni,
quindi è per questo che miglioreremo
questo metodo di login post router in modo
tale che l'autenticazione restituirà informazioni più significative a questo punto.
Quindi, per farlo,
non stiamo andando a fare il passport.authenticate qui,
invece ci prenderemo.
Quindi, lasciami rimuovere da lì e poi vedrai
come aggiornerò il post del router qui.
Quindi, vedremo corso con le opzioni e poi includeremo il req,
res e il prossimo qui.
All' interno di questo req, res e il prossimo qui,
passport.authenticate chiamerà questo con local.
Ora, quando chiamiamo questo con locale,
se si verifica un errore di autenticazione,
il passport.authenticate può essere fatto per restituire
il valore di errore e inoltre restituirà l'utente se
non ci sono errori e un terzo parametro chiamato info
che porterà informazioni aggiuntive che potrebbero essere analizzate di nuovo a l'utente.
Questo errore verrà restituito quando si
verifica un errore autentico nel passport.authenticate.
Ma se le informazioni dell'utente
vengono inviate in passport.authenticate ma l'utente non esiste,
allora ciò non viene conteggiato come un errore.
Invece, verrà conteggiato come utente non esiste e
che le informazioni vengono analizzate nuovamente nell'oggetto info che entra in.
Pertanto, l'errore verrà restituito quando si
verifica un errore genuino durante il processo di autenticazione,
ma le informazioni conterranno informazioni se l'utente non esiste.
Quindi, il passport.authenticate sta restituendo un messaggio che dice che
l'utente non esiste o che il nome utente non
è corretto o che la password non è corretta e così via.
Quindi, tali informazioni verranno passate nel messaggio info.
Ora vedremo come questo
ci è utile quando guardiamo il lato client un po 'più tardi.
Quindi, in questa situazione,
gestiremo questo come segue,
e non solo quando chiamiamo questo passport.authenticate,
abbiamo anche bisogno di passare in un req,
res, accanto come i tre parametri ad esso.
Quindi, questa è la struttura quando devi chiamare passport.authenticate e aspettarti che
ti trasmetta informazioni come questo come metodo di callback qui,
quindi devi anche fornire questo req, res,
anche lì.
Ora, se questo si verifica,
quindi diremo se err,
quindi se c'è un errore che si verifica,
diremo restituire il prossimo
errore e poi lasciare che il gestore degli errori del nostro router espresso e prendersi cura di questo.
Ora, prenderemo in considerazione altre situazioni, se non utente.
Quindi, se abbiamo raggiunto questo punto,
significa che non è stato un errore che si è verificato,
ma invece forse l'utente non è stato trovato.
Se l'utente non viene trovato,
l'utente qui verrà impostato su null in questo caso.
Quindi, in questa situazione,
se l'utente non esiste,
allora dobbiamo essere in grado di passare le informazioni sul lato server.
Quindi, quello che faremo è passeremo in queste informazioni in questo formato.
Quindi, ho intenzione di tagliare questo fuori da qui e
poi incollarlo qui e poi lo modificheremo.
Quindi, se l'utente è nullo,
allora invieremo un codice di stato come 401 che significa
non autorizzato e poi invieremo informazioni di successo false,
e quindi non passeremo indietro il token,
passeremo indietro il messaggio di stato.
Quindi, qui diremo
'Login Unsuccessfu' e poi la terza informazione,
passeremo queste informazioni quell'oggetto che abbiamo ricevuto qui come
la terza parte nel messaggio di risposta che inviamo indietro dal nostro server qui.
Quindi, il flag di successo verrà impostato su false,
lo stato verrà impostato Login non riuscito e
le informazioni di errore passate nelle informazioni verranno restituite.
Ora, si noti che questa situazione si verificherà se
il nome utente e la password non sono corretti,
e quindi questo non è un errore nel senso di errore, ma
il fatto che l'autenticazione non è riuscito a trovare l'utente o la password dell'utente non è corretto.
Quindi, tali informazioni saranno codificate nelle informazioni che entrano e in modo che io
possa tornare come errore al mio lato client.
La parte altrimenti
viene gestita come REQ.login.
Quindi, se questo ha successo,
il passport.authenticate aggiungeremo questo metodo chiamato REQ.Login all'utente.
Quindi, a questo punto,
passeremo semplicemente l'oggetto utente che abbiamo ottenuto.
Quindi qui, se abbiamo raggiunto questo punto,
allora ciò significa che l'oggetto utente non è nullo e anche nessun errore si è verificato,
quindi ciò significa che l'utente può essere loggato.
Quindi, diremo err,
proveremo ad accedere all'utente.
Quindi, diremo se err e
poi passeremo indietro lo stesso tipo di informazioni di errore che abbiamo fatto qui.
Quindi, in questo caso, se l'errore,
poi passeremo indietro un codice di stato come 401 e diremo che il successo
è falso e lo stato come Login UnSuccess
, e quindi le informazioni
di errore, invece delle informazioni,
passeremo in 'Impossibile accedere utente».
Quindi, questo è il messaggio che passeremo qui se si verifica l'errore.
Altrimenti, saremmo qui sotto.
Quindi, a questo punto,
saremmo in grado di generare il token.
Quindi, se abbiamo raggiunto fino a questo punto, ciò
significa che l'utente ha effettuato correttamente l'accesso,
e quindi ora possiamo generare il token.
Quindi, genereremo il token in base all'ID dell'utente,
e poi passeremo indietro il token all'utente.
Quindi, qui, diremo token var,
e quindi possiamo dire res.statusCode è 200 e quindi res.json successo vero,
quindi, il che significa che l'utente ha effettuato correttamente l'accesso.
Quindi, lo stato sarebbe login riuscito.
Quindi, la terza parte,
invece dell'errore,
passerò il token all'utente.
Quindi, diremo token,
questo token che abbiamo appena ottenuto in precedenza.
Quindi, quel token verrà passato come proprietà token del messaggio di risposta.
Quindi, qui, si noti che il successo è impostato su true, quindi, il
che significa che l'utente ha effettuato correttamente l'accesso,
e quindi l'utente può procedere ulteriormente a questo punto.
Questo deve essere fatto all'interno di REQ.login qui.
Quindi, a questo punto,
chiuderemo il REQ.login.
Quindi, nota che questo è all'interno di questo REQ.login qui.
Quindi, li' dentro, passeremo questi tre indietro.
Quindi, lasciatemi solo rientrare queste tre righe in.
Quindi, questo è il modo in cui gestiremmo il metodo di registrazione dell'utente.
Quindi, di nuovo, rivedere questo codice ancora una volta.
Quindi, faremo post router,
ma invece di fare l'autenticazione passaporto proprio lì,
diremo req, res,
prossimo, e poi dentro qui,
faremo un passaporto autenticato per il locale,
e questo autenticato passerà indietro.
Quindi, possiamo fornire una funzione di callback a questo,
e questa funzione di callback restituirà l'errore,
l'utente o le informazioni qui.
Quindi, se si tratta di un errore,
permetteremo solo al gestore di errori espresso di occuparsi di questo.
Se l'utente è nullo
, significa che l'accesso dell'utente non ha avuto successo
e il motivo sarà nelle informazioni.
Quindi, questo passerà come errore di informazioni nel messaggio di risposta qui.
Se arriviamo a questo punto,
l'utente viene verificato con successo.
Quindi, allora effettueremo il login all'utente.
Quindi, il passaporto si autentica,
aggiungeremo in questo metodo chiamato login al req, il messaggio di richiesta.
Quindi, possiamo chiamare il login con l'utente.
Se questo restituisce un errore,
allora restituiremo l'errore qui in modo appropriato.
In caso contrario, avremo raggiunto il punto in cui l'utente è autenticato con successo.
Quindi, siamo in grado di generare il token Web JSON qui e quindi restituire
il token Web JSON all'utente per confermare che l'utente è connesso correttamente.
Quindi, questo è l'insieme di passi che useremo qui.
Ora, il motivo per cui faccio un modo più elaborato di gestirlo è che
voglio distinguere tra la situazione in cui
si verifica un errore genuino durante il processo di autenticazione rispetto alla situazione
in cui il nome utente non è valido o la password non è valida.
Quindi, questi due casi saranno gestiti da questa situazione,
dove le informazioni porteranno le informazioni a noi.
Quindi, questo non è un errore di per sé,
ma questa è una situazione in cui l'utente
non è un utente valido o la password dell'utente non è valida.
Quindi, è così che gestiremo il processo di accesso dell'utente.
Inoltre, aggiungerò
un altro metodo qui chiamato checkJwttoken.
È del tutto possibile che, mentre il client ha effettuato l'accesso e ottenere il token Web JSON,
in un secondo momento, il token Web JSON potrebbe scadere.
Pertanto, se l'utente tenta di accedere dal lato client con un token scaduto al server,
il server non sarà in grado di autenticare l'utente.
Quindi, a intervalli periodici,
potremmo desiderare di effettuare un controllo incrociato per assicurarci che il token Web JSON sia ancora valido.
Quindi, questo è il motivo per cui sto includendo questo,
un altro endpoint chiamato CheckJWttoken.
Quindi, se si esegue un get al checkJWtToken
includendo il token nell'intestazione di autorizzazione,
questa chiamata restituirà un true o false
per indicare se il token Web JSON è ancora valido o meno.
Se non è valido, il lato client può avviare un altro accesso per
l'utente per ottenere un nuovo token Web JSON, se necessario.
Quindi, per fare questo,
diremo cors.corsWithOptions e req,
res qui come previsto.
Qui, diremo
passaporto autenticare jwt
e sessione: false,
e questo restituirebbe err, utente, informazioni.
Quindi, ricorda come usiamo il passaporto autenticare in precedenza.
Quindi, chiamiamo il JWT con sessione false qui.
Quindi, prima qui, diciamo che il passaporto autentichi il locale.
Quindi, questo è per l'autenticazione locale.
Quindi, questo è per l'autenticazione JSON Web Token.
Quindi, quando lo chiamiamo,
allora dal momento che questo sta per verificare il token Web JSON, quindi diremo,
se err restituisce il prossimo
errore, e quindi lasciare che il gestore di errori espresso si occupi di quella situazione.
Quindi, diremo, se non utente,
se l'utente non esiste, quindi allo stesso modo.
Quindi, il che significa che se l'oggetto utente è stato
trovato dal token Web JSON e quindi caricato su req.user,
significa che l'utente è un utente valido
e quindi può essere autorizzato a procedere ulteriormente.
Altrimenti, diremo che l'utente non esiste.
Quindi, dobbiamo informare che il token Web JSON è scaduto.
Quindi, a questo punto,
invieremo una riserva con
un codice di stato di 401.
Quindi, non autorizzato, SetHeader, Content-Type,
application/json, e quindi restituiremo res.
Res.json dirà lo stato JWT
non valido e quindi,
restituiremo un flag chiamato cade successo e poi,
restituiremo le informazioni che otteniamo se l'utente
non è autenticato come l'errore a questo punto.
Altrimenti, ciò significa che abbiamo raggiunto questo punto,
quindi l'utente è un utente valido.
Quindi, in questo caso,
fammi solo copiare quel codice qui,
invieremo un codice di stato di 200 e quindi il res.json,
invierà JWT valido e di successo essendo vero.
La terza parte, invieremo le informazioni dell'utente. In
questo modo, quando questo endpoint viene chiamato con il metodo get,
questo verificherà se il token è valido o meno.
Se il token è valido,
riceverai questa risposta e dal flag di successo nella risposta,
puoi verificare se il jsonwebtoken è valido o meno.
Questo è utile sul lato client.
Ora, questo passaporto autenticato qui dovrà essere fornito
con req e res come i due parametri qui.
Quindi, è così che chiamiamo l'autenticazione del passaporto.
Quindi, si noti che ogni volta che si chiama
passaporto autenticazione e si aspetta questa funzione di callback qui,
è necessario aggiungere a questo punto req.res al passaporto autenticato sul retro qui.
Nel nostro server API di riposo,
avevamo implementato i nostri commenti in modo tale che i commenti
formavano sotto-documenti all'interno del documento di dishe, in
modo che comprassero ogni piatto racchiuse la propria serie di commenti.
Ma il modo in cui abbiamo implementato il nostro cliente React è
tale che i commenti sono tenuti indipendenti dai piatti,
e i commenti stessi portavano l'ID piatto corrispondente.
Ora, questi sono due modi diversi di
implementare il lato server e il lato client.
Nell' applicazione angolare che siamo implementati nella nostra specializzazione angolare,
avevamo usato il metodo sotto-documento per la
gestione dei commenti nella nostra applicazione client angolare.
Quindi, il server API resto è stato
implementato in modo tale che fosse più adatto per il client Angular.
Ma per i client React dal momento che abbiamo mantenuto i commenti indipendenti dai piatti,
e quindi utilizzare l'ID del piatto all'interno del commento,
quindi abbiamo bisogno di ristrutturare il nostro server API di riposo,
quindi è che abbiamo un endpoint di commento separato indipendente dall'endpoint piatti.
Quindi, abbiamo bisogno di ristrutturare il nostro codice nel server
per introdurre l'endpoint API REST /comments in questa fase.
Quindi, per farlo,
andiamo avanti e implementiamo un nuovo modello chiamato come comment.js.
Quindi, andando nei modelli,
lasciami implementare un nuovo file chiamato comments.js.
Nel file comments.js,
abbiamo intenzione di spostare il CommentSchema dal
file dishes.js nel file comments.js e quindi rimuoverlo completamente dal file dishes.js.
Ma prima di farlo,
abbiamo bisogno di copiare la mangusta e lo schema da qui,
quindi lasciami copiare questo da dishes.js in comment.js.
Dopodiché, andando in dishes.js,
lasciami tagliare completamente questo CommentSchema da qui,
perché avremo questo separatamente nel modello dei commenti qui.
Quindi, spostiamolo nel modello dei commenti e quindi incollalo qui.
Ma ovviamente questo non è il completo,
aggiorneremo un po 'il CommentSchema.
Ma prima di farlo,
tornare al file dishes.js e nel file dei piatti,
rimuoveremo i commenti dal DishesChema,
perché stiamo andando a memorizzare il contenuto separatamente dai
piatti in questa versione del nostro server.
Quindi, è così che aggiorneremo il modello di piatti qui.
Quindi, abbiamo rimosso completamente i commenti dal modello piatti qui.
Entrando nel modello dei commenti,
quindi ora vediamo che abbiamo il CommentSchema implementato qui.
Ma in aggiunta, nei CommentsChema,
ora dobbiamo puntare esplicitamente al
piatto specifico per il quale questo commento è il commento corrispondente.
Ora, qui è dove
la nostra popolazione di manguste e
il modo in cui conserviamo gli ID degli oggetti vengono in nostro soccorso.
Quindi, aggiorneremo il CommentSchema dicendo che avremo la valutazione,
il commento e l'autore qui.
Oltre all'autore,
introdurremo un altro campo chiamato come il piatto qui che è
del tipo: mangoose.Schema types.ObjectID,
e quindi questo farà riferimento al piatto qui.
Quindi, questo sarebbe un riferimento oggetto al modello piatto qui,
e quindi con questa modifica ora
i nostri commenti conterranno il campo di valutazione, il campo di commento,
l'autore che è di nuovo un riferimento all'utente corrispondente,
e quindi il campo piatto che è un riferimento al corrispondente piatto qui.
Quindi, il che significa che ora dovremo
popolare i commenti sia con l'autore che con il campo piatto.
Una volta completato questo,
allora diremo var Commenti
mongoose.model e chiameremo questo 'Commento',
e poi questo utilizza il CommentSchema che abbiamo appena definito qui,
e poi abbiamo bisogno di esportare questo da qui,
il comments.model da qui.
Quindi, ora che abbiamo introdotto il comments.model,
allora andremo avanti e quindi introdurre un nuovo Router chiamato come CommentRouter.
Quindi, per introdurre il router dei commenti,
andiamo nelle rotte qui
e quindi creare un nuovo file denominato commentRouter.js.
Nel commentRouter.js, lasciami copiare alcune cose
da DishRouter.
Quindi, avremo questi commenti qui,
quindi lasciami copiare su queste cose da e anche,
mentre sono a questo fammi solo copiare questi anche fino a quel punto,
e poi aggiornerò un po 'più tardi.
Quindi, andando nel CommentRouter,
abbiamo bisogno di tutte queste parti,
quindi diremo Com, Express, BodyParser, mangusta
, autenticare, cors, e poi
importeremo commenti da modelli/commenti.
Quindi chiameremo questo come CommentRouter che è un Express.Router qui.
Quindi diremo CommentRouter usa BodyParser,
e quindi questo sarebbe ora diventato percorso CommentRouter.
Ora, abbiamo bisogno di andare nel DishRouter e quindi
rimuovere tutte le parti che si riferiscono ai commenti qui.
Quindi, lasciami tagliare questa parte e poi riutilizzeremo questi per il nostro CommentRouter.
Quindi, tutti questi non sono più necessari nel DishRouter.
Quindi, ho intenzione di rimuovere tutto questo da DishRouter qui,
quindi lasciami tagliare fuori,
tutto ciò che riguarda il percorso dei commenti dal DishRouter,
quindi andremo nel CommentRouter,
e poi lasciami andare avanti e incollarlo qui,
quindi lo modificheremo qui.
Quindi dopo questo, abbiamo bisogno di esportare il CommentRouter.
Quindi, esporterà il CommentRouter per noi.
Ma ovviamente, questo codice non è completamente accurato.
Quindi, dobbiamo andare avanti e risolvere questo codice qui.
Quindi, per questo codice,
ora ci rendiamo conto che questo non è il percorso DishRouter,
invece che dovrebbe essere
il/endpoint perché stiamo
andando a montare questo nell'endpoint /comments qui.
Quindi, diremo CommentRouter,
e poi le opzioni corsWithOptions (req,
res) che rimane come tale lì,
e poi get cors.cors e quindi req.res,
e poi questo diventerà commenti.
FindById, req.
Quindi, questo sarebbe commenti.Find
e req.query qui.
Quindi, quando vengono trovati i commenti
, allora, a questo punto,
popoleremo l'autore,
già lì, popoleremo qui.
Quindi, ho intenzione di rimuovere questo comments.author, e
poi, semplicemente popolare l'autore qui.
Quindi, questo ci darebbe dei commenti qui.
Quindi, diremo, questo può essere semplificato in modo significativo.
Quindi, l'errore di cattura è lì comunque.
Quindi, quando arriverà il commento, tornerà semplicemente.
Scusa, dovrebbe esserlo.
Quindi, se per ottenere,
quando otteniamo i commenti,
comments.Find req.query, .populate autore qui,
e poi, diremo, .then commenti,
e poi, diremo, res.StatusCode 200,
SetHeader, e poi, restituiremo i commenti da qui,
res.json commenti da qui.
Ora, non sto popolando i piatti qui perché non ho esplicitamente bisogno
dei piatti nel modo in cui uso queste informazioni nel mio cliente reattivo.
Ho solo bisogno dell'ID del piatto,
e l'ID del piatto è già presente lì,
e questo è abbastanza buono per me da usare questi dati nel mio client reattivo.
Quindi, ho intenzione di lasciarlo come tale lì.
Ho intenzione di popolare le informazioni
dell'autore solo lì perché abbiamo bisogno delle informazioni complete dell'autore
ogni volta che rendiamo un elemento di commento nel nostro client di reazione.
Quindi, il get verrà aggiornato in questo modo qui.
Per il post corsWithOptions,
diremo, authenticate.verifyUser req, res, next.
Ovviamente, per un commento da pubblicare,
è necessario che l'autore sia un utente registrato valido.
Solo allora, permetterai all'utente di pubblicare un commento.
Quindi, il commento stesso arriva nel corpo del messaggio di richiesta in arrivo.
Quindi, in primo luogo, controlleremo il corpo
per assicurarci che il commento sia incluso nel corpo qui.
Quindi, qui, ho intenzione di rimuovere tutte queste parti, e poi,
semplificarlo ulteriormente, e quindi,
implementarlo correttamente lì.
Quindi, proprio a questo punto, diremo,
se req.body non è uguale a null,
quindi il che significa che c'è un commento che è racchiuso all'interno del corpo.
Quindi, lasciami tagliare questo e spostare questo nella parte if qui,
e poi, lo modificheremo qui.
Quindi, se il corpo non esiste,
allora causeremo un errore.
Quindi, diremo, errare nuovo errore,
Commento non trovato nel corpo della richiesta.
Quindi, solleveremo questo errore qui.
Lo stato di errore è 404.
Quindi, diremo, restituire il prossimo errore.
Quindi, gestiamo la parte di errore qui se il corpo
non contiene le informazioni di commento appropriate.
Se contiene, allora, ovviamente,
quello che faremo dopo è,
diremo, req.body.author è req.user. _id.
Il motivo per cui stiamo facendo questo è che ricordiamo che se si
tratta di un utente registrato e l'utente ha effettuato l'accesso,
allora il req.user conterrà le informazioni utente.
Quindi, ho solo bisogno dell'ID dell'utente attualmente connesso.
Quindi, diremo, req.user. _id, e quindi,
imposteremo il req.body.author su req.user. _id.
Ora, l'utente di verifica si assicurerà automaticamente che se atterri a questo punto,
allora si avrebbe ovviamente un utente che ha effettuato correttamente l'accesso.
Altrimenti, ciò avrebbe già causato il problema lì.
Quindi, quando raggiungi a questo punto,
avresti un utente valido che ha già effettuato l'accesso al sistema in lì.
Quindi, questo è dove saresti in grado di farlo ora.
Quindi, quello che stiamo facendo è che il campo autore, lo
stiamo impostando esplicitamente nell'ID dell'utente qui in modo che
il req.body contenga le restanti parti del commento.
Quindi, come ti rendi conto, il commento contiene
la valutazione, il commento stesso e l'autore e i campi piatto.
Quindi, le parti rimanenti dovrebbero essere state riempite dall'utente.
La valutazione, il commento
e le informazioni sui piatti devono essere già
inseriti nel corpo del messaggio di richiesta in arrivo.
La parte dell'autore è lasciata libera lì,
che inseriremo esplicitamente a questo punto nel corpo qui.
Quindi, ora, il req.body conterrà l'intera informazione del commento.
Quindi, a questo punto,
invece di fare questo, diremo, commenti.Crea.
Usando il req.body, creeremo i commenti qui.
Quindi, questo restituirà
il commento corrispondente al commento che abbiamo appena inserito qui.
Ora, una volta che il commento è tornato,
allora dovremmo fare comments.findById.
Ora, il motivo per cui dobbiamo farlo è perché
dobbiamo popolare le informazioni dell'autore qui.
Quindi, diremo, FindById commenti. _id,
quindi, popoleremo le informazioni dell'autore nel commento stesso.
Quindi, diremo, poi commentare.
Ora, ovviamente, qui, troverai che il commento
esisterà perché abbiamo appena inserito quel commento in posizione lì.
Quindi, qui, torneremo semplicemente, res.statusCode è 200,
Res.SetHeader è Content-Type, application/json.
Il commento stesso dirà, res.json, quindi,
restituirà il commento a questo punto.
Quindi, questo è il modo in cui gestiremo l'inserimento di
un nuovo commento nel nostro lato client qui.
Per il put, come ti rendi conto,
non sarai in grado di fare un put sui punti finali /commenti/.
Quindi, diremo, operazione PUT non supportata su/comments/ punto finale.
E' questo il punto. Questo è il messaggio che restituirai.
Quindi, StatusCode è 403,
e quindi, l'operazione PUT non supportata su/comments/.
Ora, quando facciamo una cancellazione,
lasciami solo tagliare questo da qui, e poi, diremo,
commenti.Rimuovere.
scritto vuoto. Pertanto, quando esegui un'eliminazione sull'endpoint dei commenti della barra,
rimuoverai tutti i commenti dal tuo sistema.
Quindi, questa è un'operazione molto pericolosa, e quindi,
non dovresti farlo normalmente.
Quindi, permetteremo solo all'amministratore di eseguire tale operazione.
Quindi, rimuoveremo tutti i commenti da lì.
Quindi, quando ottieni la risposta,
diremo res.statusCode 200.
Quindi, lasciami copiare queste parti qui,
e poi venite a incollarle qui.
Quindi, diremo, commenti.remove.
Quindi risposta res.statusCode 200 applicazione json e quindi res.json (risposta) qui.
Quindi, è così che gestiamo la cancellazione.
Operazione di eliminazione sull'endpoint dei commenti della barra.
Ora, il prossimo percorso è il router dei commenti.
Quindi, qui diremo CommentRouter.Route e
il punto finale qui sarebbe la barra CommentId.
Quindi, qui le opzioni rimarranno come tali.
Quindi per il get sul router corrente,
per il get diremo, comments.findById (req.params.
Questo sarebbe CommentId.
Quindi, una volta trovato il commento specifico,
allora popoleremo solo l'autore da lì.
Poi una volta popolato l'autore,
allora diremo, quindi commentare.
Ora, tutta questa parte non è necessaria qui,
quindi ho intenzione di cancellare la parte.
Anche questa non è la cosa appropriata qui.
Quindi, fammi rinominare il codice.
Quindi, diremo per ottenere comments.FindById,
quindi popolare l'autore,
quindi commentare, res.StatusCode è 200, SetHeader.
Quindi il resto sono json.
Saremo semplicemente restituendo i commenti qui.
Quindi, restituiremo il commento a questo punto, res.json (commento).
Troverai il commento specifico
e poi restituirai quel commento per il post.
Per la post-operazione, come ti rendi conto,
la post-operazione non è
consentita nei commenti CommentId.
Quindi, questo è il messaggio che invieremo,
operazione POST non supportata sui commenti barra commentId.
Quindi, questo è il messaggio che diremo per il put.
Ora, per il put, diremo commenti.Trova dove Id (req.params.CommentId).
Quindi, troveremo il commento lì,
e ci commento, quindi per il put.
Quindi, troveremo il commento lì,
e poi diremo per i commenti.
Quindi, se troviamo il commento,
se il commento non è nullo,
allora controlleremo anche se comment.author.
In caso contrario, comment.arthur è uguale a (req.user. _id).
Quindi, stiamo controllando incrociando per assicurarci che
il comments.author sia lo stesso dell'utente corrente.
Solo l'utente corrente che ha effettuato l'accesso - se l'utente è uguale all'autore dei commenti,
l'utente sarà autorizzato ad aggiornare.
Quindi, questa è la prima cosa che controlleremo.
Quindi, commenti, quindi commenta.author.equal a rec.user. _id.
In caso contrario, dirai che non sei autorizzato ad aggiornare questo commento.
Come vedi il.403,
quindi restituisce il prossimo errore qui.
Quindi, creeremo l'errore lì.
Quindi dopo questo, diremo
req.body.author, req.user. _id.
Questo è importante.
Ora, questi due non sono necessari qui,
perché stiamo salvando direttamente il commento.
Poi pillole, diremo commenti.FindByidAndUpdate
e req.Params.CommentId.
Quindi, troveremo quel commento specifico,
perché ci è già stato fornito l'ID commento.
Quindi, faremo commenti findById req.Params.CommentId.
Poi diremo poi (commento).
Quando si fornisce il Req.Params.CommentId,
dovremo fornire esplicitamente il secondo parametro,
che è ciò che vogliamo cambiare.
Quindi, diremo $ set: req.body.
Quindi, il secondo parametro, essenzialmente,
ti dice quale parte stai cambiando.
Ora, dal momento che ci è stato fornito il corpo contenente il commento aggiornato,
stiamo solo andando ad aggiornare l'intero commento stesso.
Poi l'altra parte che chiederemo è nuova: vera.
Quindi, questo garantirà che il commento aggiornato verrà restituito
nella tana di questa chiamata ai comments.findByidundUpdate.
Quindi, diremo poi commenti.
Quando questo commento viene restituito,
allora diremo comments.findById (commento. _id).
Quindi popolare l'autore lì.
Popoleremo l'autore lì,
e poi diremo poi commentare.
Quindi, vedi che otterremo il commento e poi restituiremo il commento a questo punto.
Quindi, è così che aggiorneremo il commento.
Quindi, questa è la situazione in cui il commento non è nullo.
Quindi, questa istruzione if per il commento non è nullo.
Quindi, l'altro se parte,
ora questo non è applicabile,
quindi diremo altro, errore.
L' errore in questo caso.
Quindi, se il commento è nullo,
significa che non abbiamo trovato il commento lì dentro,
quindi non puoi modificare un commento inesistente.
Quindi diremo err,
nuovo commento di errore req.params.CommentId non trovato e quindi restituiremo l'errore.
Quindi, è così che gestiremo la parte put del nostro commento qui,
e poi finalmente l'eliminazione.
Per l'eliminazione, di nuovo dovremo prima trovare
comments.findById (req.params.CommentId)
e quindi commentare.
Quindi, cercheremo il commento.
Quindi, prima controlleremo se il commento non è uguale a null.
E' importante controllare qui.
Quindi, la parte successiva che controlleremo è se il comment.author è uguale a req.user. _id.
Ci assicuriamo che l'utente che sta tentando di eliminare
questo commento sia esattamente lo stesso utente che ha inserito il commento in primo luogo. In
caso contrario, quindi se questa è la situazione,
vedrai 'Non sei autorizzato a cancellare questo commento! '
E poi restituire lo stato lì.
Poi giù qui sotto,
diremo comments.FindByidAndRemove qui.
Quindi, diremo comments.findByIdAndRemove (req.params.CommentId),
quindi otterremo una risposta dal commento.
Quindi, a questo punto,
diremo semplicemente, res.statusCode.
Quindi diremo comments.FindByIdAndRemove quindi risposta.
Se viene rimosso correttamente,
diremo 200 e quindi res.json
risposta qui e prenderemo anche l'errore a questo punto.
Quindi, lasciami copiare qui e poi includeremo la cattura dell'errore a questo punto.
Quindi, questa è la prima cosa che controlleremo.
Ci assicureremo che il commento non sia uguale a null.
Altrimenti, quindi questa è l'altra parte.
Quindi, questa è l'altra parte dell'errore if else
nuovo commento req.params.CommentId non trovato e quindi
404 e invia la parte else per noi e quindi la parte allora gestirà in modo appropriato.
Quindi, queste sono le modifiche che apportiamo per il router dei commenti qui.
Quindi, stiamo gestendo il post get put ed eliminare per
i commenti barra e commenti barra punto barra commentID impatto.
Quindi, una volta completato questo,
allora abbiamo bisogno di includere questo nel file app.js.
Quindi, andremo nel file app.js e poi diremo
var CommentRouter
richiede routes/CommentRouter.
Quindi, abbiamo il router commento qui e poi andremo
giù nel file app.js qui sotto e
poi diremo app.use
slash commenti, CommentRouter qui.
Questo è tutto. Quindi ora,
il mio router di commento è pronto.
Quindi, andiamo avanti e salviamo tutte le modifiche.
Quindi il nostro server è ora aggiornato
al fine di gestire tutte le richieste dei nostri clienti React qui.
Ora, se vuoi fare il modo alternativo, cioè,
hai i tuoi commenti come sotto-documenti del tuo piatto e poi vuoi gestirlo,
allora dovrai aggiornare il client React per essere in
grado di utilizzare i commenti dall'interno di ogni piatto in modo appropriato.
Questo sarà lasciato come un esercizio per voi.
Pensa a come progettare il tuo client reattivo in modo tale che
funzioni molto bene con la versione precedente
del server che aveva i commenti come sotto-documenti dei tuoi piatti stessi.
Ora, questo sarà un modo interessante di implementarlo.
Naturalmente, è un po 'più complicato del modo in cui abbiamo
implementato il client React dove abbiamo mantenuto i commenti indipendenti dai
piatti, ma poi il lavoro aggiuntivo è quindi
la responsabilità del lato client perché è necessario selezionare
i commenti appropriati quando si mostra un piatto specifico.
È necessario selezionare i commenti da tutti i commenti qui.
Quindi, questo è un lavoro aggiuntivo che il nostro cliente React fa a causa
del fatto che abbiamo separato i commenti dai piatti stessi.
Allo stesso modo, se puoi riprogettare il tuo cliente angolare per essere in grado di
affrontare la situazione in cui i commenti sono tenuti indipendenti dai tuoi piatti.
Ora, quindi questi sono tutti esercizi che puoi fare per vedere come puoi
estendere le tue applicazioni client per gestire qualsiasi tipo di server,
i due diversi tipi di server lì.
Quindi, con questo, completiamo l'aggiornamento al nostro server qui.
Quindi, con questo, abbiamo aggiornato tutto sul lato server.
Quindi, salviamo tutte le modifiche sul lato server.
Così ora, il nostro server è pronto a gestire le richieste in arrivo dal nostro client React.
Con questo, completiamo questo esercizio.
In questo esercizio, abbiamo ora preparato il nostro server espresso
per gestire le richieste in arrivo dal nostro client React.
Nel prossimo esercizio, andremo a esaminare il client reagire in modo più dettagliato per
capire come sta comunicando con questo server aggiuntivo.
Questo è un buon momento per fare
una copertura git con il messaggio che integra client e server.