Distribuire API GraphQL/MongoDB utilizzando le funzioni Netlify
Pawel Rybczynski
Software Engineer
Obiettivi Impostazione iniziale Installazione delle dipendenze Iniziamo Per prima cosa, aggiungiamo il file tsconfig.json alla cartella principale: Ora, creiamo src/server.ts per le implementazioni dei server. Poi aggiungiamo due funzioni: una per il server locale e l'altra per lambda. Ok, non abbiamo risolutori o definizioni di tipi, quindi dobbiamo crearne alcuni. Supponiamo che, all'inizio, vogliamo [...]
Obiettivi
Configurare i server locali e lambda.
Collegare entrambi a MongoDB.
Implementare l'autenticazione di base.
Distribuire Apollo senza server GraphQL API con Netlify.
Ok, non abbiamo nessun resolver o definizione di tipo, quindi dobbiamo crearne qualcuno. Supponiamo che, all'inizio, vogliamo creare utenti e ricevere informazioni su di loro.
Ma non abbiamo alcun dato... Risolviamo il problema 😉
Non dimenticare di importare la definizione del tipo e il resolver sul server.
// src/server.ts
importare { ApolloServer as ApolloServerLambda } da "apollo-server-lambda";
importare { ApolloServer } da "apollo-server";
importare { typeDefs } da "./schemas";
importare { resolvers } da "./resolvers";
{...}
Connettersi con MongoDB tramite mongoose
Ora è il momento di creare una connessione con il nostro database. In questo caso particolare, si tratta di MongoDB. È gratuito e facile da mantenere. Ma prima di questo, installiamo altre due dipendenze:
npm install --save mongoose dotenv
Il primo passo consiste nel creare un Modello utente.
La sicurezza prima di tutto! Ora proteggiamo le nostre password con l'hashing.
npm install --save bcrypt @types/bcrypt
Ora, implementare la sicurezza della password nel callback del pre-middleware. Le funzioni pre-middleware vengono eseguite una dopo l'altra, quando ogni middleware chiama il successivo. Per rendere sicure le password, utilizziamo una tecnica che genera un sale e un hash in chiamate di funzione separate.
// src/model.ts
importare bcrypt da "bcrypt";
{...}
const SALT_WORK_FACTOR: number = 10;
UserSchema.pre("save", function (next) {
const user = this as User;
if (!this.isModified("password")) return next();
bcrypt.genSalt(SALT_WORK_FACTOR, function (err, salt) {
if (err) return next(err);
bcrypt.hash(password.utente, sale, function (err, hash) {
if (err) return next(err);
user.password = hash;
next();
});
});
});
{...}
Aggiungere quindi il metodo comparePasswords a UserSchema:
// src/model.ts
{...}
UserSchema.methods.comparePasswords = function (
candidatePassword: string,
cb: (err: Error | null, same: boolean | null) => void
) {
const user = this as User;
bcrypt.compare(candidatePassword, user.password, (err, isMatch) => {
if (err) {
return cb(err, null);
}
cb(null, isMatch);
});
};
{...}
Ora possiamo organizzare una connessione tra i server e i database. MONGODB_URI è una variabile d'ambiente che contiene una stringa di connessione necessaria per creare la connessione. È possibile ottenerla dal pannello del cluster dopo aver effettuato l'accesso al proprio account MongoDB atlas. Inserirla all'interno di .env
// .env
MONGODB_URI = ...;
Ricordate sempre di aggiungere il file a .gitignore. Ottimo! Ora aggiungiamo una funzione che permetta di connettersi al db.
Il contesto è un oggetto condiviso da tutti i risolutori. Per fornirlo, basta aggiungere una funzione di inizializzazione del contesto al costruttore di ApolloServer. Facciamolo.
Dovreste ottenere queste informazioni all'interno del terminale:
Server ir in esecuzione a http://localhost:4000/
In caso affermativo, aprire il file http://localhost:4000/ all'interno del browser.
Dovrebbe apparire l'area di gioco GraphQL. Creiamo un nuovo utente!
Date un'occhiata a come appare nel database.
Fantastico! Tutto funziona bene!
Cerchiamo di ottenere alcune informazioni sull'utente.
E aggiungere il campo della password...
Bello! Riceviamo un errore Impossibile interrogare il campo "password" sul tipo "Utente"".. Come si può verificare, non abbiamo aggiunto questo campo nella definizione del tipo di utente. È lì di proposito. Non dobbiamo rendere possibile l'interrogazione di password o altri dati sensibili.
Un'altra cosa... Possiamo ottenere i dati degli utenti senza alcuna autenticazione... non è una buona soluzione. Dobbiamo risolvere il problema.
Ma prima...
Configurare Codegen
Utilizziamo il GraphQL codice per ottenere un tipo di base compatibile, basato sul nostro schema.