Mysql
 sql >> Database >  >> RDS >> Mysql

Come utilizzare MySQL con Deno e Oak

Di recente ho scritto su come creare una API Todo in Deno + Oak (senza utilizzare un database) . Puoi trovare il repository in capitolo_1:oak su GitHub.

Questo tutorial riprende da dove l'altro si era interrotto e parlerò di come integrare MySQL in un progetto Deno e Oak.

Se in qualsiasi momento vuoi vedere l'intero codice sorgente utilizzato in questo tutorial, è disponibile al capitolo_2:mysql . Sentiti libero di dargli una stella su GitHub se ti piace.

Presumo che tu abbia già completato l'ultimo tutorial sopra menzionato. In caso contrario, dai un'occhiata qui e torna quando hai finito.

Prima di iniziare, assicurati di avere un client MySQL installato e in esecuzione:

  • Server della comunità MySQL [Scarica qui]
  • MySQL Workbench [Scarica qui]

Ho scritto una piccola guida per gli utenti di Mac OS sulla configurazione di MySQL perché anch'io ho avuto difficoltà. Dai un'occhiata qui.

Se sei su una macchina Windows puoi usare gli stessi strumenti o puoi anche usare XAMPP per avere un'istanza MySQL in esecuzione nella tua dashboard.

Una volta che hai un'istanza MySQL in esecuzione, possiamo iniziare il nostro tutorial.

Iniziamo

Supponendo che tu provenga da questo articolo, Todo API in Deno + Oak (senza utilizzare un database) , faremo quanto segue:

  • Crea una connessione al database MySQL
  • Scrivi un piccolo script che reimposti il ​​database ogni volta che avviamo il nostro server Deno
  • Esegui operazioni CRUD su un tavolo
  • Aggiungi la funzionalità CRUD ai nostri controller API

Un'ultima cosa:ecco l'intera differenza di commit che è stata fatta nel Capitolo 1 per aggiungere MySQL al progetto (codice sorgente che mostra le nuove aggiunte fatte dal capitolo 1).

Nella cartella principale del tuo progetto, la mia si chiama chapter_2:mysql , sebbene il tuo può essere chiamato come vuoi:crea una cartella chiamata db . All'interno di quella cartella, crea un file chiamato config.ts e aggiungi il seguente contenuto:

export const DATABASE: string = "deno";
export const TABLE = {
  TODO: "todo",
};

Niente di speciale qui, basta definire il nome del nostro database insieme a un oggetto per le tabelle e quindi esportarlo. Il nostro progetto avrà un database chiamato "deno" e all'interno di quel db avremo solo una tabella chiamata "todo".

Successivamente, all'interno del db cartella, crea un altro file chiamato client.ts e aggiungi il seguente contenuto:

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;

Qui stanno accadendo un paio di cose.

Stiamo importando Client da mysql biblioteca. Client ci aiuterà a connetterci al nostro database ed eseguire operazioni nel database.

client.connect({
  hostname: "127.0.0.1",
  username: "root",
  password: "",
  db: "",
});

Client fornisce un metodo chiamato connect che prende in oggetto dove possiamo fornire il hostname , username , password e db . Con queste informazioni può stabilire una connessione alla nostra istanza MySQL.

Assicurati che il tuo username non ha password , poiché entrerà in conflitto con la connessione alla libreria MySQL di Deno. Se non sai come farlo, leggi questo tutorial che ho scritto.

Ho lasciato il database campo vuoto qui perché voglio selezionarlo manualmente più avanti nel mio script.

Aggiungiamo uno script che inizializzerà un database chiamato "deno", lo selezioniamo e all'interno di quel db creiamo una tabella chiamata "todo".

Dentro db/client.ts file facciamo alcune nuove aggiunte:

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;

Qui stiamo importando DATABASE e TABLE dal nostro file di configurazione, quindi utilizzando quei valori in una nuova funzione chiamata run() .

Analizziamo questo run() funzione. Ho aggiunto commenti nel file per aiutarti a comprendere il flusso di lavoro:

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();
  • Crea un database chiamato deno . Se esiste già, non fare nulla.
  • Quindi seleziona il database da usare, che si chiama deno
  • Cancella la tabella all'interno di deno chiamato todo se esiste già.
  • Quindi, crea una nuova tabella all'interno di deno db, chiamalo todo e definisci la sua struttura:avrà un incremento automatico id univoco che sarà un numero intero, un altro campo chiamato todo che sarà una stringa e infine un campo chiamato isCompleted che è un booleano. Definisco anche id come chiave primaria.

