ultimate-crud
Version:
Ultimate dynamic CRUD API generator with REST, GraphQL, OpenAPI support and association handling for Node.js/Express/Sequelize
172 lines (144 loc) ⢠6.26 kB
JavaScript
/**
* Enhanced PUT/PATCH Operations Demo for Ultimate CRUD
* Demonstrates PUT, PATCH, and bulk update capabilities
*
* @license MIT
* @copyright 2025 cnos-dev
* @author Harish Kashyap (CNOS Dev)
*/
const express = require('express');
const { Sequelize } = require('sequelize');
const UltimateCrud = require('../index');
const app = express();
app.use(express.json());
// SQLite database for demo
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'put-demo.db',
logging: false
});
// Entity configuration with enhanced CRUD operations
const entities = [
{
name: 'products',
type: 'table',
route: '/api/products',
responseMessages: {
200: 'Success',
201: 'Product created successfully',
400: 'Invalid request data',
404: 'Product not found',
409: 'Product with this SKU already exists',
422: 'Product validation failed',
500: 'Internal server error'
}
}
];
async function setupDatabase() {
console.log('š§ Setting up database for PUT/PATCH demo...');
try {
// Create products table
await sequelize.query(`
CREATE TABLE IF NOT EXISTS products (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name VARCHAR(100) NOT NULL,
sku VARCHAR(50) NOT NULL UNIQUE,
price DECIMAL(10,2) NOT NULL,
description TEXT,
category VARCHAR(50),
stock INTEGER DEFAULT 0,
active BOOLEAN DEFAULT 1,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
)
`);
// Insert sample data
await sequelize.query(`
INSERT OR REPLACE INTO products (id, name, sku, price, description, category, stock) VALUES
(1, 'Laptop Pro', 'LPT-001', 1299.99, 'High-performance laptop', 'Electronics', 10),
(2, 'Wireless Mouse', 'MSE-002', 29.99, 'Ergonomic wireless mouse', 'Electronics', 50),
(3, 'Office Chair', 'CHR-003', 249.99, 'Comfortable office chair', 'Furniture', 15)
`);
console.log('ā
Database and sample data created');
} catch (error) {
console.error('ā Database setup failed:', error.message);
throw error;
}
}
async function startServer() {
try {
// Setup database
await setupDatabase();
// Initialize Ultimate CRUD
const ultimateCrud = UltimateCrud.create({
app,
sequelize,
entities,
enableGraphQL: false,
enableRest: true,
enableOpenAPI: true,
syncDatabase: false
});
await ultimateCrud.initialize();
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`š PUT/PATCH Demo Server running on http://localhost:${PORT}`);
console.log(`š OpenAPI Spec: http://localhost:${PORT}/openapi.json`);
console.log('\nš Enhanced PUT/PATCH Operations Demo:');
console.log('==========================================');
console.log('\n1ļøā£ GET all products:');
console.log(`curl http://localhost:${PORT}/api/products`);
console.log('\n2ļøā£ PUT (Full Replace) - Update entire product:');
console.log(`curl -X PUT http://localhost:${PORT}/api/products/1 \\`);
console.log(` -H "Content-Type: application/json" \\`);
console.log(` -d '{"name":"Gaming Laptop Pro","sku":"LPT-001","price":1499.99,"description":"High-end gaming laptop","category":"Gaming","stock":8,"active":true}'`);
console.log('\n3ļøā£ PATCH (Partial Update) - Update only specific fields:');
console.log(`curl -X PATCH http://localhost:${PORT}/api/products/2 \\`);
console.log(` -H "Content-Type: application/json" \\`);
console.log(` -d '{"price":24.99,"stock":75}'`);
console.log('\n4ļøā£ BULK PUT - Update multiple products:');
console.log(`curl -X PUT http://localhost:${PORT}/api/products \\`);
console.log(` -H "Content-Type: application/json" \\`);
console.log(` -d '[`);
console.log(` {"id":1,"price":1399.99,"stock":12},`);
console.log(` {"id":2,"price":27.99,"description":"Premium wireless mouse"},`);
console.log(` {"id":3,"stock":20,"active":true}`);
console.log(` ]'`);
console.log('\n5ļøā£ GET specific product to verify changes:');
console.log(`curl http://localhost:${PORT}/api/products/1`);
console.log('\n6ļøā£ Error handling - PATCH non-existent product:');
console.log(`curl -X PATCH http://localhost:${PORT}/api/products/999 \\`);
console.log(` -H "Content-Type: application/json" \\`);
console.log(` -d '{"price":99.99}'`);
console.log('\n7ļøā£ Error handling - Invalid bulk update (missing ID):');
console.log(`curl -X PUT http://localhost:${PORT}/api/products \\`);
console.log(` -H "Content-Type: application/json" \\`);
console.log(` -d '[{"name":"Invalid Product","price":50}]'`);
console.log('\n8ļøā£ Error handling - Invalid bulk update format:');
console.log(`curl -X PUT http://localhost:${PORT}/api/products \\`);
console.log(` -H "Content-Type: application/json" \\`);
console.log(` -d '{"not":"an_array"}'`);
console.log('\nš” HTTP Methods Supported:');
console.log(' GET - Retrieve resources');
console.log(' POST - Create new resources');
console.log(' PUT - Full resource replacement (individual or bulk)');
console.log(' PATCH - Partial resource modification');
console.log(' DELETE - Remove resources');
console.log('\nš Key Differences:');
console.log(' PUT vs PATCH:');
console.log(' ⢠PUT replaces the entire resource');
console.log(' ⢠PATCH updates only specified fields');
console.log(' ⢠PUT /api/products (bulk) updates multiple resources');
console.log(' ⢠PUT /api/products/:id updates single resource');
console.log('\nšÆ Try the commands above to test enhanced PUT/PATCH operations!');
});
} catch (error) {
console.error('ā Server startup failed:', error.message);
process.exit(1);
}
}
// Start the demo server
if (require.main === module) {
startServer();
}
module.exports = { startServer };