Node.js RESTful API

REST கட்டமைப்பு பாணியைப் பயன்படுத்தி திறமையான மற்றும் அளவிடக்கூடிய வலை சேவைகளை உருவாக்க கற்றுக்கொள்ளுங்கள்

RESTful APIகளைப் புரிந்துகொள்வது

REST (Representational State Transfer) என்பது வலை சேவைகளுக்கான தரமாக மாறியுள்ள பிணைய பயன்பாடுகளை வடிவமைப்பதற்கான ஒரு கட்டமைப்பு பாணியாகும்.

RESTful APIகள் பயன்பாடுகளை ஒருங்கிணைப்பதற்கும் வெவ்வேறு அமைப்புகளுக்கு இடையே தகவல்தொடர்பை இயக்குவதற்கும் ஒரு நெகிழ்வான, இலகுவான வழியை வழங்குகின்றன.

முக்கிய கருத்துக்கள்:

வளங்கள்

எல்லாமே ஒரு வளமாகும் (பயனர், தயாரிப்பு, ஆர்டர்)

பிரதிநிதித்துவங்கள்

வளங்களுக்கு பல பிரதிநிதித்துவங்கள் இருக்கலாம் (JSON, XML, முதலியன)

நிலையற்ற

ஒவ்வொரு கோரிக்கையும் தேவையான அனைத்து தகவல்களையும் கொண்டுள்ளது

ஒருங்கிணைந்த இடைமுகம்

வளங்களை அணுகவும் கையாளவும் சீரான வழி

RESTful APIகள் வளங்களில் CRUD செயல்பாடுகளை (Create, Read, Update, Delete) செய்ய HTTP கோரிக்கைகளைப் பயன்படுத்துகின்றன, அவை URLகளாக குறிப்பிடப்படுகின்றன.

REST என்பது நிலையற்றது, அதாவது ஒரு வாடிக்கையாளரிடமிருந்து சேவையகத்திற்கான ஒவ்வொரு கோரிக்கையும் கோரிக்கையைப் புரிந்துகொள்வதற்கும் செயலாக்குவதற்கும் தேவையான அனைத்து தகவல்களையும் கொண்டிருக்க வேண்டும்.

SOAP அல்லது RPC போலல்லாமல், REST என்பது ஒரு நெறிமுறை அல்ல, ஆனால் HTTP, URI, JSON மற்றும் XML போன்ற இருக்கும் வலை தரங்களைப் பயன்படுத்தும் ஒரு கட்டமைப்பு பாணியாகும்.

முக்கிய REST கொள்கைகள்

இந்த கொள்கைகளைப் புரிந்துகொள்வது திறம்பட்ட RESTful APIகளை வடிவமைப்பதற்கு முக்கியமானது.

அவை உங்கள் API அளவிடக்கூடிய, பராமரிக்கக்கூடிய மற்றும் பயன்படுத்த எளிதானது என்பதை உறுதி செய்கின்றன.

நடைமுறையில் முக்கிய கொள்கைகள்:

வள-அடிப்படையிலான: செயல்களை விட வளங்களில் கவனம் செலுத்துங்கள்
நிலையற்ற: ஒவ்வொரு கோரிக்கையும் சுயாதீனமானது மற்றும் சுய-கொண்டுள்ளது
கேச் செய்யக்கூடிய: பதில்கள் அவற்றின் கேச் செய்யும் தன்மையை வரையறுக்கின்றன
ஒருங்கிணைந்த இடைமுகம்: சீரான வள அடையாளம் மற்றும் கையாளுதல்
அடுக்கு அமைப்பு: வாடிக்கையாளர் அடிப்படை கட்டமைப்பைப் பற்றி தெரிந்து கொள்ள தேவையில்லை

REST கட்டமைப்பின் முக்கிய கொள்கைகள் அடங்கும்:

HTTP முறைகள் மற்றும் அவற்றின் பயன்பாடு

RESTful APIகள் வளங்களில் செயல்பாடுகளைச் செய்ய நிலையான HTTP முறைகளைப் பயன்படுத்துகின்றன.

ஒவ்வொரு முறைக்கும் குறிப்பிட்ட சொற்பொருள் உள்ளது மற்றும் பொருத்தமாக பயன்படுத்தப்பட வேண்டும்.

