I currently use my load my API endpoints using this script:
readdirSync('./routes/api').map((r) =>
app.use(
`/api/v1/${r.split('.')[0]}`,
require(`./routes/api/${r.split('.')[0]}`)
)
);
It pretty much reads everything inside the routes/api
folder and the way in which I access the endpoins in POSTMAN is as follow:
{{URL}}/api/v1/posts/123
{{URL}}/api/v1/videos/123
{{URL}}/api/v1/users/123
and so on
Now what I would like to do is to create endpoints that will be used as tools, let's say, a video converter endpoint?
Furthermore I would like to put this endpoint inside an extras
folder within the routes folder, exactly like the image below:
The way to call the endpoins inside the extras
folder would then look like this:
{{URL}}/api/v1/extras/posts/123
{{URL}}/api/v1/extras/videos/123
{{URL}}/api/v1/extras/users/123
and so on
Then I decided to run my server with a second new script to see if it could run...
readdirSync('./routes/api/extras').map((r) =>
app.use(
`/api/v1/extras/${r.split('.')[0]}`,
require(`./routes/api/extras/${r.split('.')[0]}`)
)
);
Well, it did not. I got an error thrown at me:
[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...
Does any one knows if theres a way to solve this?
CodePudding user response:
fs.readdir
will read all the files in the provided directory, i.e. files and directories also. This means that when executing readdirSync('./routes/api')
the directory name extras
will also be passed to require
inside your .map
callback and since it's a directory the following will be done (from the docs):
[...]if the filename passed to require is actually a directory, it will first look for package.json in the directory and load the file referenced in the main property. Otherwise, it will look for an index.js.
In your case neither of above seems to be found, hence you get the error Cannot find module './routes/api/extras'
One possible solution is to filter out directories and only process files, e.g.:
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]}`)
)
);
CodePudding user response:
I was not able to create routes as I wanted
/api/v1/extras/youtube
and so on
However, I was able to remove the error shown before by creating a function that iterates throught every single folder.
// 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]}`)
);
});
My youtube route is located in routes>api>extras>youtube.js
but I still need to call it this way:
/api/v1/youtube
Which I would like to say is good enough!.