Il motivo per cui ho scritto questo script è perché non voglio avere informazioni extra nell'istanza di MySQL. Ogni volta che lo script viene eseguito, reinizializza tutto.

Non è necessario aggiungere questo script. Ma se non lo fai, dovrai creare manualmente un db e la tabella.

Inoltre, controlla i documenti della libreria Deno MySQL sulla creazione di db e sulla creazione di tabelle.

Tornando alla nostra agenda, abbiamo appena ottenuto due risultati dei quattro menzionati all'inizio dell'articolo:

  • Crea una connessione al database MySQL
  • Scrivi un piccolo script che reimposti il ​​database ogni volta che avviamo il nostro server Deno

Questo è già il 50% del tutorial. Sfortunatamente, non possiamo vedere che sta succedendo molto in questo momento. Aggiungiamo rapidamente alcune funzionalità per vederlo funzionare.

Esecuzione di operazioni CRUD su una tabella e aggiunta della funzionalità ai nostri controller API

Dobbiamo prima aggiornare la nostra interfaccia di Todo. Vai a interfaces/Todo.ts file e aggiungi quanto segue:

export default interface Todo {
  id?: number,
  todo?: string,
  isCompleted?: boolean,
}

Che cos'è questo ? fa è rende la chiave nell'oggetto opzionale. L'ho fatto perché in seguito utilizzerò diverse funzioni per passare oggetti con solo un id , todo , isCompleted , o tutti insieme.

Se vuoi saperne di più sulle proprietà opzionali in TypeScript, vai ai loro documenti qui.

Quindi, crea una nuova cartella denominata models e all'interno di quella cartella, crea un file chiamato todo.ts . Aggiungi il seguente contenuto al file:

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) => {},
};

In questo momento le funzioni sono vuote, ma va bene. Li riempiremo uno per uno.

Quindi vai su controllers/todo.ts file e assicurati di aggiungere quanto segue:

// 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 },
  ) => {},
};

Qui abbiamo anche funzioni vuote. Iniziamo a riempirli.

[Ottieni] tutte le API todos

Dentro models/todo.ts , aggiungi una definizione per una funzione chiamata 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}`);
  },
}

Il Client espone anche un altro metodo oltre a connect (abbiamo usato un metodo "connect" in db/client.ts file) e questo è query . Il client.query il metodo ci consente di eseguire query MySQL direttamente dal nostro codice Deno così com'è.

Quindi vai su controllers/todo.ts aggiungi una definizione per 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}`,
      };
    }
  },
}

Tutto ciò che stiamo facendo è importare TodoModel e usando il suo metodo chiamato getAll , che abbiamo appena definito ora. Dal momento che ritorna come una promessa, l'abbiamo avvolto in async/await.

Il metodo TodoModel.getAll() ci restituirà un array che ritorneremo semplicemente a response.body con status impostato su 200 .

Se la promessa fallisce o c'è un altro errore, andiamo semplicemente al nostro blocco catch e restituiamo uno stato di 400 con success impostato su falso. Impostiamo anche il message a ciò che otteniamo dal blocco catch.

Questo è tutto, abbiamo finito. Ora accendiamo il nostro terminale.

Assicurati che la tua istanza MySQL sia in esecuzione. Nel tuo terminale digita:

$ deno run --allow-net server.ts 

Il tuo terminale dovrebbe assomigliare a questo:

La mia console mi dice due cose qui.

  1. Che il mio server API Deno è in esecuzione sulla porta 8080
  2. Che la mia istanza MySQL è in esecuzione su 127.0.0.1 , che è localhost

Testiamo la nostra API. Sto usando Postman qui, ma puoi usare il tuo client API preferito.

In questo momento restituisce solo dati vuoti. Ma una volta aggiunti i dati al nostro todo tabella, restituirà quelle cose da fare qui.

Eccezionale. Un'API inattiva e altre quattro in arrivo.

[Post] aggiungi un'API todo

In models/todo.ts file, aggiungi la seguente definizione per add() funzione:

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,
      ],
    );
  },
}

La funzione add accetta oggetto come argomento, che ha due elementi:todo e isCompleted .

Quindi add: async ({ todo, isCompleted }: Todo) => {} può anche essere scritto come ({todo, isCompleted}: {todo:string, isCompleted:boolean}) . Ma poiché abbiamo già un'interfaccia definita nelle nostre interfaces/Todo.ts file che è

export default interface Todo {
  id?: number,
  todo?: string,
  isCompleted?: boolean,
}

possiamo semplicemente scriverlo come add: async ({ todo, isCompleted }: Todo) => {} . Questo dice a TypeScript che questa funzione ha due argomenti, todo , che è una stringa e isCompleted , che è un booleano.

Se vuoi saperne di più sulle interfacce, TypeScript ha un eccellente documento che puoi trovare qui.

All'interno della nostra funzione abbiamo quanto segue:

return await client.query(
  `INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)`,
  [
    todo,
    isCompleted,
  ],
);

Questa query può essere suddivisa in due parti:

  • INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?) . I due punti interrogativi qui denotano un uso di variabili all'interno di questa query.
  • L'altra parte, [todo, isCompleted] , sono le variabili che andranno nella prima parte della query ed essere sostituito con (?, ?)
  • Table.Todo è solo una stringa proveniente dal file db/config.ts dove il Table.Todo il valore è "todo "

Avanti all'interno dei nostri controllers/todo.ts file, vai alla definizione del createTodo() funzione:

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}`,
      };
    }
  },
}

Dividiamolo in due parti:

Parte 1

const body = await request.body();
if (!request.hasBody) {
  response.status = 400;
  response.body = {
    success: false,
    message: "No data provided",
  };
  return;
}

Tutto quello che stiamo facendo qui è controllare se l'utente sta inviando i dati nel corpo. In caso contrario, restituiamo uno stato 400 e nel corpo restituisci success: false e message: <erromessage-string> .

Parte 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}`,
  };
}

Se non ci sono errori, TodoModel.add() viene chiamata la funzione e restituisce semplicemente uno stato di 200 e un messaggio di conferma all'utente.

Altrimenti genera semplicemente un errore simile che abbiamo fatto nell'API precedente.

Ora abbiamo finito. Avvia il tuo terminale e assicurati che la tua istanza MySQL sia in esecuzione. Nel tuo terminale digita:

$ deno run --allow-net server.ts 

Vai a Postman ed esegui il percorso API per questo controller:

Questo è fantastico, ora abbiamo due API funzionanti. Mancano solo altri tre.

[GET] todo by id API

Nel tuo models/todo.ts file, aggiungi la definizione per queste due funzioni, doesExistById() e 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],
    );
  },
}

Parliamo di ciascuna funzione una per una:

  • doesExistById accetta un id e restituisce un boolean indicando se una particolare cosa da fare esiste o meno nel database.

Analizziamo questa funzione:

const [result] = await client.query(
  `SELECT COUNT(*) count FROM ${TABLE.TODO} WHERE id = ? LIMIT 1`,
  [id],
);
return result.count > 0;

Controlliamo semplicemente il conteggio qui nella tabella rispetto a un particolare todo id. Se il conteggio è maggiore di zero, restituiamo true . In caso contrario, restituiremo false .

  • getById restituisce l'elemento da fare rispetto a un ID particolare:
return await client.query(
  `SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
  [id],
);

Stiamo semplicemente eseguendo una query MySQL qui per ottenere una cosa da fare tramite id e restituire il risultato così com'è.

Quindi, vai ai tuoi controllers/todo.ts file e aggiungi una definizione per un getTodoById metodo del controllore:

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}`,
      };
    }
  },
}

Dividiamolo in due parti più piccole:

const isAvailable = await TodoModel.doesExistById(
  { id: Number(params.id) },
);

if (!isAvailable) {
  response.status = 404;
  response.body = {
    success: false,
    message: "No todo found",
  };
  return;
}

Per prima cosa controlliamo se la cosa da fare esiste nel database rispetto a un id usando questo metodo:

const isAvailable = await TodoModel.doesExistById(
  { id: Number(params.id) },
);

Qui dobbiamo convertire params.id in un Number perché la nostra interfaccia todo accetta solo id come numero. Successivamente, passiamo semplicemente a params.id al doesExistById metodo. Questo metodo verrà restituito come booleano.

Quindi controlliamo semplicemente se la cosa da fare non è disponibile e restituiamo un 404 metodo con la nostra risposta standard come con gli endpoint precedenti:

if (!isAvailable) {
  response.status = 404;
  response.body = {
    success: false,
    message: "No todo found",
  };
  return;
}

