En aquest tema, aprendrem a construir una API de comerç electrònic utilitzant Node.js i Express. Aquesta API permetrà gestionar productes, usuaris, comandes i autenticació. A més, implementarem operacions CRUD (Crear, Llegir, Actualitzar, Eliminar) per a cada recurs.

Objectius del Tema

  • Configurar un projecte Node.js amb Express.
  • Crear models de dades per a productes, usuaris i comandes.
  • Implementar operacions CRUD per a cada recurs.
  • Gestionar l'autenticació i l'autorització d'usuaris.
  • Provar l'API utilitzant Postman.

  1. Configuració del Projecte

1.1. Inicialitzar el Projecte

Primer, crearem una nova carpeta per al projecte i inicialitzarem un projecte Node.js.

mkdir ecommerce-api
cd ecommerce-api
npm init -y

1.2. Instal·lar les Dependències Necessàries

Instal·larem Express, Mongoose (per a MongoDB), bcrypt (per a l'encriptació de contrasenyes) i jsonwebtoken (per a l'autenticació).

npm install express mongoose bcrypt jsonwebtoken

1.3. Configurar l'Aplicació Express

Crearem un fitxer app.js per configurar l'aplicació Express.

// app.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

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

// Middleware
app.use(bodyParser.json());

// Connexió a MongoDB
mongoose.connect('mongodb://localhost/ecommerce', { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('Connected to MongoDB'))
  .catch(err => console.error('Could not connect to MongoDB', err));

// Rutes
app.get('/', (req, res) => {
  res.send('Welcome to the E-commerce API');
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

  1. Models de Dades

2.1. Model de Producte

Crearem un model per als productes.

// models/Product.js
const mongoose = require('mongoose');

const productSchema = new mongoose.Schema({
  name: { type: String, required: true },
  description: String,
  price: { type: Number, required: true },
  category: String,
  stock: { type: Number, default: 0 }
});

const Product = mongoose.model('Product', productSchema);

module.exports = Product;

2.2. Model d'Usuari

Crearem un model per als usuaris.

// models/User.js
const mongoose = require('mongoose');
const bcrypt = require('bcrypt');

const userSchema = new mongoose.Schema({
  username: { type: String, required: true, unique: true },
  email: { type: String, required: true, unique: true },
  password: { type: String, required: true }
});

// Encriptar la contrasenya abans de guardar l'usuari
userSchema.pre('save', async function(next) {
  if (!this.isModified('password')) return next();
  const salt = await bcrypt.genSalt(10);
  this.password = await bcrypt.hash(this.password, salt);
  next();
});

const User = mongoose.model('User', userSchema);

module.exports = User;

2.3. Model de Comanda

Crearem un model per a les comandes.

// models/Order.js
const mongoose = require('mongoose');

const orderSchema = new mongoose.Schema({
  user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', required: true },
  products: [
    {
      product: { type: mongoose.Schema.Types.ObjectId, ref: 'Product', required: true },
      quantity: { type: Number, required: true }
    }
  ],
  total: { type: Number, required: true },
  status: { type: String, default: 'Pending' }
});

const Order = mongoose.model('Order', orderSchema);

module.exports = Order;

  1. Rutes i Controladors

3.1. Rutes de Productes

Crearem rutes per gestionar els productes.

// routes/products.js
const express = require('express');
const router = express.Router();
const Product = require('../models/Product');

// Crear un nou producte
router.post('/', async (req, res) => {
  const product = new Product(req.body);
  try {
    await product.save();
    res.status(201).send(product);
  } catch (error) {
    res.status(400).send(error);
  }
});

// Obtenir tots els productes
router.get('/', async (req, res) => {
  try {
    const products = await Product.find();
    res.send(products);
  } catch (error) {
    res.status(500).send(error);
  }
});

// Obtenir un producte per ID
router.get('/:id', async (req, res) => {
  try {
    const product = await Product.findById(req.params.id);
    if (!product) return res.status(404).send();
    res.send(product);
  } catch (error) {
    res.status(500).send(error);
  }
});

// Actualitzar un producte per ID
router.put('/:id', async (req, res) => {
  try {
    const product = await Product.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
    if (!product) return res.status(404).send();
    res.send(product);
  } catch (error) {
    res.status(400).send(error);
  }
});

// Eliminar un producte per ID
router.delete('/:id', async (req, res) => {
  try {
    const product = await Product.findByIdAndDelete(req.params.id);
    if (!product) return res.status(404).send();
    res.send(product);
  } catch (error) {
    res.status(500).send(error);
  }
});

module.exports = router;

3.2. Rutes d'Usuaris

Crearem rutes per gestionar els usuaris.

// routes/users.js
const express = require('express');
const router = express.Router();
const User = require('../models/User');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');

// Registrar un nou usuari
router.post('/register', async (req, res) => {
  const user = new User(req.body);
  try {
    await user.save();
    res.status(201).send(user);
  } catch (error) {
    res.status(400).send(error);
  }
});

// Iniciar sessió
router.post('/login', async (req, res) => {
  try {
    const user = await User.findOne({ email: req.body.email });
    if (!user) return res.status(400).send('Invalid email or password');

    const isMatch = await bcrypt.compare(req.body.password, user.password);
    if (!isMatch) return res.status(400).send('Invalid email or password');

    const token = jwt.sign({ _id: user._id }, 'secretkey');
    res.send({ user, token });
  } catch (error) {
    res.status(500).send(error);
  }
});

module.exports = router;

3.3. Rutes de Comandes

Crearem rutes per gestionar les comandes.

// routes/orders.js
const express = require('express');
const router = express.Router();
const Order = require('../models/Order');

// Crear una nova comanda
router.post('/', async (req, res) => {
  const order = new Order(req.body);
  try {
    await order.save();
    res.status(201).send(order);
  } catch (error) {
    res.status(400).send(error);
  }
});

// Obtenir totes les comandes
router.get('/', async (req, res) => {
  try {
    const orders = await Order.find().populate('user').populate('products.product');
    res.send(orders);
  } catch (error) {
    res.status(500).send(error);
  }
});

// Obtenir una comanda per ID
router.get('/:id', async (req, res) => {
  try {
    const order = await Order.findById(req.params.id).populate('user').populate('products.product');
    if (!order) return res.status(404).send();
    res.send(order);
  } catch (error) {
    res.status(500).send(error);
  }
});

// Actualitzar una comanda per ID
router.put('/:id', async (req, res) => {
  try {
    const order = await Order.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true });
    if (!order) return res.status(404).send();
    res.send(order);
  } catch (error) {
    res.status(400).send(error);
  }
});

// Eliminar una comanda per ID
router.delete('/:id', async (req, res) => {
  try {
    const order = await Order.findByIdAndDelete(req.params.id);
    if (!order) return res.status(404).send();
    res.send(order);
  } catch (error) {
    res.status(500).send(error);
  }
});

module.exports = router;

3.4. Integrar les Rutes a l'Aplicació

Finalment, integrarem les rutes a l'aplicació principal.

// app.js
const express = require('express');
const mongoose = require('mongoose');
const bodyParser = require('body-parser');

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

// Middleware
app.use(bodyParser.json());

// Connexió a MongoDB
mongoose.connect('mongodb://localhost/ecommerce', { useNewUrlParser: true, useUnifiedTopology: true })
  .then(() => console.log('Connected to MongoDB'))
  .catch(err => console.error('Could not connect to MongoDB', err));

// Rutes
const productRoutes = require('./routes/products');
const userRoutes = require('./routes/users');
const orderRoutes = require('./routes/orders');

app.use('/api/products', productRoutes);
app.use('/api/users', userRoutes);
app.use('/api/orders', orderRoutes);

app.get('/', (req, res) => {
  res.send('Welcome to the E-commerce API');
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});

  1. Provar l'API

4.1. Utilitzar Postman

Utilitzarem Postman per provar les diferents rutes de l'API. Aquí teniu alguns exemples de peticions:

  • Crear un producte:

    • Mètode: POST
    • URL: http://localhost:3000/api/products
    • Cos:
      {
        "name": "Product 1",
        "description": "Description of Product 1",
        "price": 100,
        "category": "Category 1",
        "stock": 10
      }
      
  • Obtenir tots els productes:

    • Mètode: GET
    • URL: http://localhost:3000/api/products
  • Registrar un usuari:

    • Mètode: POST
    • URL: http://localhost:3000/api/users/register
    • Cos:
      {
        "username": "user1",
        "email": "[email protected]",
        "password": "password123"
      }
      
  • Iniciar sessió:

    • Mètode: POST
    • URL: http://localhost:3000/api/users/login
    • Cos:
      {
        "email": "[email protected]",
        "password": "password123"
      }
      
  • Crear una comanda:

    • Mètode: POST
    • URL: http://localhost:3000/api/orders
    • Cos:
      {
        "user": "user_id",
        "products": [
          {
            "product": "product_id",
            "quantity": 2
          }
        ],
        "total": 200
      }
      

Conclusió

En aquest tema, hem après a crear una API de comerç electrònic utilitzant Node.js i Express. Hem configurat el projecte, creat models de dades, implementat operacions CRUD i gestionat l'autenticació d'usuaris. També hem provat l'API utilitzant Postman. Aquest és un bon punt de partida per desenvolupar aplicacions de comerç electrònic més complexes i robustes.

Curs de Node.js

Mòdul 1: Introducció a Node.js

Mòdul 2: Conceptes Bàsics

Mòdul 3: Sistema de Fitxers i I/O

Mòdul 4: HTTP i Servidors Web

Mòdul 5: NPM i Gestió de Paquets

Mòdul 6: Framework Express.js

Mòdul 7: Bases de Dades i ORMs

Mòdul 8: Autenticació i Autorització

Mòdul 9: Proves i Depuració

Mòdul 10: Temes Avançats

Mòdul 11: Desplegament i DevOps

Mòdul 12: Projectes del Món Real

© Copyright 2024. Tots els drets reservats