मैंने हाल ही में डेनो + ओक (डेटाबेस का उपयोग किए बिना) में टोडो एपीआई बनाने के तरीके के बारे में लिखा था . आप रेपो को अध्याय_1:ओक . के अंतर्गत पा सकते हैं गिटहब पर।
यह ट्यूटोरियल वहीं से शुरू होता है जहां दूसरे ने छोड़ा था, और मैं इस बात पर चर्चा करूंगा कि MySQL को डेनो और ओक प्रोजेक्ट में कैसे एकीकृत किया जाए।
यदि आप किसी भी समय इस ट्यूटोरियल में उपयोग किए गए संपूर्ण स्रोत कोड को देखना चाहते हैं, तो यह अध्याय_2:mysql पर उपलब्ध है। . अगर आप इसे पसंद करते हैं तो इसे गिटहब पर एक स्टार देने के लिए स्वतंत्र महसूस करें।
मुझे लगता है कि आपने ऊपर वर्णित अंतिम ट्यूटोरियल पहले ही पूरा कर लिया है। यदि नहीं, तो इसे यहां देखें और समाप्त होने पर वापस आएं।
शुरू करने से पहले, सुनिश्चित करें कि आपके पास एक MySQL क्लाइंट स्थापित और चल रहा है:
- MySQL समुदाय सर्वर [यहां डाउनलोड करें]
- MySQL कार्यक्षेत्र [यहां डाउनलोड करें]
मैंने मैक ओएस उपयोगकर्ताओं के लिए MySQL की स्थापना पर एक छोटी सी मार्गदर्शिका लिखी क्योंकि मैं इसके साथ भी संघर्ष कर रहा था। इसे यहां देखें।
यदि आप एक विंडोज़ मशीन पर हैं तो आप उन्हीं उपकरणों का उपयोग कर सकते हैं या आप अपने डैशबोर्ड में एक MySQL इंस्टेंस चलाने के लिए XAMPP का भी उपयोग कर सकते हैं।
एक बार जब आपके पास एक MySQL इंस्टेंस चल रहा हो तो हम अपना ट्यूटोरियल शुरू कर सकते हैं।
आइए शुरू करें
यह मानते हुए कि आप इस लेख से आ रहे हैं, Deno + Oak में Todo API (डेटाबेस का उपयोग किए बिना) , हम निम्नलिखित कार्य करेंगे:
- एक MySQL डेटाबेस कनेक्शन बनाएं
- एक छोटी सी स्क्रिप्ट लिखें जो हर बार जब हम अपना डेनो सर्वर शुरू करते हैं तो डेटाबेस को रीसेट करता है
- एक टेबल पर CRUD संचालन करें
- सीआरयूडी कार्यक्षमता को हमारे एपीआई नियंत्रकों में जोड़ें
एक आखिरी बात - यहाँ संपूर्ण प्रतिबद्ध अंतर है जो कि अध्याय 1 में MySQL को परियोजना में जोड़ने के लिए किया गया था (स्रोत कोड जो अध्याय 1 से किए गए नए परिवर्धन को दर्शाता है)।
आपके प्रोजेक्ट रूट फोल्डर में - मेरा नाम है chapter_2:mysql
, हालांकि आप जो चाहें कॉल कर सकते हैं - db . नामक एक फ़ोल्डर बनाएं . उस फोल्डर के अंदर config.ts और . नाम की एक फाइल बनाएं इसमें निम्नलिखित सामग्री जोड़ें:
export const DATABASE: string = "deno";
export const TABLE = {
TODO: "todo",
};
यहां कुछ भी फैंसी नहीं है, बस हमारे डेटाबेस नाम को टेबल के लिए ऑब्जेक्ट के साथ परिभाषित करना और फिर इसे निर्यात करना। हमारे प्रोजेक्ट में "डेनो" नामक एक डेटाबेस होगा और उस डीबी के अंदर हमारे पास केवल "टूडो" नामक एक टेबल होगी।
इसके बाद, db . के अंदर फ़ोल्डर, client.ts . नामक एक अन्य फ़ाइल बनाएं और निम्नलिखित सामग्री जोड़ें:
import { Client } from "https://deno.land/x/mysql/mod.ts";
// config
import { DATABASE, TABLE } from "./config.ts";
const client = await new Client();
client.connect({
hostname: "127.0.0.1",
username: "root",
password: "",
db: "",
});
export default client;
यहां एक दो चीजें हो रही हैं।
हम आयात कर रहे हैं Client
mysql
. से पुस्तकालय। Client
हमें अपने डेटाबेस से जुड़ने और डेटाबेस में संचालन करने में मदद करेगा।
client.connect({
hostname: "127.0.0.1",
username: "root",
password: "",
db: "",
});
Client
connect
. नामक एक विधि प्रदान करता है जो ऑब्जेक्ट लेता है जहां हम hostname
. प्रदान कर सकते हैं , username
, password
, और db
. इस जानकारी के साथ यह हमारे MySQL इंस्टेंस से कनेक्शन स्थापित कर सकता है।
सुनिश्चित करें कि आपका username
कोई password
नहीं है , क्योंकि यह डेनो की MySQL लाइब्रेरी से कनेक्ट होने में विरोध करेगा। यदि आप नहीं जानते कि यह कैसे करना है, तो मेरे द्वारा लिखे गए इस ट्यूटोरियल को पढ़ें।
मैंने database
छोड़ दिया है यहां फ़ील्ड खाली है क्योंकि मैं इसे बाद में अपनी स्क्रिप्ट में मैन्युअल रूप से चुनना चाहता हूं।
आइए एक स्क्रिप्ट जोड़ें जो "डेनो" नामक एक डेटाबेस को इनिशियलाइज़ करेगी, इसे चुनें, और उस डीबी के अंदर "टूडो" नामक एक टेबल बनाएं।
db/client.ts
. के अंदर फ़ाइल कुछ नए जोड़ दें:
import { Client } from "https://deno.land/x/mysql/mod.ts";
// config
import { DATABASE, TABLE } from "./config.ts";
const client = await new Client();
client.connect({
hostname: "127.0.0.1",
username: "root",
password: "",
db: "",
});
const run = async () => {
// create database (if not created before)
await client.execute(`CREATE DATABASE IF NOT EXISTS ${DATABASE}`);
// select db
await client.execute(`USE ${DATABASE}`);
// delete table if it exists before
await client.execute(`DROP TABLE IF EXISTS ${TABLE.TODO}`);
// create table
await client.execute(`
CREATE TABLE ${TABLE.TODO} (
id int(11) NOT NULL AUTO_INCREMENT,
todo varchar(100) NOT NULL,
isCompleted boolean NOT NULL default false,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`);
};
run();
export default client;
यहां हम आयात कर रहे हैं DATABASE
और TABLE
हमारी कॉन्फ़िगरेशन फ़ाइल से, फिर उन मानों का उपयोग run()
. नामक एक नए फ़ंक्शन में करें ।
आइए इस run()
को तोड़ें समारोह। वर्कफ़्लो को समझने में आपकी मदद करने के लिए मैंने फ़ाइल में टिप्पणियाँ जोड़ी हैं:
const run = async () => {
// create database (if not created before)
await client.execute(`CREATE DATABASE IF NOT EXISTS ${DATABASE}`);
// select db
await client.execute(`USE ${DATABASE}`);
// delete table if it exists before
await client.execute(`DROP TABLE IF EXISTS ${TABLE.TODO}`);
// create table
await client.execute(`
CREATE TABLE ${TABLE.TODO} (
id int(11) NOT NULL AUTO_INCREMENT,
todo varchar(100) NOT NULL,
isCompleted boolean NOT NULL default false,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`);
};
run();
deno
नामक एक डेटाबेस बनाएं . अगर यह पहले से मौजूद है तो कुछ न करें।- फिर उपयोग करने के लिए डेटाबेस का चयन करें, जिसे
deno
. कहा जाता है - तालिका को
deno
के अंदर हटाएंtodo
. कहा जाता है अगर यह पहले से मौजूद है। - अगला,
deno
. के अंदर एक नई तालिका बनाएं db, इसेtodo
call कहते हैं , और इसकी संरचना को परिभाषित करें:इसमें एक अद्वितीय ऑटो इंक्रीमेंट होगाid
जो एक पूर्णांक होगा, एक अन्य फ़ील्ड जिसेtodo
. कहा जाता है जो एक स्ट्रिंग होगी, और अंत मेंisCompleted
. नामक एक फ़ील्ड होगी जो एक बूलियन है। मैंid
. भी परिभाषित करता हूं मेरी प्राथमिक कुंजी के रूप में।
इस स्क्रिप्ट को लिखने का कारण यह था कि मैं MySQL इंस्टेंस में अतिरिक्त जानकारी नहीं चाहता। हर बार जब स्क्रिप्ट चलती है तो वह सब कुछ फिर से शुरू कर देती है।
आपको यह स्क्रिप्ट जोड़ने की आवश्यकता नहीं है। लेकिन अगर आप नहीं करते हैं, तो आपको मैन्युअल रूप से एक डीबी और टेबल बनाना होगा।
इसके अलावा, डीबी निर्माण और टेबल निर्माण पर डेनो माईएसक्यूएल लाइब्रेरी के दस्तावेज़ देखें।
अपने एजेंडे पर वापस जाते हुए, हमने लेख के शीर्ष पर उल्लिखित चार में से सिर्फ दो चीजें हासिल की हैं:
- एक MySQL डेटाबेस कनेक्शन बनाएं
- एक छोटी सी स्क्रिप्ट लिखें जो हर बार जब हम अपना डेनो सर्वर शुरू करते हैं तो डेटाबेस को रीसेट करता है
यह पहले से ही ट्यूटोरियल का 50% है। दुर्भाग्य से, हम अभी बहुत कुछ होते हुए नहीं देख सकते हैं। आइए इसे काम करते हुए देखने के लिए जल्दी से कुछ कार्यक्षमता जोड़ें।
एक टेबल पर CRUD संचालन करना और हमारे API नियंत्रकों में कार्यक्षमता जोड़ना h2>
हमें पहले अपने Todo इंटरफ़ेस को अपडेट करना होगा। interfaces/Todo.ts
पर जाएं फ़ाइल करें और निम्नलिखित जोड़ें:
export default interface Todo {
id?: number,
todo?: string,
isCompleted?: boolean,
}
यह क्या है ?
क्या यह वस्तु में कुंजी को वैकल्पिक बनाता है। मैंने ऐसा इसलिए किया क्योंकि बाद में मैं केवल id
. के साथ वस्तुओं को पास करने के लिए विभिन्न कार्यों का उपयोग करूंगा , todo
, isCompleted
, या उन सभी को एक साथ।
यदि आप टाइपस्क्रिप्ट में वैकल्पिक गुणों के बारे में अधिक जानना चाहते हैं, तो यहां उनके दस्तावेज़ देखें।
इसके बाद, मॉडल . नामक एक नया फ़ोल्डर बनाएं और उस फोल्डर के अंदर todo.ts . नाम की एक फाइल बनाएं . फ़ाइल में निम्न सामग्री जोड़ें:
import client from "../db/client.ts";
// config
import { TABLE } from "../db/config.ts";
// Interface
import Todo from "../interfaces/Todo.ts";
export default {
/**
* Takes in the id params & checks if the todo item exists
* in the database
* @param id
* @returns boolean to tell if an entry of todo exits in table
*/
doesExistById: async ({ id }: Todo) => {},
/**
* Will return all the entries in the todo column
* @returns array of todos
*/
getAll: async () => {},
/**
* Takes in the id params & returns the todo item found
* against it.
* @param id
* @returns object of todo item
*/
getById: async ({ id }: Todo) => {},
/**
* Adds a new todo item to todo table
* @param todo
* @param isCompleted
*/
add: async (
{ todo, isCompleted }: Todo,
) => {},
/**
* Updates the content of a single todo item
* @param id
* @param todo
* @param isCompleted
* @returns integer (count of effect rows)
*/
updateById: async ({ id, todo, isCompleted }: Todo) => {},
/**
* Deletes a todo by ID
* @param id
* @returns integer (count of effect rows)
*/
deleteById: async ({ id }: Todo) => {},
};
अभी कार्य खाली हैं, लेकिन यह ठीक है। हम उन्हें एक-एक करके भर देंगे।
इसके बाद controllers/todo.ts
. पर जाएं फ़ाइल और सुनिश्चित करें कि आप निम्नलिखित जोड़ते हैं:
// interfaces
import Todo from "../interfaces/Todo.ts";
// models
import TodoModel from "../models/todo.ts";
export default {
/**
* @description Get all todos
* @route GET /todos
*/
getAllTodos: async ({ response }: { response: any }) => {},
/**
* @description Add a new todo
* @route POST /todos
*/
createTodo: async (
{ request, response }: { request: any; response: any },
) => {},
/**
* @description Get todo by id
* @route GET todos/:id
*/
getTodoById: async (
{ params, response }: { params: { id: string }; response: any },
) => {},
/**
* @description Update todo by id
* @route PUT todos/:id
*/
updateTodoById: async (
{ params, request, response }: {
params: { id: string };
request: any;
response: any;
},
) => {},
/**
* @description Delete todo by id
* @route DELETE todos/:id
*/
deleteTodoById: async (
{ params, response }: { params: { id: string }; response: any },
) => {},
};
यहां हमारे पास खाली कार्य भी हैं। आइए उन्हें भरना शुरू करें।
[प्राप्त करें] सभी todos API
models/todo.ts
. के अंदर , getAll
. नामक फ़ंक्शन के लिए एक परिभाषा जोड़ें :
import client from "../db/client.ts";
// config
import { TABLE } from "../db/config.ts";
// Interface
import Todo from "../interfaces/Todo.ts";
export default {
/**
* Will return all the entries in the todo column
* @returns array of todos
*/
getAll: async () => {
return await client.query(`SELECT * FROM ${TABLE.TODO}`);
},
}
Client
connect
. के अलावा एक अन्य विधि को भी उजागर करता है (हमने db/client.ts
. में "कनेक्ट" विधि का उपयोग किया है फ़ाइल) और वह है query
. client.query
विधि हमें MySQL क्वेरीज़ को सीधे हमारे डेनो कोड से चलाने देती है।
इसके बाद controllers/todo.ts
. पर जाएं getAllTodos
. के लिए परिभाषा जोड़ें :
// interfaces
import Todo from "../interfaces/Todo.ts";
// models
import TodoModel from "../models/todo.ts";
export default {
/**
* @description Get all todos
* @route GET /todos
*/
getAllTodos: async ({ response }: { response: any }) => {
try {
const data = await TodoModel.getAll();
response.status = 200;
response.body = {
success: true,
data,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
}
हम केवल TodoModel
आयात कर रहे हैं और इसकी विधि का उपयोग करके getAll
. कहा जाता है , जिसे हमने अभी परिभाषित किया है। चूंकि यह एक वादे के रूप में वापस आता है, इसलिए हमने इसे एसिंक/प्रतीक्षा में लपेट लिया है।
विधि TodoModel.getAll()
हमें एक सरणी लौटाएगा जिसे हम केवल response.body
. पर वापस कर देंगे status
. के साथ 200
. पर सेट करें ।
यदि वादा विफल हो जाता है या कोई अन्य त्रुटि होती है, तो हम बस अपने कैच ब्लॉक में जाते हैं और success
के साथ 400 की स्थिति लौटाते हैं असत्य पर सेट। हम message
. भी सेट करते हैं कैच ब्लॉक से हमें क्या मिलता है।
बस इतना ही, हम कर चुके हैं। अब हमारे टर्मिनल में आग लगाते हैं।
सुनिश्चित करें कि आपका MySQL इंस्टेंस चल रहा है। आपके टर्मिनल प्रकार में:
$ deno run --allow-net server.ts
आपका टर्मिनल कुछ इस तरह दिखना चाहिए:
मेरा कंसोल मुझे यहां दो बातें बता रहा है।
- कि मेरा डेनो एपीआई सर्वर पोर्ट 8080 पर चल रहा है
- कि मेरा MySQL इंस्टेंस
127.0.0.1
पर चल रहा है , जोlocalhost
. है
आइए हमारे एपीआई का परीक्षण करें। मैं यहां पोस्टमैन का उपयोग कर रहा हूं, लेकिन आप अपने पसंदीदा एपीआई क्लाइंट का उपयोग कर सकते हैं।
अभी यह केवल खाली डेटा देता है। लेकिन एक बार जब हम अपने todo
. में डेटा जोड़ते हैं तालिका, यह उन टूडो को यहाँ लौटा देगा।
विस्मयकारी। एक एपीआई नीचे और चार और जाने के लिए।
[पोस्ट] एक टूडू API जोड़ें
models/todo.ts
. में फ़ाइल में, add()
के लिए निम्न परिभाषा जोड़ें समारोह:
export default {
/**
* Adds a new todo item to todo table
* @param todo
* @param isCompleted
*/
add: async (
{ todo, isCompleted }: Todo,
) => {
return await client.query(
`INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)`,
[
todo,
isCompleted,
],
);
},
}
ऐड फ़ंक्शन ऑब्जेक्ट को एक तर्क के रूप में लेता है, जिसमें दो आइटम होते हैं:todo
और isCompleted
।
तो add: async ({ todo, isCompleted }: Todo) => {}
({todo, isCompleted}: {todo:string, isCompleted:boolean})
के रूप में भी लिखा जा सकता है . लेकिन चूंकि हमारे पास पहले से ही हमारे interfaces/Todo.ts
. में परिभाषित एक इंटरफ़ेस है फ़ाइल जो है
export default interface Todo {
id?: number,
todo?: string,
isCompleted?: boolean,
}
हम इसे बस add: async ({ todo, isCompleted }: Todo) => {}
. यह टाइपस्क्रिप्ट को बताता है कि इस फ़ंक्शन के दो तर्क हैं, todo
, जो एक स्ट्रिंग है, और isCompleted
, जो एक बूलियन है।
यदि आप इंटरफेस के बारे में और अधिक पढ़ना चाहते हैं, तो टाइपस्क्रिप्ट के पास इस पर एक उत्कृष्ट दस्तावेज़ है जिसे आप यहां पा सकते हैं।
हमारे फ़ंक्शन के अंदर हमारे पास निम्नलिखित हैं:
return await client.query(
`INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)`,
[
todo,
isCompleted,
],
);
इस क्वेरी को दो भागों में विभाजित किया जा सकता है:
INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)
. यहां दो प्रश्न चिह्न इस क्वेरी के अंदर चर के उपयोग को दर्शाते हैं।- दूसरा भाग,
[todo, isCompleted]
, वेरिएबल हैं जो पहले भाग . में जाएंगे क्वेरी का और(?, ?)
. से बदला जाए Table.Todo
फ़ाइलdb/config.ts
. से केवल एक स्ट्रिंग आ रही है जहांTable.Todo
मान है "todo
"
अगला हमारे controllers/todo.ts
. के अंदर फ़ाइल, createTodo()
की परिभाषा पर जाएं समारोह:
export default {
/**
* @description Add a new todo
* @route POST /todos
*/
createTodo: async (
{ request, response }: { request: any; response: any },
) => {
const body = await request.body();
if (!request.hasBody) {
response.status = 400;
response.body = {
success: false,
message: "No data provided",
};
return;
}
try {
await TodoModel.add(
{ todo: body.value.todo, isCompleted: false },
);
response.body = {
success: true,
message: "The record was added successfully",
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
}
आइए इसे दो भागों में विभाजित करें:
भाग 1
const body = await request.body();
if (!request.hasBody) {
response.status = 400;
response.body = {
success: false,
message: "No data provided",
};
return;
}
हम यहां केवल यह जांच रहे हैं कि उपयोगकर्ता शरीर में डेटा भेज रहा है या नहीं। यदि नहीं, तो हम एक स्थिति 400
return लौटाते हैं और शरीर में वापसी success: false
और message: <erromessage-string>
।
भाग 2
try {
await TodoModel.add(
{ todo: body.value.todo, isCompleted: false },
);
response.body = {
success: true,
message: "The record was added successfully",
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
यदि कोई त्रुटि नहीं है, तो TodoModel.add()
फ़ंक्शन को कॉल किया जाता है और बस 200
. की स्थिति देता है और उपयोगकर्ता को एक पुष्टिकरण संदेश।
अन्यथा यह वही त्रुटि देता है जो हमने पिछले API में किया था।
अब हम कर चुके हैं। अपने टर्मिनल को फायर करें और सुनिश्चित करें कि आपका MySQL इंस्टेंस चल रहा है। आपके टर्मिनल प्रकार में:
$ deno run --allow-net server.ts
पोस्टमैन पर जाएं और इस कंट्रोलर के लिए एपीआई रूट चलाएं:
यह बहुत अच्छा है, अब हमारे पास दो काम करने वाले एपीआई हैं। केवल तीन और जाने के लिए।
[GET] todo by id API
आपके models/todo.ts
. में फ़ाइल, इन दो कार्यों के लिए परिभाषा जोड़ें, doesExistById()
और getById()
:
export default {
/**
* Takes in the id params & checks if the todo item exists
* in the database
* @param id
* @returns boolean to tell if an entry of todo exits in table
*/
doesExistById: async ({ id }: Todo) => {
const [result] = await client.query(
`SELECT COUNT(*) count FROM ${TABLE.TODO} WHERE id = ? LIMIT 1`,
[id],
);
return result.count > 0;
},
/**
* Takes in the id params & returns the todo item found
* against it.
* @param id
* @returns object of todo item
*/
getById: async ({ id }: Todo) => {
return await client.query(
`SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
[id],
);
},
}
आइए प्रत्येक कार्य के बारे में एक-एक करके बात करें:
doesExistById
एकid
लेता है और एकboolean
देता है यह दर्शाता है कि कोई विशेष टूडू डेटाबेस में मौजूद है या नहीं।
आइए इस फ़ंक्शन को तोड़ दें:
const [result] = await client.query(
`SELECT COUNT(*) count FROM ${TABLE.TODO} WHERE id = ? LIMIT 1`,
[id],
);
return result.count > 0;
हम केवल एक विशेष टूडू आईडी के खिलाफ तालिका में यहां गिनती की जांच करते हैं। यदि गिनती शून्य से अधिक है, तो हम true
return लौटाते हैं . अन्यथा, हम false
लौटाते हैं ।
getById
किसी विशेष आईडी के विरुद्ध टूडू आइटम लौटाता है:
return await client.query(
`SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
[id],
);
आईडी द्वारा टूडू प्राप्त करने के लिए और जैसा है वैसा ही परिणाम लौटाने के लिए हम यहां एक MySQL क्वेरी चला रहे हैं।
इसके बाद, अपने controllers/todo.ts
. पर जाएं फ़ाइल और getTodoById
. के लिए एक परिभाषा जोड़ें नियंत्रक विधि:
export default {
/**
* @description Get todo by id
* @route GET todos/:id
*/
getTodoById: async (
{ params, response }: { params: { id: string }; response: any },
) => {
try {
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
const todo = await TodoModel.getById({ id: Number(params.id) });
response.status = 200;
response.body = {
success: true,
data: todo,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
}
आइए इसे दो छोटे भागों में विभाजित करें:
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
पहले हम जाँचते हैं कि क्या इस विधि का उपयोग करके किसी आईडी के विरुद्ध डेटाबेस में टूडू मौजूद है:
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
यहां हमें params.id
convert कन्वर्ट करने की जरूरत है एक Number
. में क्योंकि हमारा टूडू इंटरफ़ेस केवल id
. स्वीकार करता है एक संख्या के रूप में। इसके बाद, हम बस params.id
. पास करते हैं करने के लिए doesExistById
तरीका। यह विधि एक बूलियन के रूप में वापस आ जाएगी।
फिर हम बस जांचते हैं कि क्या टूडू उपलब्ध नहीं है और एक 404
. लौटाते हैं पिछले समापन बिंदुओं की तरह हमारे मानक प्रतिक्रिया के साथ विधि:
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
तब हमारे पास है:
try {
const todo: Todo = await TodoModel.getById({ id: Number(params.id) });
response.status = 200;
response.body = {
success: true,
data: todo,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
यह वैसा ही है जैसा हम अपने पिछले एपीआई में कर रहे थे। यहाँ हम केवल db से डेटा प्राप्त कर रहे हैं, वेरिएबल todo
. सेट कर रहे हैं , और फिर प्रतिक्रिया लौटा रहा है। यदि कोई त्रुटि है तो हम उपयोगकर्ता को वापस कैच ब्लॉक में एक मानक त्रुटि संदेश वापस कर देते हैं।
अब अपने टर्मिनल को फायर करें और सुनिश्चित करें कि आपका MySQL इंस्टेंस चल रहा है। आपके टर्मिनल प्रकार में:
$ deno run --allow-net server.ts
पोस्टमैन पर जाएँ और इस नियंत्रक के लिए एपीआई रूट चलाएँ।
याद रखें कि हर बार जब हम अपने सर्वर को पुनरारंभ करते हैं तो हम डीबी रीसेट करते हैं। यदि आप यह व्यवहार नहीं चाहते हैं, तो आप केवल run
. पर टिप्पणी कर सकते हैं फ़ाइल में कार्य करें db/client.ts
।
अब तक हमने इनके लिए एपीआई किया है:
- सभी कार्य प्राप्त करें
- नया कार्य बनाएं
- आईडी द्वारा कार्य प्राप्त करें
और यहाँ शेष API हैं:
- आईडी द्वारा एक टूडू अपडेट करें
- आईडी द्वारा एक टूडू हटाएं
[PUT] आईडी API द्वारा टूडू अपडेट करें
आइए पहले इस एपीआई के लिए एक मॉडल बनाएं। हमारे models/todo.ts
में जाएं फ़ाइल और updateById
. के लिए एक परिभाषा जोड़ें समारोह:
**
* Updates the content of a single todo item
* @param id
* @param todo
* @param isCompleted
* @returns integer (count of effect rows)
*/
updateById: async ({ id, todo, isCompleted }: Todo) => {
const result = await client.query(
`UPDATE ${TABLE.TODO} SET todo=?, isCompleted=? WHERE id=?`,
[
todo,
isCompleted,
id,
],
);
// return count of rows updated
return result.affectedRows;
},
updateById
3 पैरा लेता है:id
, todo
, और isCompleted
।
हम इस फ़ंक्शन के अंदर बस एक MySQL क्वेरी चलाते हैं:
onst result = await client.query(
`UPDATE ${TABLE.TODO} SET todo=?, isCompleted=? WHERE id=?`,
[
todo,
isCompleted,
id,
],
);
यह एकल टूडू आइटम के todo
. को अपडेट करता है और isCompleted
एक विशिष्ट id
. द्वारा ।
इसके बाद हम इस क्वेरी द्वारा अपडेट की गई पंक्तियों की संख्या लौटाते हैं:
// return count of rows updated
return result.affectedRows;
गिनती या तो 0 या 1 होगी, लेकिन 1 से अधिक कभी नहीं होगी। ऐसा इसलिए है क्योंकि हमारे डेटाबेस में हमारे पास अद्वितीय आईडी हैं - एक ही आईडी के साथ कई टोडो मौजूद नहीं हो सकते हैं।
इसके बाद हमारे controllers/todo.ts
. पर जाएं फ़ाइल और updateTodoById
. के लिए एक परिभाषा जोड़ें समारोह:
updateTodoById: async (
{ params, request, response }: {
params: { id: string };
request: any;
response: any;
},
) => {
try {
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
// if todo found then update todo
const body = await request.body();
const updatedRows = await TodoModel.updateById({
id: Number(params.id),
...body.value,
});
response.status = 200;
response.body = {
success: true,
message: `Successfully updated ${updatedRows} row(s)`,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
यह लगभग हमारे पिछले एपीआई के समान ही है जिसे हमने लिखा था। जो हिस्सा यहाँ नया है वह यह है:
// if todo found then update todo
const body = await request.body();
const updatedRows = await TodoModel.updateById({
id: Number(params.id),
...body.value,
});
हम सरल शरीर प्राप्त करते हैं जो उपयोगकर्ता हमें JSON में भेजता है और शरीर को हमारे TodoModel.updateById
पर भेजता है समारोह।
हमें id
. को कन्वर्ट करना है हमारे Todo इंटरफ़ेस का अनुपालन करने के लिए एक नंबर पर।
क्वेरी निष्पादित की जाती है और अद्यतन पंक्तियों की संख्या लौटाती है। वहां से हम इसे केवल अपनी प्रतिक्रिया में वापस कर देते हैं। अगर कोई त्रुटि होती है तो यह कैच ब्लॉक में जाती है जहां हम अपना मानक प्रतिक्रिया संदेश लौटाते हैं।
आइए इसे चलाएं और देखें कि क्या यह काम करता है। सुनिश्चित करें कि आपका MySQL इंस्टेंस चल रहा है और अपने टर्मिनल से निम्नलिखित चलाएँ:
$ deno run --allow-net server.ts
पोस्टमैन पर जाएं और इस कंट्रोलर के लिए एपीआई रूट चलाएं:
[DELETE] todo by id API
आपके models/todo.ts
. में फ़ाइल deleteById
called नामक एक फ़ंक्शन बनाएं :
/**
* Deletes a todo by ID
* @param id
* @returns integer (count of effect rows)
*/
deleteById: async ({ id }: Todo) => {
const result = await client.query(
`DELETE FROM ${TABLE.TODO} WHERE id = ?`,
[id],
);
// return count of rows updated
return result.affectedRows;
},
यहाँ हम बस एक id
पास करते हैं एक परम के रूप में और फिर हटाएं MySQL क्वेरी का उपयोग करें। फिर हम पंक्तियों की अद्यतन संख्या लौटाते हैं। अपडेट की गई गणना या तो 0 या 1 होगी क्योंकि प्रत्येक टूडू की आईडी अद्वितीय होती है।
इसके बाद, अपने controllers/todo.ts
. में जाएं फ़ाइल और परिभाषित एक deleteByTodoId
विधि:
/**
* @description Delete todo by id
* @route DELETE todos/:id
*/
deleteTodoById: async (
{ params, response }: { params: { id: string }; response: any },
) => {
try {
const updatedRows = await TodoModel.deleteById({
id: Number(params.id),
});
response.status = 200;
response.body = {
success: true,
message: `Successfully updated ${updatedRows} row(s)`,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
यह काफी सीधा है। हम params.id
. पास करते हैं हमारे TodoModel.deleteById
. पर विधि और इस क्वेरी के साथ अपडेट की गई पंक्तियों की संख्या लौटाएं।
यदि कुछ भी गलत होता है तो कैच ब्लॉक में एक त्रुटि डाली जाती है जो हमारी मानक त्रुटि प्रतिक्रिया देता है।
आइए इसे देखें।
सुनिश्चित करें कि आपका MySQL इंस्टेंस चल रहा है। आपके टर्मिनल प्रकार में:
$ deno run --allow-net server.ts
पोस्टमैन पर जाएं और इस कंट्रोलर के लिए एपीआई रूट चलाएं:
इसके साथ हम अपने डेनो + ओक + मायएसक्यूएल ट्यूटोरियल के साथ कर रहे हैं।
संपूर्ण स्रोत कोड यहां उपलब्ध है:https://github.com/adeelibr/deno-playground। अगर आपको कोई समस्या मिलती है, तो बस मुझे बताएं। या एक पुल अनुरोध करने के लिए स्वतंत्र महसूस करें और मैं आपको रिपोजिटरी में क्रेडिट दूंगा।
अगर आपको यह ट्यूटोरियल मददगार लगा हो तो कृपया इसे शेयर करें। और हमेशा की तरह, मैं ट्विटर पर @adeelibr के तहत उपलब्ध हूं। मुझे इस पर आपके विचार जानना अच्छा लगेगा।