Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

312
Visualizações
How to load API Endpoints from different folders in Express Server?

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:

enter image description here

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?

about 4 years ago · Juan Pablo Isaza
2 Respostas
Responde à pergunta

0

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!.

UPDATE ON 2021/10/27:

I ended up modifying my loop and instead of using both returned values, item and routePath, I opted to use routePath only and modify the string which was more complete according to my needs.

routes.map((result) => {
  const firstRoute = result.routePath
    .split(`./routes`)[1]
    .replace(`/api/`, `/api/v1/`)
    .split('.')[0];
  app.use(`${firstRoute}`, require(`.${result.routePath.split('.')[1]}`));
});

This small trick actually allows me to call my endpoins many levels deep.

about 4 years ago · Juan Pablo Isaza Relatório

0

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]}`)
  )
);
about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda