Ինչպես ստեղծել NodeJS API առանց Framework օգտագործելու


Շրջանակները հեշտացնում են ձեր կյանքը, իսկ հավելվածները՝ ավելի ամուր: Բայց կարող է օգտակար լինել իմանալ, թե ինչպես կառուցել API առանց դրա:

Node.js-ը բաց կոդով JavaScript-ի գործարկման ժամանակ է՝ կառուցված chrome-ի v8 շարժիչի վրա, որը թույլ է տալիս գործարկել JavaScript կոդը բրաուզերից դուրս:

Իր իրադարձությունների մոդելը, էկոհամակարգը և արագությունը Node.js-ը դարձրել են սերվերի կողմից օգտագործվող գործարկման ժամանակներից մեկը:

Node.js API սերվերների մեծ մասը օգտագործում է Express կամ այլ շրջանակ: Այնուամենայնիվ, դուք կարող եք նաև ստեղծել հասարակ Node.js API առանց շրջանակի ընդամենը մի քանի քայլով:

Քայլ 1. Ստեղծեք ձեր զարգացման միջավայրը

Ստեղծեք նախագծի գրացուցակ և cd դրա մեջ՝ գործարկելով.

mkdir nodejs-api
cd nodejs-api

Հաջորդը, սկզբնավորեք npm ձեր նախագծում՝ գործարկելով.

npm init -y

Այս CRUD API-ն կներառի MongoDB-ի՝ NoSQL տվյալների բազայի և նրա հանրաճանաչ ODM-ի՝ mongoose-ի օգտագործումը:

Գործարկեք հետևյալ հրամանը՝ mongoose տեղադրելու համար.

npm install mongoose

Հաջորդը, ձեր նախագծի արմատական գրացուցակում ստեղծեք server.js ֆայլ և ավելացրեք ստորև բերված կոդի բլոկը՝ սերվեր ստեղծելու համար.

const http = require("http");
const server = http.createServer((req, res) => {});
 
server.listen(3000, () => {
  console.log(`Server is running`);
});

Այս կոդի բլոկը ներմուծում է http մոդուլը՝ հիմնական Node.js մոդուլը: http մոդուլը թույլ է տալիս Node.js-ին տվյալները փոխանցել HTTP-ով: Այս մոդուլը պարունակում է սերվեր ստեղծելու համար անհրաժեշտ մեթոդներ:

Այնուհետև այն կանչում է http մոդուլի createServer մեթոդը, որը ստեղծում և վերադարձնում է սերվերի օրինակ: createServer մեթոդը վերցնում է հետ կանչելու ֆունկցիա՝ որպես պարամետրեր հարցման և պատասխանի օբյեկտ:

Հաջորդը, կոդը կանչում է լսել մեթոդը վերադարձված սերվերի օրինակում: Սա թույլ է տալիս սերվերին սկսել լսել տրաֆիկի համար տվյալ նավահանգիստը: լսել մեթոդը գործարկում է հետ կանչ՝ երկրորդ արգումենտը, երբ այն հաջողվում է:

Վերջապես, ձեր նախագծի արմատական գրացուցակում ստեղծեք երկու դիրեկտորիա՝ երթուղիներ և մոդելներ: երթուղիներ պանակը կպարունակի ձեր API-ի երթուղային տրամաբանությունը, մինչդեռ մոդելը կպարունակի տվյալների բազայի հետ կապված ամեն ինչ:

Քայլ 2. Ձեր հավելվածը միացնելով տվյալների շտեմարանին

server.js-ում ներմուծեք mongoose՝

const mongoose = require("mongoose");

Զանգահարեք միացում մեթոդը mongoose-ի վրա և փոխանցեք ձեր MongoDB URI որպես փաստարկ.

mongoose.connect("MongoDB_URI")

Քայլ 3. API մոդելի ստեղծում

Ստեղծեք CRUD API պարզ բլոգային հավելվածի համար: Ձեր models պանակում ստեղծեք blogModel.js ֆայլ և ավելացրեք հետևյալ կոդը ձեր ֆայլում.

const mongoose = require("mongoose");
const blogSchema = mongoose.Schema({
  title: {
    type: String,
    required: [true, "Blog must have a title"],
  },
  body: {
    type: String,
    required: [true, "Blog must have a body"],
  },
});
module.exports = mongoose.model("Blog", blogSchema);

Վերևում գտնվող կոդի բլոկը ստեղծում է երկու հատկություններով մանգուստ մոդել և դրանք քարտեզագրում MongoDB տվյալների բազայում:

Այս մոդելի երկու հատկություններն էլ ունեն String տեսակ, որտեղ պահանջվում է սահմանված է true: Ուղեկցող սխալի հաղորդագրությունները կցուցադրվեն, եթե հարցման մարմինը չի պարունակում հատկություններից որևէ մեկը:

