如何从 Express Server 中的不同文件夹加载 API 个端点?
How to load API Endpoints from different folders in Express Server?
我目前使用此脚本加载我的 API 端点:
readdirSync('./routes/api').map((r) =>
app.use(
`/api/v1/${r.split('.')[0]}`,
require(`./routes/api/${r.split('.')[0]}`)
)
);
它几乎读取了 routes/api
文件夹中的所有内容,我在 POSTMAN 中访问端点的方式如下:
{{URL}}/api/v1/posts/123
{{URL}}/api/v1/videos/123
{{URL}}/api/v1/users/123
and so on
现在我想做的是创建将用作工具的端点,比方说,视频转换器端点?
此外,我想将此端点放在路由文件夹内的 extras
文件夹中,如下图所示:
调用 extras
文件夹内的端点的方法如下所示:
{{URL}}/api/v1/extras/posts/123
{{URL}}/api/v1/extras/videos/123
{{URL}}/api/v1/extras/users/123
and so on
然后我决定 运行 我的服务器用第二个新脚本看看它是否可以 运行...
readdirSync('./routes/api/extras').map((r) =>
app.use(
`/api/v1/extras/${r.split('.')[0]}`,
require(`./routes/api/extras/${r.split('.')[0]}`)
)
);
好吧,它没有。我收到一个错误消息:
[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...
有谁知道有没有办法解决这个问题?
fs.readdir
将读取提供目录中的所有文件,即 和 目录中的文件。这意味着当执行 readdirSync('./routes/api')
时,目录名称 extras
也将在 .map
回调中传递给 require
并且由于它是一个目录,因此将完成以下操作(来自 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.
在你的情况下,以上两者似乎都没有找到,因此你得到错误 Cannot find module './routes/api/extras'
一种可能的解决方案是过滤掉目录,只处理文件,例如:
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]}`)
)
);
我无法创建我想要的路线
/api/v1/extras/youtube
and so on
但是,我能够通过创建一个遍历每个文件夹的函数来消除之前显示的错误。
// 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]}`)
);
});
我的 youtube 路由位于 routes>api>extras>youtube.js
但我仍然需要这样称呼它:
/api/v1/youtube
我想说的是够好!
2021 年 10 月 27 日更新:
我最终修改了我的循环,而不是使用两个返回值,item
和 routePath
,我选择只使用 routePath
并修改更完整的字符串满足我的需要。
routes.map((result) => {
const firstRoute = result.routePath
.split(`./routes`)[1]
.replace(`/api/`, `/api/v1/`)
.split('.')[0];
app.use(`${firstRoute}`, require(`.${result.routePath.split('.')[1]}`));
});
这个小技巧实际上让我可以调用我的端点很多层。
我目前使用此脚本加载我的 API 端点:
readdirSync('./routes/api').map((r) =>
app.use(
`/api/v1/${r.split('.')[0]}`,
require(`./routes/api/${r.split('.')[0]}`)
)
);
它几乎读取了 routes/api
文件夹中的所有内容,我在 POSTMAN 中访问端点的方式如下:
{{URL}}/api/v1/posts/123
{{URL}}/api/v1/videos/123
{{URL}}/api/v1/users/123
and so on
现在我想做的是创建将用作工具的端点,比方说,视频转换器端点?
此外,我想将此端点放在路由文件夹内的 extras
文件夹中,如下图所示:
调用 extras
文件夹内的端点的方法如下所示:
{{URL}}/api/v1/extras/posts/123
{{URL}}/api/v1/extras/videos/123
{{URL}}/api/v1/extras/users/123
and so on
然后我决定 运行 我的服务器用第二个新脚本看看它是否可以 运行...
readdirSync('./routes/api/extras').map((r) =>
app.use(
`/api/v1/extras/${r.split('.')[0]}`,
require(`./routes/api/extras/${r.split('.')[0]}`)
)
);
好吧,它没有。我收到一个错误消息:
[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...
有谁知道有没有办法解决这个问题?
fs.readdir
将读取提供目录中的所有文件,即 和 目录中的文件。这意味着当执行 readdirSync('./routes/api')
时,目录名称 extras
也将在 .map
回调中传递给 require
并且由于它是一个目录,因此将完成以下操作(来自 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.
在你的情况下,以上两者似乎都没有找到,因此你得到错误 Cannot find module './routes/api/extras'
一种可能的解决方案是过滤掉目录,只处理文件,例如:
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]}`)
)
);
我无法创建我想要的路线
/api/v1/extras/youtube
and so on
但是,我能够通过创建一个遍历每个文件夹的函数来消除之前显示的错误。
// 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]}`)
);
});
我的 youtube 路由位于 routes>api>extras>youtube.js
但我仍然需要这样称呼它:
/api/v1/youtube
我想说的是够好!
2021 年 10 月 27 日更新:
我最终修改了我的循环,而不是使用两个返回值,item
和 routePath
,我选择只使用 routePath
并修改更完整的字符串满足我的需要。
routes.map((result) => {
const firstRoute = result.routePath
.split(`./routes`)[1]
.replace(`/api/`, `/api/v1/`)
.split('.')[0];
app.use(`${firstRoute}`, require(`.${result.routePath.split('.')[1]}`));
});
这个小技巧实际上让我可以调用我的端点很多层。