¿Cómo estructurar una API para separar la lógica de datos?
Crear una API eficiente y bien organizada requiere separar la lógica de datos de la lógica de negocio. Este enfoque no solo facilita el mantenimiento, sino también la escalabilidad de una aplicación. Aquí te mostramos cómo estructurar tu API para lograrlo.
¿Cómo almacenar y gestionar bases de datos?
La organización es clave al manejar diferentes bases de datos. Sigue estos pasos para optimizar su almacenamiento y gestión:
Crear una carpeta dedicada: En el directorio raíz, crea una carpeta llamada storage para almacenar las bases de datos. Esto hace que sean accesibles de manera fácil y organizada.
Base de datos falsa: Inicializa inicialmente una base de datos falsa en un archivo llamado db.js. Utiliza un objeto con funciones para listar, obtener, agregar y eliminar datos. Así podrás probar el acceso a datos sin configurar aún una base de datos real.
Funciones de datos:
list: Requiere el tipo de dato o tabla y devuelve los elementos de la misma.
functionlist(table){return database[table];}
get: Recupera un elemento basado en su identificador.
functionget(table, id){let col =list(table);return col.filter(item=> item.id=== id)[0]||null;}
add: Inserta nuevos datos en una tabla especificada.
remove: Elimina un elemento específico a partir de su identificador.
functionremove(table, id){let col =list(table); database[table]= col.filter(item=> item.id!== id);}
¿Cómo integrar el almacenamiento con la capa de red?
Tener un archivo dedicado al control de datos y su integración mejora la cohesión. Sigue estas instrucciones para que tu API funcione como un reloj:
Crear el controlador controller.js: Este archivo gestionará la interacción entre el almacenamiento de datos y la capa de red. Primero, importa el módulo de almacenamiento de la base de datos:
const store =require('../storage/db');
Funcionamiento de los controladores: Por ejemplo, para listar usuarios:
functionlistUsers(){return store.list('users');}
Integración en la capa de red: En el archivo network.js, como un servidor, importa y utiliza las funciones del controlador para responder las solicitudes. Al integrar el controlador a la respuesta HTTP, el acceso a datos se vuelve consistente y modular:
La separación y la modularización son fundamentales para mantener tu aplicación flexible y fácil de escalar:
Abstracción de Datos: Toda la lógica de datos se encapsula en db.js, permitiendo cambiar la implementación sin afectar el resto del código.
Inyección de dependencias: En las siguientes etapas, integrarás las dependencias directamente al controlador, permitiendo sencillamente el cambio de base de datos durante la ejecución.
Este enfoque no solo organiza el código, sino que lo prepara para pruebas, mantenimiento y futuras mejoras. ¡Continúa aprendiendo y refinando tus habilidades para construir aplicaciones robustas y eficientes!
Tambien se puede usar en la funcion get() de dummy find en lugar de filter, ya que find te regresa el primero que encuentra, y filter te regresa todos los que cumplan con la condicion.
functionget(table,id){let col =list(table)return col.find(item=> item.id== id)||null}
Ya que queremos que regrese el primero nos sirve el find.
:thumbsup:
yo vi lo mismo, e hice facepalm, siempre lo mas optimizado seria escribir un "for" e ir iterando, pero para que sea mas legible y mantenible se inventaron una serie de métodos, como el map para transformar, etc. La cuestion es que uno tiene que usar siempre el método mas a fin, "filter" en este caso no es correcto, filter lo usariamos si esperamos que mas de un elemento cumplan la condición. Es "find" el que se adecua perfecto a la finalidad, y si se quisiera el indice seria "findIndex"
¿El archivo network se podría llamar routes, correcto?
Es correcto david puedes tambien llamarlo asi
Me parece más claro porque se utiliza más ese nombre y es más descriptivo
Sería bueno que programen todo en ingles o en español pero no mezclar.
Tienes toda la razón.
.
En mi día a día, exclusivamente programo en inglés. Sin embargo, para los cursos intento hacerlo en español, por facilitar el aprendizaje.
.
Es muy difícil estar atento a todos los detalles, y siempre pongo el foco en explicar con claridad, a costa de que se me pueda pasar el detalle del idioma.
.
En cualquier caso, este tipo de comentarios me ayudan a mejorar, muchas gracias!
Lo haces muy bien Carlos, gracias por enfocar tu esfuerzo en el idioma, y a veces al inicio a muchos (me incluyo) nos cuesta programar en ingles
El mejor profesor. No hay forma de perderse con él.
Me gusta como vamos, solo como sugerencia todas las variables deberían ir en inglés. Hay que irnos acostumbrando al lenguaje y a tener un estandar.
Estoy de acuerdo, sin embargo este también es un ambiente de didáctico y puede que al profe se le haya pasado escribir todo en inglés :P. Pero estoy de acuerdo en que hay que tener un estándar en lo que escribimos.
Esta forma de realizar las consultas a la base de datos es simple y ahorra tiempo, pero no la recomiendo para proyectos profesionales, en su lugar, lo mejor es crear procedimientos almacenados
Implementación en TypeScript
controller.tsimport*as storefrom"../../../data/dummy";constTABLA='user';functionlist(){return store.list(TABLA);}export{ list
}```_app.ts_
import { config } from ‘…/…/config’;
import response from ‘…/network/response’;
import {router as user} from ‘./components/user/network’;
const app = express();
app.use(json());
app.use(’/api/user/’, user)
app.get(’/’, (req, res) => {
response.success(req, res, ‘Hello, TypeScript!’, 200);
});```
Este curso está dictado por un español, no sé si está nervio, pero no le entiendo cuando habla.
tambien me pasa js
¿Por qué utilizar esta arquitectura y no una como la siguiente: Model-Routes-Controllers-Services?
Hola @saminoarbelaez.
El uso de la arquitectura depende como se llegue el acuerdo en el equipo de trabajo o las necesidades que se tengan en el proyecto no podría decirte el porque usar esta arquitectura o no la otro ya que mas que nada es cuestión de que los integrante del equipo de trabajo se pongan de acuerdo de las pautas que tendrá el proyecto.
Espero que mi comentario te sea de utilidad y suerte en tus estudios.
Hola! así como dijo @CriSTEM es algo que depende del acuerdo que se lleve con el equipo de desarrollo, mayormente basandose en la estructura de la aplicación a constuir, ya que a cada aplicación debe aplicarse la arquitectura que mejor se adapte.
Aislar el código de la base de datos
Ahora una base de datos de prueba por el momento. Creamos una carpeta 'store' en la raíz y dentro un archivo dummy.js:
Dentro de 'components/user/' creamos controller.js:
//* Debe tener acceso a networkconst store =require('../../../store/dummy')constTABLA='user'functionlist(){return store.list(TABLA)}module.exports={ list
}
Hola, ¿De qué documentación de Node.js está creando la estructura del proyecto el profesor?
adjunto las capturas del codigo necesario para editar y eliminar ademas de logica para insertar
controller
network
db
Yo le agregué un poco de lógica al método remove, para tener un comportamiento un poco más parecido al de una DB!
.
Bien Jesús, también puede ser db[tabla].splice(id, 1);
Muy bueno Profe Carlos. Al principio me enrede un poco, pero luego fui conectando. Excelente contenido
Excelente teacher, cada vez se entiende mas todo este tema de Node...
Me ocurrio algo en el archivo dummy que nunca me habia pasado, cuando pongo el export al final no me reconoce las funciones lo tuve que colocar al inicio, ¿que puedo estar haciendo mal ?
RangeError [ERR_HTTP_INVALID_STATUS_CODE]: Invalid status code: Todo correcto
at ServerResponse.writeHead (_http_server.js:208:11)
at ServerResponse._implicitHeader (http_server.js:199:8)
at write (_http_outgoing.js:585:9)
at ServerResponse.end (_http_outgoing.js:709:5)
at ServerResponse.send (C:…\PlatziSocial\node_modules\express\lib\response.js:221:10)
at ServerResponse.json (C:…s\PlatziSocial\node_modules\express\lib\response.js:267:15)
at ServerResponse.send (C:…\PlatziSocial\node_modules\express\lib\response.js:158:21)
at Object.exports.success (C:…\PlatziSocial\network\response.js:4:24)
at C:…\PlatziSocial\api\components\user\network.js:10:14
at Layer.handle [as handle_request] (C:…\PlatziSocial\node_modules\express\lib\router\layer.js:95:5)
¿Alguien sabe que está pasando?
Hola no me funcionó, en el navegador me muestra lista pero no los elementos de la BD,
{
"error": false,
"status": 200,
"body": "lista"
}
Hola buenas, seguís con el error o lo pudiste solucionar? Si no has podido solucionarlo me podrías compartir el código?
Me parece que es más sencillo si el controlador es una función que recibe el (req, res) de la petición. Para que quede algo como esto: