sql >> Base de Datos >  >> RDS >> Mysql

Cómo usar MySQL con Deno y Oak

Recientemente escribí sobre cómo hacer una API Todo en Deno + Oak (sin usar una base de datos) . Puede encontrar el repositorio en chapter_1:oak en GitHub.

Este tutorial continúa donde lo dejó el otro y repasaré cómo integrar MySQL en un proyecto de Deno y Oak.

Si en algún momento desea ver el código fuente completo utilizado en este tutorial, está disponible en chapter_2:mysql . No dudes en darle una estrella en GitHub si te gusta.

Supongo que ya completó el último tutorial mencionado anteriormente. Si no, échale un vistazo aquí y vuelve cuando hayas terminado.

Antes de comenzar, asegúrese de tener un cliente MySQL instalado y ejecutándose:

  • Servidor comunitario MySQL [Descargar aquí]
  • Banco de trabajo MySQL [Descargar aquí]

Escribí una pequeña guía para usuarios de Mac OS sobre cómo configurar MySQL porque también tuve problemas con él. Compruébalo aquí.

Si está en una máquina con Windows, puede usar las mismas herramientas o también puede usar XAMPP para tener una instancia de MySQL ejecutándose en su tablero.

Una vez que tenga una instancia de MySQL ejecutándose, podemos comenzar nuestro tutorial.

Comencemos

Asumiendo que vienes de este artículo, Todo API en Deno + Oak (sin usar una base de datos) , haremos lo siguiente:

  • Cree una conexión de base de datos MySQL
  • Escriba un pequeño script que restablezca la base de datos cada vez que iniciamos nuestro servidor Deno
  • Realizar operaciones CRUD en una tabla
  • Agregue la funcionalidad CRUD a nuestros controladores API

Una última cosa:aquí está toda la diferencia de confirmación que se hizo en el Capítulo 1 para agregar MySQL al proyecto (código fuente que muestra las nuevas incorporaciones realizadas en el capítulo 1).

En la carpeta raíz de su proyecto, el mío se llama chapter_2:mysql , aunque el tuyo puede llamarse como quieras:crea una carpeta llamada db . Dentro de esa carpeta, cree un archivo llamado config.ts y añádele el siguiente contenido:

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

Aquí no hay nada sofisticado, solo definir el nombre de nuestra base de datos junto con un objeto para las tablas y luego exportarlo. Nuestro proyecto tendrá una base de datos llamada "deno" y dentro de esa base de datos solo tendremos una tabla llamada "todo".

A continuación, dentro de la db carpeta, cree otro archivo llamado client.ts y agregue el siguiente contenido:

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;

Un par de cosas están sucediendo aquí.

Estamos importando Client desde el mysql biblioteca. Client nos ayudará a conectarnos a nuestra base de datos y realizar operaciones en la base de datos.

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

Client proporciona un método llamado connect que toma un objeto donde podemos proporcionar el hostname , username , password y db . Con esta información puede establecer una conexión con nuestra instancia de MySQL.

Asegúrese de que su username no tiene password , ya que entrará en conflicto con la conexión a la biblioteca MySQL de Deno. Si no sabe cómo hacerlo, lea este tutorial que escribí.

He dejado la database campo en blanco aquí porque quiero seleccionarlo manualmente más adelante en mi secuencia de comandos.

Agreguemos un script que inicializará una base de datos llamada "deno", selecciónela y dentro de esa base de datos cree una tabla llamada "todo".

Dentro de db/client.ts archivo hagamos algunas adiciones nuevas:

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;

Aquí estamos importando DATABASE y TABLE desde nuestro archivo de configuración, luego usando esos valores en una nueva función llamada run() .

Analicemos este run() función. He agregado comentarios en el archivo para ayudarlo a comprender el flujo de trabajo:

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();
  • Cree una base de datos llamada deno . Si ya existe, no haga nada.
  • Luego seleccione la base de datos a usar, que se llama deno
  • Eliminar la tabla dentro de deno llamado todo si ya existe.
  • Luego, cree una nueva tabla dentro del deno db, llámalo todo , y defina su estructura:tendrá un incremento automático único id que será un número entero, otro campo llamado todo que será una cadena, y finalmente un campo llamado isCompleted que es un booleano. También defino id como mi clave principal.

La razón por la que escribí este script fue porque no quiero tener información adicional en la instancia de MySQL. Cada vez que se ejecuta el script, simplemente reinicia todo.

No es necesario que agregue este script. Pero si no lo hace, tendrá que crear manualmente una base de datos y la tabla.

Además, consulte los documentos de la biblioteca MySQL de Deno sobre la creación de bases de datos y la creación de tablas.

Volviendo a nuestra agenda, acabamos de lograr dos cosas de las cuatro mencionadas en la parte superior del artículo:

  • Cree una conexión de base de datos MySQL
  • Escriba un pequeño script que restablezca la base de datos cada vez que iniciamos nuestro servidor Deno

Eso ya es el 50% del tutorial. Desafortunadamente, no podemos ver que suceda mucho en este momento. Agreguemos rápidamente algunas funciones para que funcione.