Վերջնական տողը ստեղծում և արտահանում է մանգուստ մոդել՝ զանգահարելով model մեթոդը mongoose-ի վրա: Փոխանցեք մոդելի անունը (Blog) որպես առաջին արգումենտ և սխեման (blogSchema), որպես երկրորդ փաստարկ:

Քայլ 4. Ձեր հավելվածում երթուղավորման իրականացում

Առանց Express-ի նման շրջանակների օգնության, դուք պետք է ձեռքով ստեղծեք տրամաբանություն՝ ձեր API-ին արված յուրաքանչյուր հարցումը կարգավորելու համար:

Նախ, ձեր routes պանակում ստեղծեք blogRoutes.js ֆայլ, ապա ներմուծեք բլոգի մոդելը՝

const Blog = require("../models/blogModel");

Հաջորդը, ստեղծեք ասինխրոն երթուղիչ ֆունկցիա, փոխանցեք req և res որպես պարամետրեր և արտահանեք գործառույթը.

const router = async function (req, res) {};
module.exports = router;

Այս գործառույթը կպարունակի ձեր ողջ երթուղային տրամաբանությունը:

Հաջորդը, դուք կիրականացնեք երթուղային տրամաբանական երթուղին առ երթուղի:

GET երթուղիներ

Ներքևում ավելացրեք կոդի բլոկը ձեր երթուղիչի ֆունկցիայի մեջ՝ GET երթուղու մշակիչը /api/blogs-ին արված հարցումների համար:

// GET: /api/blogs
if (req.url === "/api/blogs" && req.method === "GET") {
    // get all blogs
    const blogs = await Blog.find();
 
    // set the status code and content-type
    res.writeHead(200, { "Content-Type": "application/json" });
 
    // send data
    res.end(JSON.stringify(blogs));
}

Վերևի կոդի բլոկը ստուգում է հարցումի օբյեկտի url և մեթոդը հատկությունները: Այնուհետև այն վերցնում է բոլոր բլոգները տվյալների բազայից գտնել մեթոդի միջոցով մանգուստ մոդելի վրա (Բլոգ):

Այնուհետև այն կանչում է writeHead մեթոդը res-ի վրա՝ պատասխան օբյեկտի վրա: Այս մեթոդն ուղարկում է պատասխանի վերնագիր՝ տրված երեք արգումենտների՝ կարգավիճակի կոդ, կամընտիր կարգավիճակի հաղորդագրություն և վերնագրեր: 200 կարգավիճակի կոդը ներկայացնում է հաջող պատասխան, և այս API զանգի բովանդակության տեսակը դրված է application/json:

Վերջապես, փակեք հարցումը, որպեսզի համոզվեք, որ սերվերը չի կախված՝ զանգահարելով վերջ մեթոդը res-ում: Զանգը JSON.stringify-ին փոխակերպում է blogs օբյեկտը JSON տողի և փոխանցելով այն end մեթոդին այն վերադարձնում է որպես պատասխանի մարմին:

Ստորև բերված կոդի բլոկը ավելացրեք ձեր երթուղիչի ֆունկցիային՝ մեկ ռեսուրսի համար GET երթուղու մշակիչն իրականացնելու համար.

// GET: /api/blogs/:id
if (req.url.match(/\\/api\\/blogs\\/([0-9]+)/) && req.method === "GET") {
    try {
        // extract id from url
        const id = req.url.split("/")[3];
 
        // get blog from DB
        const blog = await Blog.findById(id);
 
        if (blog) {
            res.writeHead(200, { "Content-Type": "application/json" });
            res.end(JSON.stringify(blog));
        } else {
            throw new Error("Blog does not exist");
        }
    } catch (error) {
        res.writeHead(404, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ message: error }));
    }
}

Այս կոդը օգտագործում է համապատասխան մեթոդը, որն ընդունում է ռեգեքս արտահայտությունը որպես փաստարկ՝ ստուգելու, թե արդյոք URL-ը համապատասխանում է ձևաչափին՝ /api/blogs/:

Հաջորդը, հանեք id հատկությունը url տողից՝ կանչելով դրա split մեթոդը: Այս մեթոդը օրինաչափությունն ընդունում է որպես արգումենտ (/), բաժանում է տողը օրինաչափության հիման վրա և վերադարձնում զանգված։ Այդ զանգվածի երրորդ տարրը idն է։

Վերջապես, ձեր տվյալների բազայից վերցրեք փաստաթուղթը համապատասխան idով: Եթե այն կա, ուղարկեք պատասխանի կոդը 200, փակեք հարցումը և ուղարկեք վերցված բլոգը: Եթե այն գոյություն չունի, սխալ գցեք և ուղարկեք որպես պատասխան catch բլոկում:

ՓՈՍՏ երթուղի

Ստորև բերված կոդի բլոկը ավելացրեք ձեր երթուղիչի գործառույթին՝ POST երթուղու մշակիչն իրականացնելու համար.

// POST: /api/blogs/
if (req.url === "/api/blogs" && req.method === "POST") {
    try {
        let body = "";
 
        // Listen for data event
        req.on("data", (chunk) => {
            body += chunk.toString();
        });
 
        // Listen for end event
        req.on("end", async () => {
            // Create Blog
            let blog = new Blog(JSON.parse(body));
 
            // Save to DB
            await blog.save();
            res.writeHead(200, { "Content-Type": "application/json" });
            res.end(JSON.stringify(blog));
        });
    } catch (error) {
        console.log(error);
    }
}

Հարցման օբյեկտն իրականացնում է Node.js ReadableStream ինտերֆեյսը: Այս հոսքը թողարկում է տվյալներ և վերջ իրադարձություն, որը հնարավորություն է տալիս մուտք գործել հարցումի մարմնի տվյալները:

Այս կոդը լսում է տվյալների իրադարձությունը և մշակում այն՝ փոխակերպելով այն տողի և միացնելով body փոփոխականին: վերջ իրադարձությունների մշակիչում այն ստեղծում է Բլոգ օրինակ վերլուծված հիմնական տողով: Այնուհետև այն պահպանում է նոր բլոգը, ուղարկում է կարգավիճակի կոդը և բովանդակության վերնագիրը և փակում հարցումը:

PUT Երթուղի

Ստորև բերված կոդի բլոկը ավելացրեք ձեր երթուղիչի գործառույթին՝ PUT երթուղու մշակիչն իրականացնելու համար.

// PUT: /api/blogs/:id
if (req.url.match(/\\/api\\/blogs\\/([0-9]+)/) && req.method === "PUT") {
    try {
        // extract id from url
        const id = req.url.split("/")[3];
        let body = "";
 
        req.on("data", (chunk) => {
            body += chunk.toString();
        });
        req.on("end", async () => {
            // Find and update document
            let updatedBlog = await Blog.findByIdAndUpdate(id, JSON.parse(body), {
                new: true,
            });
 
            res.writeHead(200, { "Content-Type": "application/json" });
            res.end(JSON.stringify(updatedBlog));
        });
    } catch (error) {
        console.log(error);
    }
}

PUT հարցումների մշակիչը գրեթե նույնական է POST հարցումների մշակիչին, բացառությամբ, որ այն հանում է id հատկությունը url-ից՝ համապատասխան բլոգը թարմացնելու համար:

Ջնջել երթուղին

Ստորև բերված կոդի բլոկը ավելացրեք ձեր երթուղիչի գործառույթին՝ ձեր ՋՆՋԵԼ երթուղու մշակիչն իրականացնելու համար:

// DELETE: /api/blogs/:id
if (req.url.match(/\\/api\\/blogs\\/([0-9]+)/) && req.method === "DELETE") {
    try {
        const id = req.url.split("/")[3];
        
       // Delete blog from DB
        await Blog.findByIdAndDelete(id);
        res.writeHead(200, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ message: "Blog deleted successfully" }));
    } catch (error) {
        res.writeHead(404, { "Content-Type": "application/json" });
        res.end(JSON.stringify({ message: error }));
    }
}

Այս կոդի բլոկը հանում է idurl-ից, ջնջում է փաստաթուղթը համապատասխան id-ով, ուղարկում է կարգավիճակի կոդը և վերնագրերը և փակում հարցումը։ .

Ի վերջո, ներմուծեք երթուղիչը ձեր server.js ֆայլում և զանգահարեք ձեր երթուղիչի ֆունկցիան՝ անցնելով req և : resորպես փաստարկներ:

const router = require("./routes/blogRoutes");
 
const server = http.createServer((req, res) => {
    router(req, res);
});

Սա թույլ է տալիս ձեր սերվերին ընդհատել և պատշաճ կերպով մշակել հարցումները:

Ավարտված նախագիծը կարող եք գտնել այս GitHub պահոցում:

Օգտագործելով Node.js Framework

Թեև հնարավոր է ձեռքով ստեղծել վեբ API, դա կարող է բարդ խնդիր լինել: Դուք պետք է համոզվեք, որ դուք ծածկել եք բազմաթիվ եզրային դեպքեր, և ձեր կոդը ավելի լավ է վրիպազերծ լինի:

Տարիների ընթացքում մշակողները ստեղծել են այնպիսի շրջանակներ, ինչպիսիք են ExpressJS-ը, NestJS-ը, Fastify-ը և այլն, որպեսզի դա շատ ավելի հեշտ դարձնեն: