Parte 3. Crear una API REST: manejar solicitudes GET
En el
artículo anterior, estableció una conexión a la base de datos.
En el mismo, agregue la lógica de enrutamiento, controlador y base de datos para manejar la solicitud HTTP GET al punto final de la API de "empleados".
Agregar lógica de enrutamiento
Express se envía con la clase
Router , que simplifica el enrutamiento de las solicitudes HTTP a la lógica del controlador apropiado.
Las rutas de ruta definen los puntos finales de una URL de API y pueden contener
parámetros de ruta que capturan valores en una URL.
Hay muchas formas de determinar las rutas para su aplicación. Por ejemplo, cuando se inicia la aplicación, puede leer todos los archivos en el directorio del controlador y generar automáticamente la lógica de enrutamiento basada en algunas reglas predefinidas, como los nombres de archivo y las propiedades que proporcionan. Alternativamente, puede agregar el archivo al directorio de configuración y leerlo al inicio.
En esta aplicación, utilizará un enfoque de nivel ligeramente inferior, definiendo programáticamente rutas a través del nuevo módulo de enrutador. Cree un nuevo archivo llamado
router.js en el directorio de
servicios . Agregue el siguiente código al archivo y guarde los cambios.
const express = require('express'); const router = new express.Router(); const employees = require('../controllers/employees.js'); router.route('/employees/:id?') .get(employees.get); module.exports = router;
El módulo enrutador comienza solicitando el módulo Express y luego crea una nueva instancia de la clase Router Express. El método de ruta del módulo enrutador se utiliza para determinar la ruta en función de los datos transmitidos. La ruta incluye un parámetro opcional (debido a un signo de interrogación) llamado id. La ruta devuelta desde el enrutador tiene métodos que coinciden con los métodos HTTP y permiten definir los controladores. En este caso, el método get se utiliza para asignar la solicitud GET entrante a la función get definida en el controlador del empleado (que se creará a continuación).
Por el momento tiene un enrutador, pero no se utiliza en la aplicación. Para usarlo, abra el
archivo services / web-server.js y elimine la línea en la parte superior, que requiere un módulo de base de datos (se usó solo para probar en la
publicación anterior ). Agregue la siguiente línea de código en su lugar.
Luego use el siguiente código para reemplazar todo el controlador app.get, que responde a las solicitudes GET utilizando el módulo de base de datos (las 7 líneas).
Ahora se solicita el enrutador en el módulo de servicio web y se "monta" en / api. Esto significa que la URL completa para el punto final del empleado será http: // servidor: puerto / api / employee /: id.
Agregar lógica de controlador
La lógica del controlador entrará en funcionamiento desde el momento en que se conozca la URL del punto final y el método HTTP. Dado que el servidor web se construye usando Express, la lógica del controlador se determinará usando
middleware especial o funciones que tienen acceso a objetos de solicitud y respuesta, así como a la siguiente función.
La función de middleware utilizará la entrada del objeto de solicitud para generar una respuesta que se envía al objeto de respuesta. La siguiente función se usa generalmente para invocar la siguiente función de middleware en la tubería. Sin embargo, en esta API, la lógica del controlador será el último paso en la tubería y completará la respuesta HTTP. La siguiente función solo se llamará si se produce un error que pasa el control al controlador de errores Express estándar.
Vaya al directorio de
controladores y cree un nuevo archivo llamado
employee.js . Copie y pegue el siguiente código en el archivo y guarde los cambios.
const employees = require('../db_apis/employees.js'); async function get(req, res, next) { try { const context = {}; context.id = parseInt(req.params.id, 10); const rows = await employees.find(context); if (req.params.id) { if (rows.length === 1) { res.status(200).json(rows[0]); } else { res.status(404).end(); } } else { res.status(200).json(rows); } } catch (err) { next(err); } } module.exports.get = get;
Línea 1: API de la base de datos de empleados (se creará a continuación).
Líneas 3-23: se declara
una función asincrónica llamada get. El bloque try-catch se usa en el cuerpo de la función para capturar las excepciones lanzadas en el hilo principal y pasarlas a la siguiente función.
Líneas 5-7: se declara una constante con un contexto con nombre: este es un objeto universal que contendrá propiedades relacionadas con el método de búsqueda API de la base de datos. La propiedad id se agrega al contexto en función del valor que se obtiene a través de req.params.id.
Línea 9: El método de búsqueda se utiliza para recuperar los registros de empleados apropiados en la base de datos.
Líneas 11-19: la lógica condicional se utiliza para determinar el código de estado HTTP correcto y el cuerpo de respuesta. Si se solicitó un empleado pero no se encontró, el código de error "404 no encontrado" se envía como respuesta. De lo contrario, se envía un código 200 OK junto con el cuerpo de respuesta basado en JSON.
Línea 25: exportación de módulos para que pueda agregar a otros módulos
El objeto req.params es solo una de varias propiedades utilizadas para obtener datos de un objeto de
solicitud entrante . Otras propiedades comunes incluyen req.query para los valores de cadena de consulta en la URL, req.body para el cuerpo de la solicitud y req.cookies. Los encabezados HTTP se pueden obtener utilizando el método req.get.
Agregar lógica de base de datos
Para iniciar el módulo de base de datos de empleados, vaya al directorio
db_apis y cree un nuevo archivo llamado
employee.js . Agregue el siguiente código al archivo.
const database = require('../services/database.js'); const baseQuery = `select employee_id "id", first_name "first_name", last_name "last_name", email "email", phone_number "phone_number", hire_date "hire_date", job_id "job_id", salary "salary", commission_pct "commission_pct", manager_id "manager_id", department_id "department_id" from employees`; async function find(context) { let query = baseQuery; const binds = {}; if (context.id) { binds.employee_id = context.id; query += `\nwhere employee_id = :employee_id`; } const result = await database.simpleExecute(query, binds); return result.rows; } module.exports.find = find;
El módulo de base de datos de empleados introduce un módulo de base de datos común e inicializa una constante llamada baseQuery para la consulta SQL en la tabla de empleados. Los alias de columna con comillas dobles se utilizan para controlar el caso de las claves devueltas.
Luego se declara una función llamada find, que se utiliza para ejecutar la consulta y devolver las filas extraídas. Si el parámetro de contexto pasado tiene un valor de ID verdadero, entonces la cláusula where se agrega a la solicitud, por lo que solo se devuelve un empleado.
Tenga en cuenta que el valor context.id no se agregó a la solicitud directamente. En su lugar, se usó un marcador de posición llamado: employee_id; esto se llama una
variable de enlace . El uso de variables de enlace de bases de datos Oracle es muy importante en términos de seguridad y rendimiento. El valor de la variable de vinculación se asigna al objeto de vinculación, que se pasa junto con la consulta a database.simpleExecute. Finalmente, las filas recuperadas de la base de datos se devuelven a la persona que llama.
Inicie la aplicación y vaya al navegador en http: // localhost: 3000 / api / employee. Debería ver una lista de empleados de la siguiente manera (colapsé un par):

Puede seleccionar un empleado agregando un identificador al final de la URL, por ejemplo: http: // localhost: 3000 / api / employee / 100.

En este punto, su API puede manejar solicitudes GET en el punto final de los empleados. En la
próxima publicación, ampliará la funcionalidad CRUD agregando lógica que procesa las solicitudes POST, PUT y DELETE.