🔄 சக்தி மாற்றம் மற்றும் பாதுகாப்பு:

  • பாதுகாப்பான முறைகள்: GET, HEAD, OPTIONS (வளங்களை மாற்றக்கூடாது)
  • சக்தி மாற்ற முறைகள்: GET, PUT, DELETE (பல ஒத்த கோரிக்கைகள் = ஒன்றின் அதே விளைவு)
  • சக்தி மாற்றம் இல்லாதவை: POST, PATCH (பல அழைப்புகளுடன் வெவ்வேறு விளைவுகளைக் கொண்டிருக்கலாம்)

எப்போதும் உங்கள் செயல்பாட்டின் நோக்கத்துடன் பொருந்தும் மிகவும் குறிப்பிட்ட முறையைப் பயன்படுத்தவும்.

முறை செயல் எடுத்துக்காட்டு
GET வள(கள்)ஐ மீட்டெடுக்கவும் GET /api/users
POST ஒரு புதிய வளத்தை உருவாக்கவும் POST /api/users
PUT ஒரு வளத்தை முழுமையாக புதுப்பிக்கவும் PUT /api/users/123
PATCH ஒரு வளத்தை பகுதியாக புதுப்பிக்கவும் PATCH /api/users/123
DELETE ஒரு வளத்தை நீக்கவும் DELETE /api/users/123

எடுத்துக்காட்டு: வெவ்வேறு HTTP முறைகளைப் பயன்படுத்துதல்

const express = require('express');
const app = express();

// Middleware for parsing JSON
app.use(express.json());

let users = [
  { id: 1, name: 'John Doe', email: 'john@example.com' },
  { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
];

// GET - Retrieve all users
app.get('/api/users', (req, res) => {
  res.json(users);
});

// GET - Retrieve a specific user
app.get('/api/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });
  res.json(user);
});

// POST - Create a new user
app.post('/api/users', (req, res) => {
  const newUser = {
    id: users.length + 1,
    name: req.body.name,
    email: req.body.email
  };
  users.push(newUser);
  res.status(201).json(newUser);
});

// PUT - Update a user completely
app.put('/api/users/:id', (req, res) => {
  const user = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ message: 'User not found' });

  user.name = req.body.name;
  user.email = req.body.email;

  res.json(user);
});

// DELETE - Remove a user
app.delete('/api/users/:id', (req, res) => {
  const userIndex = users.findIndex(u => u.id === parseInt(req.params.id));
  if (userIndex === -1) return res.status(404).json({ message: 'User not found' });

  const deletedUser = users.splice(userIndex, 1);
  res.json(deletedUser[0]);
});

app.listen(8080, () => {
  console.log('REST API server running on port 8080');
});

RESTful API கட்டமைப்பு மற்றும் வடிவமைப்பு

நன்கு வடிவமைக்கப்பட்ட API அதை உள்ளுணர்வு மற்றும் பயன்படுத்த எளிதானதாக மாற்றும் சீரான வடிவங்களைப் பின்பற்றுகிறது. நல்ல API வடிவமைப்பு டெவலப்பர் அனுபவம் மற்றும் நீண்ட கால பராமரிப்புக்கு முக்கியமானது.

வடிவமைப்பு கருத்தில் கொள்ள வேண்டியவை:

வள பெயரிடல்: வினைச்சொற்களை அல்ல, பெயர்ச்சொற்களைப் பயன்படுத்தவும் (எ.கா., /users not /getUsers)
பன்மைப்படுத்தல்: தொகுப்புகளுக்கு பன்மையைப் பயன்படுத்தவும் (/users/123 not /user/123)
படிநிலை: உறவுகளைக் காட்ட வளங்களை கூடு கட்டவும் (/users/123/orders)
வடிகட்டுதல்/வரிசைப்படுத்துதல்: விருப்ப செயல்பாடுகளுக்கு வினா அளவுருக்களைப் பயன்படுத்தவும்
பதிப்பு உத்தி: தொடக்கத்திலிருந்தே API பதிப்பிற்கான திட்டம் (எ.கா., /v1/users vs /v2/users)

நன்கு கட்டமைக்கப்பட்ட API இந்த மரபுகளைப் பின்பற்றுகிறது:

எடுத்துக்காட்டு: நன்கு கட்டமைக்கப்பட்ட API வழிகள்

// Good API structure
app.get('/api/products', getProducts);
app.get('/api/products/:id', getProductById);
app.get('/api/products/:id/reviews', getProductReviews);
app.get('/api/users/:userId/orders', getUserOrders);
app.post('/api/orders', createOrder);

// Filtering and pagination
app.get('/api/products?category=electronics&sort=price&limit=10&page=2');

Node.js மற்றும் Express உடன் REST APIகளை உருவாக்குதல்

Node.js with Express.js RESTful APIகளை உருவாக்குவதற்கான ஒரு சிறந்த அடித்தளத்தை வழங்குகிறது.

பின்வரும் பிரிவுகள் செயல்படுத்தலுக்கான சிறந்த நடைமுறைகள் மற்றும் வடிவங்களை வரையறுக்கின்றன.

முக்கிய கூறுகள்:

Express Router

வழிகளை ஒழுங்கமைப்பதற்கு

மிடில்வேர்

குறுக்கு வெட்டு கவலைகளுக்கு

கண்ட்ரோலர்கள்

கோரிக்கை தர்க்கத்தை கையாள்வதற்கு

மாதிரிகள்

தரவு அணுகல் மற்றும் வணிக தர்க்கத்திற்கு

சேவைகள்

சிக்கலான வணிக தர்க்கத்திற்கு

Express.js என்பது Node.js இல் REST APIகளை உருவாக்குவதற்கான மிகவும் பிரபலமான கட்டமைப்பாகும்.

இங்கே ஒரு அடிப்படை திட்ட கட்டமைப்பு:

Project Structure
- app.js # Main application file
- routes/ # Route definitions
  - users.js
  - products.js
- controllers/ # Request handlers
  - userController.js
  - productController.js
- models/ # Data models
  - User.js
  - Product.js
- middleware/ # Custom middleware
  - auth.js
  - validation.js
- config/ # Configuration files
  - db.js
  - env.js
- utils/ # Utility functions
  - errorHandler.js

எடுத்துக்காட்டு: Express Router ஐ அமைத்தல்

// routes/users.js
const express = require('express');
const router = express.Router();
const { getUsers, getUserById, createUser, updateUser, deleteUser } = require('../controllers/userController');

router.get('/', getUsers);
router.get('/:id', getUserById);
router.post('/', createUser);
router.put('/:id', updateUser);
router.delete('/:id', deleteUser);

module.exports = router;

// app.js
const express = require('express');
const app = express();
const userRoutes = require('./routes/users');

app.use(express.json());
app.use('/api/users', userRoutes);

app.listen(8080, () => {
  console.log('Server is running on port 8080');
});

கண்ட்ரோலர்கள் மற்றும் மாதிரிகள்

வழிகள், கண்ட்ரோலர்கள் மற்றும் மாதிரிகள் இடையே கவலைகளைப் பிரித்தல் குறியீட்டு ஒழுங்கமைப்பு மற்றும் பராமரிப்பை மேம்படுத்துகிறது:

எடுத்துக்காட்டு: கண்ட்ரோலர் செயல்படுத்தல்

// controllers/userController.js
const User = require('../models/User');

const getUsers = async (req, res) => {
  try {
    const users = await User.findAll();
    res.status(200).json(users);
  } catch (error) {
    res.status(500).json({ message: 'Error retrieving users', error: error.message });
  }
};

const getUserById = async (req, res) => {
  try {
    const user = await User.findById(req.params.id);
    if (!user) {
      return res.status(404).json({ message: 'User not found' });
    }
    res.status(200).json(user);
  } catch (error) {
    res.status(500).json({ message: 'Error retrieving user', error: error.message });
  }
};

const createUser = async (req, res) => {
  try {
    const user = await User.create(req.body);
    res.status(201).json(user);
  } catch (error) {
    res.status(400).json({ message: 'Error creating user', error: error.message });
  }
};

module.exports = { getUsers, getUserById, createUser };

API பதிப்பு

பதிப்பு உங்கள் APIயை இருக்கும் வாடிக்கையாளர்களை உடைக்காமல் உருவாக்க உதவுகிறது.

பொதுவான அணுகுமுறைகள் அடங்கும்:

URI பாதை பதிப்பு

/api/v1/users

வினா அளவுரு

/api/users?version=1

தனிப்பயன் தலைப்பு

X-API-Version: 1

Accept தலைப்பு

Accept: application/vnd.myapi.v1+json

எடுத்துக்காட்டு: URI பாதை பதிப்பு

