Module 5: Building RESTful APIs with Express


1. RESTful APIs යනු මොනවාද? 🌐

API (Application Programming Interface) යනු මෘදුකාංග දෙකකට එකිනෙකා සමඟ කතා කිරීමට ඉඩ සලසන අතරමැදියෙකි. Web API එකක් මගින් frontend application එකකට (web browser, mobile app) backend server එක සමඟ සන්නිවේදනය කර දත්ත හුවමාරු කර ගැනීමට ඉඩ සලසයි.

REST (REpresentational State Transfer) යනු APIs නිර්මාණය කිරීම සඳහා භාවිතා කරන ගෘහ නිර්මාණ ශිල්පීය මූලධර්ම (architectural principles) සමූහයකි. REST මූලධර්ම අනුගමනය කරන API එකක් **RESTful API** ලෙස හැඳින්වේ. මෙමගින් APIs වඩාත් ක්‍රමවත්, තේරුම් ගැනීමට පහසු සහ නඩත්තු කිරීමට පහසු වේ.

REST හි මූලික මූලධර්ම:

2. CRUD Operations (ක්‍රියාදාමයන්)

ඕනෑම application එකක දත්ත කළමනාකරණය කිරීමේදී මූලික ක්‍රියාදාමයන් හතරක් ඇත. මේවා CRUD ලෙස හඳුන්වයි.

Operation Name Description HTTP Method
Create නිර්මාණය කිරීම අලුතින් දත්ත ඇතුළත් කිරීම. POST
Read කියවීම දැනට ඇති දත්ත ලබා ගැනීම. GET
Update යාවත්කාලීන කිරීම දැනට ඇති දත්ත වෙනස් කිරීම. PUT / PATCH
Delete මකා දැමීම දැනට ඇති දත්ත ඉවත් කිරීම. DELETE

RESTful API එකකදී, අපි මෙම CRUD ක්‍රියාදාමයන් HTTP methods සමඟ සම්බන්ධ කර, සම්පත් (resources) මත ක්‍රියාත්මක කරමු. උදාහරණයක් ලෙස, "users" නමැති resource එකක් සඳහා CRUD මෙසේ විය හැක:


3. JSON Responses යැවීම සහ Route Parameters භාවිතය

APIs වලදී දත්ත හුවමාරු කරගන්නා සම්මත ආකෘතිය (standard format) වන්නේ **JSON (JavaScript Object Notation)** ය. Express හි `res.json()` function එක මගින් JavaScript object එකක් JSON format එකට çevirip client එකට යැවීම ඉතා පහසු කරයි.

Route Parameters යනු URL එකේ ඇති dynamic කොටස් වේ. උදාහරණයක් ලෙස `/users/1` හි `1` යනු parameter එකකි. Express හිදී, අපි path එකේ `:parameterName` ලෙස මෙය අර්ථ දක්වමු.

Project Setup

අපි දැන් මෙම සංකල්ප සියල්ල එකට එකතු කර සරල "Notes API" එකක් ගොඩනගමු. මේ සඳහා database එකක් වෙනුවට, server එක run වන විට මතකයේ (in-memory) රැඳෙන array එකක් භාවිතා කරමු.

`index.js` file එක:


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

// Middleware to parse JSON bodies
// POST සහ PUT requests වලදී එවන JSON data (req.body) කියවීමට මෙය අත්‍යවශ්‍ය වේ.
app.use(express.json());

// In-memory "database"
let notes = [
    { id: 1, title: 'First Note', content: 'This is the first note.' },
    { id: 2, title: 'Second Note', content: 'This is the second note.' }
];

// --- READ (GET) ---
// 1. Get all notes
app.get('/notes', (req, res) => {
    res.json(notes);
});

// 2. Get a single note by ID
// :id යනු route parameter එකයි
app.get('/notes/:id', (req, res) => {
    // req.params object එකෙන් parameter එක ලබා ගැනීම
    const noteId = parseInt(req.params.id);
    const note = notes.find(n => n.id === noteId);

    if (note) {
        res.json(note);
    } else {
        res.status(404).json({ message: 'Note not found' });
    }
});

// --- CREATE (POST) ---
// 3. Create a new note
app.post('/notes', (req, res) => {
    const newNote = {
        id: notes.length > 0 ? notes[notes.length - 1].id + 1 : 1,
        title: req.body.title,
        content: req.body.content
    };

    notes.push(newNote);
    res.status(201).json(newNote); // 201 = Created
});

// --- UPDATE (PUT) ---
// 4. Update an existing note
app.put('/notes/:id', (req, res) => {
    const noteId = parseInt(req.params.id);
    const noteIndex = notes.findIndex(n => n.id === noteId);

    if (noteIndex !== -1) {
        notes[noteIndex].title = req.body.title || notes[noteIndex].title;
        notes[noteIndex].content = req.body.content || notes[noteIndex].content;
        res.json(notes[noteIndex]);
    } else {
        res.status(404).json({ message: 'Note not found' });
    }
});

// --- DELETE ---
// 5. Delete a note
app.delete('/notes/:id', (req, res) => {
    const noteId = parseInt(req.params.id);
    const noteIndex = notes.findIndex(n => n.id === noteId);

    if (noteIndex !== -1) {
        const deletedNote = notes.splice(noteIndex, 1);
        res.json({ message: 'Note deleted successfully', deletedNote: deletedNote[0] });
    } else {
        res.status(404).json({ message: 'Note not found' });
    }
});


app.listen(port, () => {
    console.log(`Notes API server running at http://localhost:${port}`);
});
        

මෙම API එක test කිරීමට ඔබට **Postman** හෝ VS Code හි **Thunder Client** extension එක වැනි මෙවලමක් භාවිතා කළ හැක.


4. Query Strings සමඟ වැඩ කිරීම

Query Strings යනු URL එකේ `?` ලකුණට පසුව එන key-value යුගල වේ. මේවා දත්ත filter කිරීමට, sort කිරීමට හෝ paginate කිරීමට වැනි optional parameters සඳහා භාවිතා වේ. උදා: `/search?q=nodejs&page=2`.

Express හිදී, query strings `req.query` object එක හරහා ලබාගත හැක.

Query String උදාහරණයක්:

අපි අපේ Notes API එකේ සියලු notes ලබාගන්නා (`GET /notes`) route එකට, title එක අනුව filter කිරීමේ හැකියාව එකතු කරමු.


// Get all notes (with optional query string for filtering)
app.get('/notes', (req, res) => {
    const { title } = req.query; // URL එකේ ?title=... ලෙස එවන අගය ලබා ගැනීම

    if (title) {
        const filteredNotes = notes.filter(note => 
            note.title.toLowerCase().includes(title.toLowerCase())
        );
        res.json(filteredNotes);
    } else {
        res.json(notes);
    }
});
        

දැන් ඔබට `http://localhost:3000/notes?title=first` වැනි URL එකකට request කිරීමෙන්, title එකේ "first" යන වචනය අඩංගු notes පමණක් ලබාගත හැක.


Go Back to Module 4 Go to Module 6