Niedawno pisałem o tym, jak zrobić API Todo w Deno + Oak (bez użycia bazy danych) . Repozytorium można znaleźć w rozdziale_1:dąb na GitHubie.
W tym samouczku wracamy do miejsca, w którym poprzednie zostały przerwane, a ja omówię, jak zintegrować MySQL z projektem Deno i Oak.
Jeśli w dowolnym momencie zechcesz zobaczyć cały kod źródłowy użyty w tym samouczku, jest on dostępny pod adresem chapter_2:mysql . Jeśli Ci się spodoba, możesz przyznać mu gwiazdkę na GitHub.
Zakładam, że ukończyłeś już ostatni wspomniany wyżej samouczek. Jeśli nie, sprawdź to tutaj i wróć, gdy skończysz.
Zanim zaczniemy, upewnij się, że masz zainstalowanego i uruchomionego klienta MySQL:
- Serwer społeczności MySQL [Pobierz tutaj]
- MySQL Workbench [Pobierz tutaj]
Napisałem mały przewodnik dla użytkowników Mac OS na temat konfigurowania MySQL, ponieważ również miałem z nim problemy. Sprawdź to tutaj.
Jeśli korzystasz z komputera z systemem Windows, możesz użyć tych samych narzędzi lub możesz również użyć XAMPP, aby uruchomić instancję MySQL na swoim pulpicie nawigacyjnym.
Po uruchomieniu instancji MySQL możemy rozpocząć nasz samouczek.
Zacznijmy
Zakładając, że pochodzisz z tego artykułu, Todo API w Deno + Oak (bez użycia bazy danych) , zrobimy co następuje:
- Utwórz połączenie z bazą danych MySQL
- Napisz mały skrypt, który resetuje bazę danych za każdym razem, gdy uruchamiamy nasz serwer Deno
- Wykonywanie operacji CRUD na stole
- Dodaj funkcjonalność CRUD do naszych kontrolerów API
Ostatnia rzecz – tutaj jest cała różnica w zatwierdzaniu, która została dokonana w Rozdziale 1, aby dodać MySQL do projektu (kod źródłowy, który pokazuje nowe dodatki wykonane z rozdziału 1).
W folderze głównym twojego projektu – mój nazywa się chapter_2:mysql
, chociaż Twój może być nazwany, jak chcesz – utwórz folder o nazwie db . Wewnątrz tego folderu utwórz plik o nazwie config.ts i dodaj do niego następującą treść:
export const DATABASE: string = "deno";
export const TABLE = {
TODO: "todo",
};
Nic nadzwyczajnego, wystarczy zdefiniować nazwę naszej bazy danych wraz z obiektem dla tabel, a następnie go wyeksportować. Nasz projekt będzie miał jedną bazę danych o nazwie „deno”, a wewnątrz tej bazy danych będziemy mieć tylko jedną tabelę o nazwie „todo”.
Następnie w bazie folderu, utwórz inny plik o nazwie client.ts i dodaj następującą treść:
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;
Dzieje się tutaj kilka rzeczy.
Importujemy Client
z mysql
biblioteka. Client
pomoże nam połączyć się z naszą bazą danych i wykonać operacje w bazie danych.
client.connect({
hostname: "127.0.0.1",
username: "root",
password: "",
db: "",
});
Client
udostępnia metodę o nazwie connect
który przyjmuje obiekt, w którym możemy podać hostname
, username
, password
i db
. Dzięki tym informacjom może nawiązać połączenie z naszą instancją MySQL.
Upewnij się, że Twoja username
nie ma password
, ponieważ będzie to powodować konflikt z połączeniem z biblioteką MySQL firmy Deno. Jeśli nie wiesz, jak to zrobić, przeczytaj ten samouczek, który napisałem.
Opuściłem database
pole puste tutaj, ponieważ chcę je później wybrać ręcznie w moim skrypcie.
Dodajmy skrypt, który zainicjuje bazę danych o nazwie „deno”, wybierz ją i wewnątrz tej bazy utwórzmy tabelę o nazwie „todo”.
Wewnątrz db/client.ts
plik zróbmy kilka nowych dodatków:
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;
Tutaj importujemy DATABASE
i TABLE
z naszego pliku konfiguracyjnego, a następnie używając tych wartości w nowej funkcji o nazwie run()
.
Podzielmy to run()
funkcjonować. Dodałem komentarze w pliku, aby pomóc Ci zrozumieć przepływ pracy:
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();
- Utwórz bazę danych o nazwie
deno
. Jeśli już istnieje, nie rób nic. - Następnie wybierz bazę danych do użycia, która nazywa się
deno
- Usuń tabelę wewnątrz
deno
o nazwietodo
jeśli już istnieje. - Następnie utwórz nową tabelę w
deno
db, nazwij totodo
i zdefiniuj jego strukturę:będzie miał unikalny automatyczny przyrostid
która będzie liczbą całkowitą, innym polem o nazwietodo
który będzie ciągiem, a na końcu polem o nazwieisCompleted
co jest wartością logiczną. Definiuję równieżid
jako mój klucz podstawowy.
Powodem, dla którego napisałem ten skrypt, było to, że nie chcę mieć dodatkowych informacji w instancji MySQL. Za każdym razem, gdy skrypt jest uruchamiany, po prostu ponownie inicjuje wszystko.
Nie musisz dodawać tego skryptu. Ale jeśli tego nie zrobisz, będziesz musiał ręcznie utworzyć bazę danych i tabelę.
Zapoznaj się również z dokumentacją biblioteki Deno MySQL dotyczącą tworzenia baz danych i tworzenia tabel.
Wracając do naszego programu, właśnie osiągnęliśmy dwie rzeczy z czterech wymienionych na początku artykułu:
- Utwórz połączenie z bazą danych MySQL
- Napisz mały skrypt, który resetuje bazę danych za każdym razem, gdy uruchamiamy nasz serwer Deno
To już 50% samouczka. Niestety w tej chwili niewiele się dzieje. Dodajmy szybko kilka funkcji, aby zobaczyć, jak działa.
Wykonywanie operacji CRUD na tabeli i dodawanie funkcjonalności do naszych kontrolerów API
Najpierw musimy zaktualizować nasz interfejs Todo. Przejdź do interfaces/Todo.ts
plik i dodaj następujące:
export default interface Todo {
id?: number,
todo?: string,
isCompleted?: boolean,
}
Co to jest ?
robi to sprawia, że klucz w obiekcie jest opcjonalny. Zrobiłem to, ponieważ później użyję różnych funkcji do przekazywania obiektów tylko z id
, todo
, isCompleted
lub wszystkie na raz.
Jeśli chcesz dowiedzieć się więcej o opcjonalnych właściwościach w TypeScript, przejdź do ich dokumentacji tutaj.
Następnie utwórz nowy folder o nazwie modele i wewnątrz tego folderu utwórz plik o nazwie todo.ts . Dodaj następującą zawartość do pliku:
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) => {},
};
W tej chwili funkcje są puste, ale to jest w porządku. Zapełnimy je jeden po drugim.
Następnie przejdź do controllers/todo.ts
plik i upewnij się, że dodałeś następujące informacje:
// 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 },
) => {},
};
Tutaj też mamy puste funkcje. Zacznijmy je wypełniać.
[Pobierz] wszystkie API todos
Wewnątrz models/todo.ts
, dodaj definicję funkcji o nazwie 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
udostępnia również inną metodę poza connect
(użyliśmy metody "connect" w db/client.ts
plik) i to jest query
. client.query
Metoda pozwala nam uruchamiać zapytania MySQL bezpośrednio z naszego kodu Deno, tak jak jest.
Następnie przejdź do controllers/todo.ts
dodaj definicję dla 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}`,
};
}
},
}
Wszystko, co robimy, to importowanie TodoModel
i używając jego metody o nazwie getAll
, który właśnie zdefiniowaliśmy. Ponieważ powraca jako obietnica, otoczyliśmy go async/await.
Metoda TodoModel.getAll()
zwróci nam tablicę, którą po prostu zwracamy do response.body
ze status
ustaw na 200
.
Jeśli obietnica się nie powiedzie lub wystąpi inny błąd, po prostu przechodzimy do naszego bloku catch i zwracamy status 400 z success
ustawiony na fałsz. Ustawiamy również message
do tego, co otrzymujemy z bloku catch.
To wszystko, skończyliśmy. Teraz odpalmy nasz terminal.
Upewnij się, że Twoja instancja MySQL jest uruchomiona. W swoim terminalu wpisz:
$ deno run --allow-net server.ts
Twój terminal powinien wyglądać mniej więcej tak:
Moja konsola mówi mi tutaj dwie rzeczy.
- Że mój serwer Deno API działa na porcie 8080
- Że moja instancja MySQL działa na
127.0.0.1
, czylilocalhost
Przetestujmy nasze API. Używam tutaj Postmana, ale możesz użyć swojego ulubionego klienta API.
W tej chwili zwraca tylko puste dane. Ale kiedy dodamy dane do naszego todo
tabeli, zwróci te zadania tutaj.
Niesamowite. Jeden interfejs API nie działa, a jeszcze cztery.
[Opublikuj] dodaj API zadań
W models/todo.ts
pliku, dodaj następującą definicję dla add()
funkcja:
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,
],
);
},
}
Funkcja add przyjmuje obiekt jako argument, który ma dwa elementy:todo
i isCompleted
.
Więc add: async ({ todo, isCompleted }: Todo) => {}
można również zapisać jako ({todo, isCompleted}: {todo:string, isCompleted:boolean})
. Ale ponieważ mamy już interfejs zdefiniowany w naszych interfaces/Todo.ts
plik, który jest
export default interface Todo {
id?: number,
todo?: string,
isCompleted?: boolean,
}
możemy po prostu napisać to jako add: async ({ todo, isCompleted }: Todo) => {}
. To informuje TypeScript, że ta funkcja ma dwa argumenty, todo
, który jest ciągiem i isCompleted
, który jest wartością logiczną.
Jeśli chcesz przeczytać więcej o interfejsach, TypeScript ma doskonały dokument na ten temat, który możesz znaleźć tutaj.
Wewnątrz naszej funkcji mamy:
return await client.query(
`INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)`,
[
todo,
isCompleted,
],
);
To zapytanie można podzielić na dwie części:
INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)
. Dwa znaki zapytania tutaj oznaczają użycie zmiennych w zapytaniu.- Druga część,
[todo, isCompleted]
, to zmienne, które znajdą się w pierwszej części zapytania i być zastąpione przez(?, ?)
Table.Todo
to tylko ciąg znaków pochodzący z plikudb/config.ts
gdzieTable.Todo
wartość to „todo
"
Dalej w naszych controllers/todo.ts
pliku, przejdź do definicji createTodo()
funkcja:
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}`,
};
}
},
}
Podzielmy to na dwie części:
Część 1
const body = await request.body();
if (!request.hasBody) {
response.status = 400;
response.body = {
success: false,
message: "No data provided",
};
return;
}
Wszystko, co tutaj robimy, to sprawdzanie, czy użytkownik wysyła dane w treści. Jeśli nie, zwracamy status 400
aw treści zwróć success: false
i message: <erromessage-string>
.
Część 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}`,
};
}
Jeśli nie ma błędu, TodoModel.add()
funkcja jest wywoływana i po prostu zwraca stan 200
oraz wiadomość z potwierdzeniem dla użytkownika.
W przeciwnym razie po prostu wygeneruje podobny błąd, który zrobiliśmy w poprzednim API.
Teraz skończyliśmy. Uruchom terminal i upewnij się, że Twoja instancja MySQL działa. W swoim terminalu wpisz:
$ deno run --allow-net server.ts
Przejdź do Postman i uruchom trasę API dla tego kontrolera:
To świetnie, teraz mamy dwa działające API. Jeszcze tylko trzy.
[GET] rzeczy do zrobienia według identyfikatora API
W swoim models/todo.ts
plik, dodaj definicję dla tych dwóch funkcji, doesExistById()
i 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],
);
},
}
Porozmawiajmy o każdej funkcji jeden po drugim:
doesExistById
przyjmujeid
i zwracaboolean
wskazując, czy konkretne zadanie istnieje w bazie danych, czy nie.
Podzielmy tę funkcję:
const [result] = await client.query(
`SELECT COUNT(*) count FROM ${TABLE.TODO} WHERE id = ? LIMIT 1`,
[id],
);
return result.count > 0;
Po prostu porównujemy liczbę w tabeli z konkretnym identyfikatorem rzeczy do zrobienia. Jeśli liczba jest większa od zera, zwracamy true
. W przeciwnym razie zwracamy false
.
getById
zwraca element do zrobienia z określonym identyfikatorem:
return await client.query(
`SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
[id],
);
Po prostu uruchamiamy tutaj zapytanie MySQL, aby uzyskać zadanie według identyfikatora i zwrócić wynik bez zmian.
Następnie przejdź do controllers/todo.ts
i dodaj definicję dla getTodoById
metoda kontrolera:
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}`,
};
}
},
}
Podzielmy to na dwie mniejsze części:
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
Najpierw sprawdzamy, czy zadanie istnieje w bazie danych z identyfikatorem za pomocą tej metody:
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
Tutaj musimy przekonwertować params.id
w Number
ponieważ nasz interfejs todo akceptuje tylko id
jako liczba. Następnie po prostu przekazujemy params.id
do doesExistById
metoda. Ta metoda zostanie zwrócona jako wartość logiczna.
Następnie po prostu sprawdzamy, czy zadanie nie jest dostępne i zwracamy 404
metoda z naszą standardową odpowiedzią, jak w przypadku poprzednich punktów końcowych:
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
Następnie mamy:
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}`,
};
Jest to podobne do tego, co robiliśmy w naszych poprzednich interfejsach API. Tutaj po prostu pobieramy dane z bazy danych, ustawiając zmienną todo
, a następnie zwracając odpowiedź. Jeśli wystąpi błąd, po prostu zwracamy użytkownikowi standardowy komunikat o błędzie w bloku catch.
Teraz uruchom terminal i upewnij się, że Twoja instancja MySQL jest uruchomiona. W swoim terminalu wpisz:
$ deno run --allow-net server.ts
Przejdź do Postman i uruchom trasę API dla tego kontrolera.
Pamiętaj, że za każdym razem, gdy restartujemy nasz serwer, resetujemy db. Jeśli nie chcesz tego zachowania, możesz po prostu zakomentować run
funkcja w pliku db/client.ts
.
Do tej pory wykonaliśmy API dla:
- Pobierz wszystkie rzeczy do zrobienia
- Utwórz nowe zadanie
- Zdobądź zadanie według identyfikatora
A oto pozostałe API:
- Zaktualizuj zadanie według identyfikatora
- Usuń zadanie według identyfikatora
[PUT] zaktualizuj todo przez id API
Najpierw stwórzmy model dla tego API. Wejdź do naszych models/todo.ts
i dodaj definicję dla updateById
funkcja:
**
* 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
przyjmuje 3 parametry:id
, todo
i isCompleted
.
Po prostu uruchamiamy zapytanie MySQL w tej funkcji:
onst result = await client.query(
`UPDATE ${TABLE.TODO} SET todo=?, isCompleted=? WHERE id=?`,
[
todo,
isCompleted,
id,
],
);
To aktualizuje todo
pojedynczego elementu do zrobienia i isCompleted
przez konkretny id
.
Następnie zwracamy liczbę wierszy zaktualizowanych przez to zapytanie, wykonując:
// return count of rows updated
return result.affectedRows;
Liczba będzie wynosić 0 lub 1, ale nigdy więcej niż 1. Dzieje się tak, ponieważ w naszej bazie danych mamy unikalne identyfikatory – nie może istnieć wiele zadań z tym samym identyfikatorem.
Następnie przejdź do naszych controllers/todo.ts
i dodaj definicję dla updateTodoById
funkcja:
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}`,
};
}
},
To prawie to samo, co w przypadku naszych poprzednich interfejsów API, które napisaliśmy. Nowością jest to:
// if todo found then update todo
const body = await request.body();
const updatedRows = await TodoModel.updateById({
id: Number(params.id),
...body.value,
});
Po prostu pobieramy treść, którą użytkownik wysyła nam w JSON i przekazujemy ją do naszego TodoModel.updateById
funkcja.
Musimy przekonwertować id
do liczby zgodnej z naszym interfejsem Todo.
Zapytanie jest wykonywane i zwraca liczbę zaktualizowanych wierszy. Stamtąd po prostu zwracamy to w naszej odpowiedzi. Jeśli wystąpi błąd, przechodzi do bloku catch, w którym zwracamy naszą standardową wiadomość odpowiedzi.
Uruchommy to i zobaczmy, czy to działa. Upewnij się, że Twoja instancja MySQL jest uruchomiona i uruchom następujące polecenie z terminala:
$ deno run --allow-net server.ts
Przejdź do Postman i uruchom trasę API dla tego kontrolera:
[DELETE] todo przez id API
W swoim models/todo.ts
plik utwórz funkcję o nazwie deleteById
:
/**
* 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;
},
Tutaj po prostu przekazujemy id
jako parametr, a następnie użyj zapytania delete MySQL. Następnie zwracamy zaktualizowaną liczbę wierszy. Zaktualizowana liczba będzie wynosić 0 lub 1, ponieważ identyfikator każdego zadania jest unikalny.
Następnie przejdź do swoich controllers/todo.ts
plik i zdefiniuj deleteByTodoId
metoda:
/**
* @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}`,
};
}
},
To całkiem proste. Przekazujemy params.id
do naszego TodoModel.deleteById
metody i zwróć liczbę wierszy zaktualizowanych za pomocą tego zapytania.
Jeśli coś pójdzie nie tak, w bloku catch zgłaszany jest błąd, który zwraca naszą standardową odpowiedź na błąd.
Sprawdźmy to.
Upewnij się, że Twoja instancja MySQL jest uruchomiona. W swoim terminalu wpisz:
$ deno run --allow-net server.ts
Przejdź do Postman i uruchom trasę API dla tego kontrolera:
Z tym skończyliśmy z naszym samouczkiem Deno + Oak + MySQL.
Cały kod źródłowy jest dostępny tutaj:https://github.com/adeelibr/deno-playground. Jeśli znajdziesz problem, po prostu daj mi znać. Lub złóż żądanie ściągnięcia, a przyznam ci kredyt w repozytorium.
Jeśli uznałeś ten samouczek za pomocny, udostępnij go. I jak zawsze jestem dostępny na Twitterze pod @adeelibr. Bardzo chciałbym poznać Twoje przemyślenia na ten temat.