Set-up MongoDB in NextJS
Deoarece 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. Configurarea fișierului cu chei de mediu
În fișierul de .env o să salvăm cheile secrete necesare ca proiectul nostru să poată comunica cu baza de date creată în cloud la pașii anteriori.
Deschidem fișierul de .env în care o să adăugăm connection string-ul primit de la MongoDB Cloud și numele colecției cu care urmează să lucrăm.
NODE_ENV = development
NEXT_ATLAS_URI = mongodb+srv://USERNAME:PASSWORD@cluster0.tt3lolq.mongodb.net/
NEXT_ATLAS_DATABASE = CloudComputing
2. Instalarea dependințelor
Pentru a putea lucra cu MongoDB Cloud, suntem nevoiți să adăugăm o noua librărie în proiectul nostru.
Ne mutăm în terminal și rulăm comanda:
npm install mongodb
Dacă totul a mers în regulă, în cadrul fișierului de package.json ar trebui să putem vedea librăria abia instalată în lista de dependințe.

3. Crearea fișierelor de configurare
În cadrul proiectului, creăm un nou folder pe care îl numim lib și unde o să adăugăm fișiere de configurare pentru fiecare librărie sau serviciu pe care urmează să le folosim.
În cadrul folderului lib, o să adăugăm un fișier care se numește mongodb.js și care o să realizeze conexiunea între aplicația noastră și baza de date:
// 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');
}
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);
}
}
Ulterior, o să creăm un nou folder denumit utils, în care o să adăugăm un nou fișier numit functions.js:
// utils/functions.js
import {connectToDatabase,} from '@/lib/mongodb.js';
export const getCollection = async collectionName => {
const {database,} = await connectToDatabase();
return database.collection(collectionName);
};
4. Configurarea API-ului NextJS
Tot în cadrul folderului utils, o să creăm un nou folder denumit apiMethods.js, fișier care conține diferite tipuri de răspuns pentru rutele API pe care urmează să le creăm.
// 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',
}
);
};
Următorul pas este dat de crearea metodelor CRUD în ceea ce privește manipularea datelor din cadrul colecției de records, așadar ne mutăm în cadrul folderului pages/api și o să adăugăm un nou fișier numit records.js.
// /pages/api/records.js
import {sendMethodNotAllowed, sendOk,} from '@/utils/apiMethods.js';
import {getCollection} from "@/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: ObjectId.createFromHexString(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);
}
}
5. Testarea API-urilor
Pentru testarea API-urilor, o să ne folosim de aplicația Postman.
Pentru returnarea tuturor înregistrărilor din colecția records, o să ne folosim de path-ul /api/records și cu metoda GET:

Pentru crearea de noi entry-uri, o să schimbăm metoda la POST, o să selectăm că dorim să trimitem ceva în body-ul requestului, de tip JSON.
După trimiterea requestului, dacă totul a funcționat cum trebuie, o să primim un răspuns cu id-ul entry-ului pe care abia l-am creat.

Pentru editarea unui entry, o să schimbăm metoda la PUT, și o să trimitem obiectul pe care vrem să îl edităm, alături de id-ul obiectului.

Pentru ștergerea uni entry, la path-ul request-ului o să adăugăm și un query parameter, selectăm să nu trimitem body și schimbăm metoda la DELETE.

Last updated