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}`);
});