Actualmente uso mis puntos finales de carga de mi API usando este script:
readdirSync('./routes/api').map((r) => app.use( `/api/v1/${r.split('.')[0]}`, require(`./routes/api/${r.split('.')[0]}`) ) ); Prácticamente lee todo dentro de la carpeta routes/api y la forma en que accedo a los puntos finales en POSTMAN es la siguiente:
{{URL}}/api/v1/posts/123 {{URL}}/api/v1/videos/123 {{URL}}/api/v1/users/123 and so onAhora, lo que me gustaría hacer es crear puntos finales que se usarán como herramientas, digamos, ¿un punto final de conversión de video?
Además, me gustaría colocar este punto final dentro de una carpeta de extras dentro de la carpeta de rutas, exactamente como la imagen a continuación:
La forma de llamar a los puntos finales dentro de la carpeta de extras se vería así:
{{URL}}/api/v1/extras/posts/123 {{URL}}/api/v1/extras/videos/123 {{URL}}/api/v1/extras/users/123 and so onEntonces decidí ejecutar mi servidor con un segundo script nuevo para ver si podía ejecutarse...
readdirSync('./routes/api/extras').map((r) => app.use( `/api/v1/extras/${r.split('.')[0]}`, require(`./routes/api/extras/${r.split('.')[0]}`) ) );Bueno, no fue así. Me arrojaron un error:
[0] Error: Cannot find module './routes/api/extras' [0] Require stack: [0] - C:\xampp\htdocs\befree\server.js [0] at Function.Module._resolveFilename (internal/modules/cjs/loader.js:902:15) [0] at Function.Module._load (internal/modules/cjs/loader.js:746:27) [0] at Module.require (internal/modules/cjs/loader.js:974:19) [0] at require (internal/modules/cjs/helpers.js:93:18) [0] at C:\xampp\htdocs\befree\server.js:165:5 [0] at Array.map (<anonymous>) [0] at Object.<anonymous> (C:\xampp\htdocs\befree\server.js:162:29) [0] at Module._compile (internal/modules/cjs/loader.js:1085:14) [0] at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10) [0] at Module.load (internal/modules/cjs/loader.js:950:32) { [0] code: 'MODULE_NOT_FOUND', [0] requireStack: [ 'C:\\xampp\\htdocs\\befree\\server.js' ] [0] } [0] Error Cannot find module './routes/api/extras' [0] Require stack: [0] - C:\xampp\htdocs\befree\server.js [0] [nodemon] app crashed - waiting for file changes before starting...Alguien sabe si hay alguna forma de solucionar esto?
No pude crear rutas como quería
/api/v1/extras/youtube and so onSin embargo, pude eliminar el error que se mostró anteriormente al crear una función que itera a través de cada carpeta.
// Define routes const dir = './routes/api'; function getFiles(dir) { return fs.readdirSync(dir).flatMap((item) => { // const file = item.split('.')[0]; const routePath = `${dir}/${item}`; if (fs.statSync(routePath).isDirectory()) { return getFiles(routePath); } // return { singlefile: file, directories: routePath }; return { item, routePath }; }); } const routes = getFiles(dir); routes.map((result) => { app.use( `/api/v1/${result.item.split('.')[0]}`, require(`.${result.routePath.split('.')[1]}`) ); }); Mi ruta de youtube se encuentra en routes>api>extras>youtube.js pero aún necesito llamarla de esta manera:
/api/v1/youtubeLo cual me gustaría decir que es lo suficientemente bueno!.
ACTUALIZACIÓN EL 27/10/2021 :
Terminé modificando mi bucle y, en lugar de usar ambos valores devueltos, item y routePath , opté por usar solo routePath y modificar la cadena, que era más completa según mis necesidades.
routes.map((result) => { const firstRoute = result.routePath .split(`./routes`)[1] .replace(`/api/`, `/api/v1/`) .split('.')[0]; app.use(`${firstRoute}`, require(`.${result.routePath.split('.')[1]}`)); });Este pequeño truco en realidad me permite llamar a mis puntos finales a muchos niveles de profundidad.
fs.readdir leerá todos los archivos en el directorio proporcionado, es decir, también archivos y directorios. Esto significa que al ejecutar readdirSync('./routes/api') los extras del nombre del directorio también se pasarán para require dentro de su devolución de llamada .map y, dado que es un directorio, se hará lo siguiente (de los documentos ):
[...] si el nombre de archivo pasado a require es en realidad un directorio, primero buscará package.json en el directorio y cargará el archivo al que se hace referencia en la propiedad principal. De lo contrario, buscará un index.js.
En su caso, parece que no se encuentra ninguno de los anteriores, por lo que aparece el error Cannot find module './routes/api/extras'
Una posible solución es filtrar directorios y solo procesar archivos, por ejemplo:
readdirSync('./routes/api') .filter(r => fs.lstatSync('./routes/api/'+ r).isFile()) .map((r) => app.use( `/api/v1/${r.split('.')[0]}`, require(`./routes/api/${r.split('.')[0]}`) ) );