Allora abbiamo:

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}`,
};

Questo è simile a quello che stavamo facendo nelle nostre precedenti API. Qui stiamo semplicemente ottenendo i dati dal db, impostando la variabile todo e quindi restituire la risposta. Se si verifica un errore, restituiamo semplicemente all'utente un messaggio di errore standard nel blocco catch.

Ora avvia il tuo terminale e assicurati che la tua istanza MySQL sia in esecuzione. Nel tuo terminale digita:

$ deno run --allow-net server.ts 

Vai a Postman ed esegui il percorso API per questo controller.

Ricorda che ogni volta che riavviamo il nostro server resettiamo il db. Se non vuoi questo comportamento, puoi semplicemente commentare run funzione nel file db/client.ts .

restituirà la cosa da fare per quell'id se trovato" width="2000" height="1165" loading=" pigro">

Finora abbiamo creato API per:

  • Ricevi tutte le cose da fare
  • Crea una nuova attività
  • Ricevi una cosa da fare per ID

Ed ecco le restanti API:

  • Aggiorna una cosa da fare per ID
  • Elimina una cosa da fare per ID

[PUT] aggiorna todo da id API

Creiamo prima un modello per questa API. Vai nel nostro models/todo.ts file e aggiungi una definizione per un updateById funzione:

**
 * 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;
},

Il updateById accetta 3 parametri:id , todo e isCompleted .

Eseguiamo semplicemente una query MySQL all'interno di questa funzione:

onst result = await client.query(
  `UPDATE ${TABLE.TODO} SET todo=?, isCompleted=? WHERE id=?`,
  [
    todo,
    isCompleted,
    id,
  ],
);

Questo aggiorna le todo di un singolo elemento da fare e isCompleted da uno specifico id .

Successivamente restituiamo un conteggio di righe aggiornate da questa query eseguendo:

  // return count of rows updated
  return result.affectedRows;

Il conteggio sarà 0 o 1, ma mai più di 1. Questo perché abbiamo ID univoci nel nostro database:non possono esistere più cose da fare con lo stesso ID.

Quindi vai ai nostri controllers/todo.ts file e aggiungi una definizione per un updateTodoById funzione:

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}`,
    };
  }
},

Questo è quasi lo stesso delle nostre precedenti API che abbiamo scritto. La parte che è nuova qui è questa:

// if todo found then update todo
const body = await request.body();
const updatedRows = await TodoModel.updateById({
  id: Number(params.id),
  ...body.value,
});

Otteniamo semplicemente il corpo che l'utente ci invia in JSON e lo passiamo al nostro TodoModel.updateById funzione.

Dobbiamo convertire l'id a un numero per rispettare la nostra interfaccia Todo.

La query viene eseguita e restituisce il conteggio delle righe aggiornate. Da lì lo restituiamo semplicemente nella nostra risposta. Se c'è un errore, va al blocco catch dove restituiamo il nostro messaggio di risposta standard.

Eseguiamo questo e vediamo se funziona. Assicurati che la tua istanza MySQL sia in esecuzione ed esegui quanto segue dal tuo terminale:

$ deno run --allow-net server.ts 

Vai a Postman ed esegui il percorso API per questo controller:

[DELETE] todo by id API

Nel tuo models/todo.ts file crea una funzione chiamata 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;
},

Qui passiamo semplicemente un id come parametro e quindi utilizzare la query di eliminazione MySQL. Quindi restituiamo il conteggio aggiornato delle righe. Il conteggio aggiornato sarà 0 o 1 perché l'ID di ogni attività è univoco.

Quindi, vai nel tuo controllers/todo.ts file e definire un deleteByTodoId metodo:

/**
 * @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}`,
    };
  }
},

Questo è piuttosto semplice. Passiamo il params.id al nostro TodoModel.deleteById metodo e restituisce il conteggio delle righe aggiornate con questa query.

Se qualcosa va storto, viene generato un errore nel blocco catch che restituisce la nostra risposta di errore standard.

Diamo un'occhiata.

Assicurati che la tua istanza MySQL sia in esecuzione. Nel tuo terminale digita:

$ deno run --allow-net server.ts 

Vai a Postman ed esegui il percorso API per questo controller:

Con questo abbiamo finito con il nostro tutorial Deno + Oak + MySQL.

L'intero codice sorgente è disponibile qui:https://github.com/adeelibr/deno-playground. Se trovi un problema, fammelo sapere. Oppure sentiti libero di fare una richiesta pull e ti darò credito nel repository.

Se hai trovato utile questo tutorial, condividilo. E come sempre, sono disponibile su Twitter sotto @adeelibr. Mi piacerebbe sentire i tuoi pensieri al riguardo.