Realizar operaciones CRUD en una tabla y agregar la funcionalidad a nuestros controladores API

Necesitamos actualizar nuestra interfaz Todo primero. Ve a interfaces/Todo.ts archivo y agregue lo siguiente:

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

¿Qué es esto ? lo que hace es que la clave en el objeto sea opcional. Hice esto porque luego usaré diferentes funciones para pasar objetos con solo un id , todo , isCompleted , o todos a la vez.

Si desea obtener más información sobre las propiedades opcionales en TypeScript, diríjase a sus documentos aquí.

A continuación, cree una nueva carpeta llamada modelos. y dentro de esa carpeta, crea un archivo llamado todo.ts . Agregue el siguiente contenido al archivo:

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

En este momento, las funciones están vacías, pero está bien. Los llenaremos uno por uno.

A continuación, vaya a controllers/todo.ts y asegúrese de agregar lo siguiente:

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

Aquí también tenemos funciones vacías. Comencemos a llenarlos.

[Obtener] todas las API de todos

Dentro de models/todo.ts , agregue una definición para una función llamada 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}`);
  },
}

El Client también expone otro método además de connect (usamos un método de "conexión" en db/client.ts archivo) y eso es query . El client.query nos permite ejecutar consultas MySQL directamente desde nuestro código Deno tal como está.

A continuación, vaya a controllers/todo.ts agregar definición para 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}`,
      };
    }
  },
}

Todo lo que estamos haciendo es importar TodoModel y usando su método llamado getAll , que acabamos de definir ahora. Dado que regresa como una promesa, lo hemos envuelto en async/await.

El método TodoModel.getAll() nos devolverá una matriz que simplemente devolveremos a response.body con status establecido en 200 .

Si la promesa falla o hay otro error, simplemente vamos a nuestro bloque catch y devolvemos un estado de 400 con success establecido en falso. También configuramos el message a lo que obtenemos del bloque catch.

Eso es todo, hemos terminado. Ahora encendamos nuestra terminal.

Asegúrese de que su instancia de MySQL se esté ejecutando. En tu terminal escribe:

$ deno run --allow-net server.ts 

Tu terminal debería verse así:

Mi consola me dice dos cosas aquí.

  1. Que mi servidor API Deno se está ejecutando en el puerto 8080
  2. Que mi instancia de MySQL se ejecuta en 127.0.0.1 , que es localhost

Probemos nuestra API. Estoy usando Postman aquí, pero puedes usar tu cliente API favorito.

En este momento solo devuelve datos vacíos. Pero una vez que agregamos datos a nuestro todo mesa, devolverá todos los que están aquí.

Impresionante. Una API inactiva y quedan cuatro más.

[Publicar] agregar una API de tareas

En los models/todo.ts archivo, agregue la siguiente definición para add() función:

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 función de agregar toma el objeto como argumento, que tiene dos elementos:todo y isCompleted .

Así que add: async ({ todo, isCompleted }: Todo) => {} también se puede escribir como ({todo, isCompleted}: {todo:string, isCompleted:boolean}) . Pero como ya tenemos una interfaz definida en nuestro interfaces/Todo.ts archivo que es

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

simplemente podemos escribir esto como add: async ({ todo, isCompleted }: Todo) => {} . Esto le dice a TypeScript que esta función tiene dos argumentos, todo , que es una cadena, y isCompleted , que es un valor booleano.

Si desea leer más sobre las interfaces, TypeScript tiene un documento excelente que puede encontrar aquí.

Dentro de nuestra función tenemos lo siguiente:

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

Esta consulta se puede dividir en dos partes:

  • INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?) . Los dos signos de interrogación aquí indican un uso de variables dentro de esta consulta.
  • La otra parte, [todo, isCompleted] , son las variables que irán en la primera parte de la consulta y ser reemplazado por (?, ?)
  • Table.Todo es solo una cadena que proviene del archivo db/config.ts donde la Table.Todo el valor es "todo "

Siguiente dentro de nuestro controllers/todo.ts archivo, vaya a la definición de createTodo() función:

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

Vamos a dividir esto en dos partes:

Parte 1

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

Todo lo que estamos haciendo aquí es verificar si el usuario está enviando datos en el cuerpo. Si no, devolvemos un estado 400 y en el cuerpo devuelve success: false y 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}`,
  };
}

Si no hay error, el TodoModel.add() se llama a la función y simplemente devuelve un estado de 200 y un mensaje de confirmación para el usuario.

De lo contrario, arroja un error similar al que hicimos en la API anterior.

Ahora hemos terminado. Encienda su terminal y asegúrese de que su instancia de MySQL se esté ejecutando. En tu terminal escribe:

$ deno run --allow-net server.ts 

Vaya a Postman y ejecute la ruta API para este controlador:

Esto es genial, ahora tenemos dos API en funcionamiento. Solo faltan tres más.

[GET] todo por id API

En tus models/todo.ts archivo, agregue definición para estas dos funciones, doesExistById() y 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],
    );
  },
}

Hablemos de cada función una por una:

  • doesExistById toma un id y devuelve un boolean indicando si una tarea particular existe en la base de datos o no.

Desglosemos esta función:

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

Simplemente verificamos el conteo aquí en la tabla contra una identificación de tareas en particular. Si el conteo es mayor que cero, devolvemos true . De lo contrario, devolvemos false .

  • getById devuelve el elemento de tareas pendientes contra una identificación particular:
return await client.query(
  `SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
  [id],
);

Simplemente estamos ejecutando una consulta MySQL aquí para obtener una tarea por ID y devolver el resultado tal como está.

Luego, ve a tus controllers/todo.ts archivo y agregue una definición para un getTodoById método del controlador:

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

Dividamos esto en dos partes más pequeñas:

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

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

Primero verificamos si el todo existe en la base de datos contra una identificación usando este método:

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

Aquí necesitamos convertir params.id en un Number porque nuestra interfaz de tareas solo acepta id como un número A continuación, simplemente pasamos params.id al doesExistById método. Este método regresará como un booleano.

Luego simplemente verificamos si el todo no está disponible y devolvemos un 404 método con nuestra respuesta estándar como con los puntos finales anteriores:

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

Entonces tenemos:

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

Esto es similar a lo que estábamos haciendo en nuestras API anteriores. Aquí simplemente estamos obteniendo datos de la base de datos, configurando la variable todo y luego devolver la respuesta. Si hay un error, simplemente devolvemos al usuario un mensaje de error estándar en el bloque catch.

Ahora encienda su terminal y asegúrese de que su instancia de MySQL se esté ejecutando. En tu terminal escribe:

$ deno run --allow-net server.ts 

Vaya a Postman y ejecute la ruta API para este controlador.

Recuerda que cada vez que reiniciamos nuestro servidor reseteamos la db. Si no desea este comportamiento, simplemente puede comentar el run función en el archivo db/client.ts .

devolverá la tarea para esa identificación si se encuentra" width="2000" height="1165" loading=" perezoso">

Hasta ahora hemos hecho API para:

  • Obtener todos
  • Crear una nueva tarea pendiente
  • Obtener una tarea por ID

Y aquí están las API restantes:

  • Actualizar una tarea pendiente por ID
  • Eliminar una tarea pendiente por ID

[PUT] actualizar todo por id API

Primero creemos un modelo para esta API. Entra en nuestros models/todo.ts y agregue una definición para un updateById función:

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

El updateById toma en 3 parámetros:id , todo y isCompleted .

Simplemente ejecutamos una consulta MySQL dentro de esta función:

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

Esto actualiza el todo de un único elemento de tareas pendientes. y isCompleted por un id específico .

A continuación, devolvemos un recuento de filas actualizadas por esta consulta haciendo:

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

El conteo será 0 o 1, pero nunca más de 1. Esto se debe a que tenemos identificaciones únicas en nuestra base de datos:no pueden existir varios todos con la misma identificación.

A continuación, vaya a nuestro controllers/todo.ts archivo y agregue una definición para un updateTodoById función:

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

Esto es casi lo mismo que nuestras API anteriores que escribimos. La parte que es nueva aquí es esta:

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

Simplemente obtenemos el cuerpo que nos envía el usuario en JSON y le pasamos el cuerpo a nuestro TodoModel.updateById función.

Tenemos que convertir el id a un número para cumplir con nuestra interfaz Todo.

La consulta se ejecuta y devuelve el recuento de filas actualizadas. A partir de ahí simplemente lo devolvemos en nuestra respuesta. Si hay un error, va al bloque catch donde devolvemos nuestro mensaje de respuesta estándar.

Ejecutemos esto y veamos si funciona. Asegúrese de que su instancia de MySQL se esté ejecutando y ejecute lo siguiente desde su terminal:

$ deno run --allow-net server.ts 

Vaya a Postman y ejecute la ruta API para este controlador:

[ELIMINAR] todo por id API

En tus models/todo.ts archivo crea una función llamada 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;
},

Aquí simplemente pasamos un id como un parámetro y luego use la consulta de eliminación de MySQL. Luego devolvemos el recuento actualizado de filas. El recuento actualizado será 0 o 1 porque el ID de cada tarea es único.

A continuación, vaya a su controllers/todo.ts archivo y defina un deleteByTodoId método:

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

Esto es bastante sencillo. Pasamos el params.id a nuestro TodoModel.deleteById método y devolver el recuento de filas actualizadas con esta consulta.

Si algo sale mal, se arroja un error en el bloque catch que devuelve nuestra respuesta de error estándar.

Echemos un vistazo a esto.

Asegúrese de que su instancia de MySQL se esté ejecutando. En tu terminal escribe:

$ deno run --allow-net server.ts 

Vaya a Postman y ejecute la ruta API para este controlador:

Con esto hemos terminado con nuestro tutorial de Deno + Oak + MySQL.

El código fuente completo está disponible aquí:https://github.com/adeelibr/deno-playground. Si encuentra un problema, hágamelo saber. O siéntete libre de hacer una solicitud de extracción y te daré crédito en el repositorio.

Si te ha resultado útil este tutorial, compártelo. Y como siempre, estoy disponible en Twitter bajo @adeelibr. Me encantaría escuchar tu opinión al respecto.