const express = require('express');
const app = express();

// Version 1 routes
const v1UserRoutes = require('./routes/v1/users');
app.use('/api/v1/users', v1UserRoutes);

// Version 2 routes with new features
const v2UserRoutes = require('./routes/v2/users');
app.use('/api/v2/users', v2UserRoutes);

app.listen(8080);

கோரிக்கை சரிபார்ப்பு

தரவு ஒருமைப்பாடு மற்றும் பாதுகாப்பை உறுதிப்படுத்த உள்வரும் கோரிக்கைகளை எப்போதும் சரிபார்க்கவும்.

Joi அல்லது express-validator போன்ற நூலகங்கள் உதவக்கூடும்:

எடுத்துக்காட்டு: Joi உடன் கோரிக்கை சரிபார்ப்பு

const express = require('express');
const Joi = require('joi');
const app = express();

app.use(express.json());

// Validation schema
const userSchema = Joi.object({
  name: Joi.string().min(3).required(),
  email: Joi.string().email().required(),
  age: Joi.number().integer().min(18).max(120)
});

app.post('/api/users', (req, res) => {
  // Validate request body
  const { error } = userSchema.validate(req.body);
  if (error) {
    return res.status(400).json({ message: error.details[0].message });
  }

  // Process valid request
  // ...
  res.status(201).json({ message: 'User created successfully' });
});

app.listen(8080);

பிழை கையாளுதல்

API நுகர்வோருக்கு தெளிவான பின்னூட்டத்தை வழங்க சீரான பிழை கையாளுதலை செயல்படுத்தவும்:

எடுத்துக்காட்டு: மையப்படுத்தப்பட்ட பிழை கையாளுதல்

// utils/errorHandler.js
class AppError extends Error {
  constructor(statusCode, message) {
    super(message);
    this.statusCode = statusCode;
    this.status = `${statusCode}`.startsWith('4') ? 'fail' : 'error';
    this.isOperational = true;

    Error.captureStackTrace(this, this.constructor);
  }
}

module.exports = { AppError };

// middleware/errorMiddleware.js
const errorHandler = (err, req, res, next) => {
  err.statusCode = err.statusCode || 500;
  err.status = err.status || 'error';

  // Different error responses for development and production
  if (process.env.NODE_ENV === 'development') {
    res.status(err.statusCode).json({
      status: err.status,
      message: err.message,
      stack: err.stack,
      error: err
    });
  } else {
    // Production: don't leak error details
    if (err.isOperational) {
      res.status(err.statusCode).json({
        status: err.status,
        message: err.message
      });
    } else {
      // Programming or unknown errors
      console.error('ERROR 💥', err);
      res.status(500).json({
        status: 'error',
        message: 'Something went wrong'
      });
    }
  }
};

module.exports = { errorHandler };

// Usage in app.js
const { errorHandler } = require('./middleware/errorMiddleware');
const { AppError } = require('./utils/errorHandler');

// This route throws a custom error
app.get('/api/error-demo', (req, res, next) => {
  next(new AppError(404, 'Resource not found'));
});

// Error handling middleware (must be last)
app.use(errorHandler);

API ஆவணப்படுத்தல்

நல்ல ஆவணப்படுத்தல் API தத்தெடுப்புக்கு அத்தியாவசியமானது.

Swagger/OpenAPI போன்ற கருவிகள் குறியீட்டிலிருந்து தானாக ஆவணங்களை உருவாக்க முடியும்:

எடுத்துக்காட்டு: Swagger ஆவணப்படுத்தல்

const express = require('express');
const swaggerJsDoc = require('swagger-jsdoc');
const swaggerUi = require('swagger-ui-express');

const app = express();

// Swagger configuration
const swaggerOptions = {
  definition: {
    openapi: '3.0.0',
    info: {
      title: 'User API',
      version: '1.0.0',
      description: 'A simple Express User API'
    },
    servers: [
      {
        url: 'http://localhost:8080',
        description: 'Development server'
      }
    ]
  },
  apis: ['./routes/*.js'] // Path to the API routes folders
};

const swaggerDocs = swaggerJsDoc(swaggerOptions);
app.use('/api-docs', swaggerUi.serve, swaggerUi.setup(swaggerDocs));

