N
Neon15mo ago
extended-salmon

Multi-tenant Approach using One Project per Tenant

Is this sort of the ideal approach to multi-tenant (project per tenant) with Neon?
TENANT1_DATABASE_URL="postgresql://<user>:<password>@<endpoint_hostname>.neon.tech:<port>/<dbname>?sslmode=require"
TENANT2_DATABASE_URL="postgresql://<user>:<password>@<endpoint_hostname>.neon.tech:<port>/<dbname>?sslmode=require"
TENANT1_DATABASE_URL="postgresql://<user>:<password>@<endpoint_hostname>.neon.tech:<port>/<dbname>?sslmode=require"
TENANT2_DATABASE_URL="postgresql://<user>:<password>@<endpoint_hostname>.neon.tech:<port>/<dbname>?sslmode=require"
require('dotenv').config();

const express = require('express');
const { neon } = require('@neondatabase/serverless');

const app = express();
const PORT = process.env.PORT || 3000;

// Middleware to determine tenant based on request
const tenantMiddleware = (req, res, next) => {
// For this example, we'll use a query parameter to determine the tenant
// In a real-world scenario, you might use subdomains, headers, or JWT claims
const tenantId = req.query.tenant;
if (tenantId === '1' || tenantId === '2') {
req.tenantId = tenantId;
next();
} else {
res.status(400).json({ error: 'Invalid tenant' });
}
};

app.use(tenantMiddleware);

app.get('/', async (req, res) => {
const databaseUrl = process.env[`TENANT${req.tenantId}_DATABASE_URL`];
const sql = neon(databaseUrl);

try {
// This is just an example query. Replace with your actual query.
const response = await sql`SELECT * FROM users LIMIT 5`;
res.json(response);
} catch (error) {
console.error('Database query failed', error);
res.status(500).json({ error: 'Internal Server Error' });
}
});

app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
require('dotenv').config();

const express = require('express');
const { neon } = require('@neondatabase/serverless');

const app = express();
const PORT = process.env.PORT || 3000;

// Middleware to determine tenant based on request
const tenantMiddleware = (req, res, next) => {
// For this example, we'll use a query parameter to determine the tenant
// In a real-world scenario, you might use subdomains, headers, or JWT claims
const tenantId = req.query.tenant;
if (tenantId === '1' || tenantId === '2') {
req.tenantId = tenantId;
next();
} else {
res.status(400).json({ error: 'Invalid tenant' });
}
};

app.use(tenantMiddleware);

app.get('/', async (req, res) => {
const databaseUrl = process.env[`TENANT${req.tenantId}_DATABASE_URL`];
const sql = neon(databaseUrl);

try {
// This is just an example query. Replace with your actual query.
const response = await sql`SELECT * FROM users LIMIT 5`;
res.json(response);
} catch (error) {
console.error('Database query failed', error);
res.status(500).json({ error: 'Internal Server Error' });
}
});

app.listen(PORT, () => {
console.log(`Server running on http://localhost:${PORT}`);
});
9 Replies
extended-salmon
extended-salmonOP15mo ago
Context: this is from Neon AI
extended-salmon
extended-salmon15mo ago
Hey! Do you mind sharing more details about what you're building? Happy to point you in the right direction 😄
extended-salmon
extended-salmonOP15mo ago
Hey @Mahmoud I'm trying to build a single backend api that will handle multi-tenant requests. I'm essentially trying to achieve this using tenant/project.
No description
extended-salmon
extended-salmonOP15mo ago
Neon
Multi-tenancy and Database-per-User Design in Postgres - Neon
The first blog post of a series series dedicated to building and scaling multi-tenant, database-per-user apps in Postgres via Neon.
generous-apricot
generous-apricot15mo ago
I too am looking into exactly this. I.e the recommended approach / best practice (with example code would be added bonus). This is the closest I have found ... https://github.com/neondatabase/ai-vector-db-per-tenant
GitHub
GitHub - neondatabase/ai-vector-db-per-tenant: Example chat-with-pd...
Example chat-with-pdf app showing how to provision a dedicated vector database instance for each user. Powered by Neon - neondatabase/ai-vector-db-per-tenant
extended-salmon
extended-salmon15mo ago
This is something we're actively working on documentation-wise Do you mind sharing more details about your tech stack of choice?
generous-apricot
generous-apricot15mo ago
@ʞk ... 👆 ... I don't want to hijack your thread 😉
extended-salmon
extended-salmonOP15mo ago
Currently using Elysia.js for backend and Next.js for frontend. No worries!
extended-salmon
extended-salmon14mo ago

Did you find this page helpful?