Introduction
GDPR imposes strict obligations for personal data protection. In 2026, companies must demonstrate compliance through concrete technical mechanisms. This tutorial guides you step by step in implementing a REST API that manages consents, data exports, and anonymization. We use Node.js and TypeScript to ensure maintainable and secure code.
Prerequisites
- Node.js 20+
- TypeScript 5.4+
- PostgreSQL 15+
- Basic knowledge of Express and Prisma
- AWS account or equivalent for encryption
Prisma Configuration for GDPR Logs
model Consent {
id String @id @default(uuid())
userId String
purpose String
granted Boolean
timestamp DateTime @default(now())
ipAddress String
}
model DataExport {
id String @id @default(uuid())
userId String
status String @default("pending")
fileUrl String?
createdAt DateTime @default(now())
}This Prisma schema records consents with timestamps and IP addresses, as well as data export requests. It helps prove compliance during an audit.
Consent Middleware
import { Request, Response, NextFunction } from 'express';
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
export async function checkConsent(req: Request, res: Response, next: NextFunction) {
const userId = req.headers['x-user-id'] as string;
const purpose = 'marketing';
const consent = await prisma.consent.findFirst({
where: { userId, purpose, granted: true }
});
if (!consent) {
return res.status(403).json({ error: 'Consentement requis' });
}
next();
}This middleware checks consent before any data processing operation. It rejects requests without valid consent and records the IP for traceability.
Data Export Endpoint
import { Router } from 'express';
import { PrismaClient } from '@prisma/client';
import { generateExport } from '../utils/export';
const router = Router();
const prisma = new PrismaClient();
router.post('/export', async (req, res) => {
const userId = req.body.userId;
const exportRequest = await prisma.dataExport.create({
data: { userId, status: 'processing' }
});
const data = await generateExport(userId);
res.json({ exportId: exportRequest.id, data });
});
export default router;This endpoint creates an export request and generates a structured JSON file. It respects the GDPR right to data portability.
Data Anonymization Function
export function anonymizeUserData(data: any): any {
return {
...data,
email: data.email ? data.email.split('@')[0] + '@anonymized.com' : null,
ipAddress: '0.0.0.0',
name: 'Utilisateur Anonyme',
timestamp: new Date(data.timestamp).toISOString().split('T')[0]
};
}This function replaces identifying data with anonymous values. It is used before any long-term storage or data sharing.
Data Deletion Route
import { Router } from 'express';
import { PrismaClient } from '@prisma/client';
const router = Router();
const prisma = new PrismaClient();
router.delete('/user/:id', async (req, res) => {
const userId = req.params.id;
await prisma.consent.deleteMany({ where: { userId } });
await prisma.dataExport.deleteMany({ where: { userId } });
res.status(204).send();
});
export default router;This route implements the right to erasure. It removes all records linked to a user without leaving any identifying traces.
Best Practices
- Always log consents with timestamps and IP addresses
- Encrypt personal data at rest with AES-256
- Limit data retention to a maximum of 13 months
- Provide an export mechanism in JSON or CSV format
- Regularly test deletion procedures with automated audits
Common Mistakes to Avoid
- Forgetting to check consent before any data processing
- Storing personal data without anonymization after the legal period
- Failing to implement an audit log for data access
- Ignoring user export and deletion requests
Going Further
Deepen your skills with our GDPR and security courses at Learni. You will find advanced modules on encryption and automated compliance.