Prerequisites: Set-up NextJS si Set-up Cloud Storage MongoDB
1. Initializarea conexiunii NextJS - MongoDB
Pentru ca scopul nostru este configurarea si utilizarea tehnologiilor cloud, nu invatarea unor noi limbaje de programare, majoritatea codului "boilerplate" si functiilor utile vor fi puse la dispozitie de mine si le puteti folosi in proiecte.
1.1. Adaugarea fisierului .env
In fisierul .env vom stoca date secrete (cum ar fi connection string-ul pentru BD), care nu ne dorim sa fie versionate cu git (stocate in cod) si sa ajunga publice.
Accesati proiectul NextJS
Modificati fisierul .gitignore. Adaugati pe ultima linie: .env
In root-ul proiectului, creati fisierul .env
Copy # .env
NODE_ENV=development
NEXT_ATLAS_URI=mongodb+srv://<user>:<password>@cluster0.8qqv1kp.mongodb.net/?retryWrites=true&w=majority
NEXT_ATLAS_DATABASE=<your_database_name>
Copiati continutul de mai sus si inlocuiti userul, parola si numele bazei de date create (ATENTIE: Numele bazei de date !== Numele colectiei create ). Save
2.2 Configurarea conexiunii la BD
In terminal, in folderul proiectului curent, rulati npm i mongodb
Creati in root-ul proiectului un folder cu denumirea lib
In folderul lib, creati fisierul mongodb.js
Copy and paste the following
Copy // lib/mongodb.js
import { MongoClient , } from 'mongodb' ;
const uri = process . env . NEXT_ATLAS_URI ;
const options = {
useUnifiedTopology : true ,
useNewUrlParser : true ,
};
let mongoClient = null ;
let database = null ;
if ( ! process . env . NEXT_ATLAS_URI ) {
throw new Error ( 'Please add your Mongo URI to .env.local' );
}
export async function connectToDatabase () {
try {
if (mongoClient && database) {
return { mongoClient , database , };
}
if ( process . env . NODE_ENV === 'development' ) {
if ( ! global ._mongoClient) {
mongoClient = await ( new MongoClient (uri , options)) .connect ();
global ._mongoClient = mongoClient;
} else {
mongoClient = global ._mongoClient;
}
} else {
mongoClient = await ( new MongoClient (uri , options)) .connect ();
}
database = await mongoClient .db ( process . env . NEXT_ATLAS_DATABASE );
return { mongoClient , database , };
} catch (e) {
console .error (e);
}
}
In root-ul proiectului, creati folderul js
In folderul js, creati folderul utils
In folderul utils, creati fisierul functions.js
Copy and paste the following
Copy // js/utils/functions.js
import {connectToDatabase , } from '@/lib/mongodb.js' ;
export const getCollection = async collectionName => {
const { database , } = await connectToDatabase ();
return database .collection (collectionName);
};
2.3 Configurarea API-ului NextJS
Tot in folderul utils, creati fisierul apiMethods.js
Copy // js/utils/apiMethods.js
export const sendOk = (res , data) => {
res .status ( 200 ) .json (
{
'data' : data ,
}
);
};
export const sendNotFound = (res , message) => {
res .status ( 404 ) .json (
{
'error' : message ,
}
);
};
export const sendBadRequest = (res , message) => {
res .status ( 400 ) .json (
{
'error' : message ,
}
);
};
export const sendUnauthorized = (res , message) => {
res .status ( 401 ) .json (
{
'error' : message ,
}
);
};
export const sendMethodNotAllowed = res => {
res .status ( 405 ) .json (
{
'error' : 'Method not allowed' ,
}
);
};
Pana acum, structura de fisiere din proiect ar trebui sa arate astfel
In folderul pages/api creati fisierul records.js. Acesta va reprezenta ruta /api/records si va asigura conexiunea si accesul backend - baza de date
Copy // pages/api/records.js
import {sendMethodNotAllowed , sendOk , } from '@/js/utils/apiMethods.js' ;
import {getCollection} from "@/js/utils/functions" ;
import {ObjectId , } from 'mongodb' ;
const COLLECTION_NAME = 'records' ;
const getRecords = async () => {
const collection = await getCollection ( COLLECTION_NAME );
return collection .find ({}) .toArray ();
}
const getRecord = async (id) => {
const collection = await getCollection ( COLLECTION_NAME );
return collection .findOne ({_id : new ObjectId (id)});
}
const postRecord = async (record) => {
const collection = await getCollection ( COLLECTION_NAME );
return collection .insertOne (record);
}
const putRecord = async (record) => {
const collection = await getCollection ( COLLECTION_NAME );
const id = record ._id;
delete record ._id;
return collection .updateOne ({_id : new ObjectId (id)} , {$set : record});
}
const deleteRecord = async (id) => {
const collection = await getCollection ( COLLECTION_NAME );
return collection .deleteOne ({_id : new ObjectId (id)});
}
export default async function handler (req , res) {
const isAllowedMethod = req .method === 'GET' || req .method === 'POST' || req .method === 'PUT' || req .method === 'DELETE' ;
if ( ! isAllowedMethod) {
return sendMethodNotAllowed (res);
}
if ( req .method === 'GET' && req . query .id) {
const id = req . query .id;
const record = await getRecord (id);
return sendOk (res , record);
}
else if ( req .method === 'GET' ) {
const records = await getRecords ();
return sendOk (res , records);
}
else if ( req .method === 'POST' ) {
const record = req .body;
const result = await postRecord (record);
return sendOk (res , result);
}
else if ( req .method === 'PUT' ) {
const record = req .body;
const result = await putRecord (record);
return sendOk (res , result);
}
else if ( req .method === 'DELETE' ) {
const id = req . query .id;
const result = await deleteRecord (id);
return sendOk (res , result);
}
}