/**
* @swagger
* /api/users:
* get:
* summary: Returns a list of users
* description: Retrieve a list of all users
* responses:
* 200:
* description: A list of users
* content:
* application/json:
* schema:
* type: array
* items:
* type: object
* properties:
* id:
* type: integer
* name:
* type: string
* email:
* type: string
*/
app.get('/api/users', (req, res) => {
  // Handler implementation
});

app.listen(8080);

APIகளை சோதித்தல்

சோதனை API நம்பகத்தன்மைக்கு முக்கியமானது.

Jest, Mocha, அல்லது Supertest போன்ற நூலகங்களைப் பயன்படுத்தவும்:

எடுத்துக்காட்டு: Jest மற்றும் Supertest உடன் API சோதனை

// tests/users.test.js
const request = require('supertest');
const app = require('../app');

describe('User API', () => {
  describe('GET /api/users', () => {
    it('should return all users', async () => {
      const res = await request(app).get('/api/users');
      expect(res.statusCode).toBe(200);
      expect(Array.isArray(res.body)).toBeTruthy();
    });
  });
  describe('POST /api/users', () => {
    it('should create a new user', async () => {
      const userData = {
        name: 'Test User',
        email: 'test@example.com'
      };
      const res = await request(app)
        .post('/api/users')
        .send(userData);

      expect(res.statusCode).toBe(201);
      expect(res.body).toHaveProperty('id');
      expect(res.body.name).toBe(userData.name);
    });
    it('should validate request data', async () => {
      const invalidData = {
        email: 'not-an-email'
      };
      const res = await request(app)
        .post('/api/users')
        .send(invalidData);

      expect(res.statusCode).toBe(400);
    });
  });
});

சிறந்த நடைமுறைகள் சுருக்கம்

REST கொள்கைகளைப் பின்பற்றவும் மற்றும் பொருத்தமான HTTP முறைகளைப் பயன்படுத்தவும்
இறுதிப் புள்ளிகளுக்கு சீரான பெயரிடல் மரபுகளைப் பயன்படுத்தவும்
வள-அடிப்படையிலான URLகளுடன் உங்கள் APIயை தர்க்கரீதியாக கட்டமைக்கவும்
பதில்களில் பொருத்தமான நிலை குறியீடுகளைத் திருப்பி அனுப்பவும்
தெளிவான செய்திகளுடன் சரியான பிழை கையாளுதலை செயல்படுத்தவும்
பெரிய தரவு தொகுப்புகளுக்கு பக்கமிடலைப் பயன்படுத்தவும்
பின்னோக்கி இணக்கத்தன்மையை பராமரிக்க உங்கள் APIயை பதிப்பு செய்யவும்
பாதுகாப்பு பிரச்சினைகளைத் தடுக்க அனைத்து உள்ளீட்டையும் சரிபார்க்கவும்
உங்கள் APIயை முழுமையாக ஆவணப்படுத்தவும்
நம்பகத்தன்மையை உறுதிப்படுத்த விரிவான சோதனைகளை எழுதவும்
அனைத்து உற்பத்தி APIகளுக்கும் HTTPS ஐப் பயன்படுத்தவும்
தவறாகப் பயன்படுத்துவதைத் தடுக்க விகிதம் கட்டுப்பாட்டை செயல்படுத்தவும்

பயிற்சி

சரியான சொல்லை இழுத்து விடவும்.

REST API இறுதிப் புள்ளிகள் பொதுவாக செயல்பாடுகளை வரையறுக்க HTTP ______ ஐப் பயன்படுத்துகின்றன.

headers
✗ தவறு! HTTP headers செயல்பாடுகளை வரையறுக்கப் பயன்படுவதில்லை, ஆனால் கூடுதல் தகவல்களை வழங்கப் பயன்படுகின்றன
status codes
✗ தவறு! HTTP status codes கோரிக்கையின் முடிவைக் குறிக்கின்றன, ஆனால் செயல்பாடுகளை வரையறுக்கப் பயன்படுவதில்லை
methods
✓ சரி! REST API இறுதிப் புள்ளிகள் பொதுவாக GET, POST, PUT, DELETE, PATCH போன்ற HTTP methods ஐப் பயன்படுத்தி செயல்பாடுகளை வரையறுக்கின்றன
cookies
✗ தவறு! HTTP cookies நிலையைப் பராமரிக்கப் பயன்படுகின்றன, ஆனால் REST API செயல்பாடுகளை வரையறுக்கப் பயன்படுவதில்லை