Home > Blockchain >  express.js - How can I handle API calls differently based on the page from which they have been call
express.js - How can I handle API calls differently based on the page from which they have been call

Time:03-16

I am a newbie to node and express and I will break the question into 2 steps to better explain what I need.

I am using node and express to build a server with some APIs. I am serving the HTML with:

let publicPath = path.join(__dirname, 'public');
app.use(express.static(publicPath));
app.use((err, req, res, next) => {
    myLogger.error(err);
    res.status(err.statusCode).json(err);
});
app.listen(PORT, () => { myLogger.log(`Server listening on port ${PORT}`); });

First step:

I would like my app to serve the same HTML ('index.html') on different pages, e.g.:

localhost:3000/example1
localhost:3000/example2
localhost:3000/example3

I am able to do this with:

app.use('/example1', express.static(publicPath));

and so on and so forth for the other examples. However, I am using jstreetable on the front-end (that is not available on a CDN AFAIK), so I had to download it to node_modules and include it in the HTML with:

app.use('/node_modules', express.static(path.join(__dirname, 'node_modules')));

<script src="node_modules/jstree-table/jstreetable.js"></script>

Now, when I access the server through one of the URLs above (e.g. 'localhost:3000/example1'), I get the following error:

GET http://localhost:3000/example1/node_modules/jstree-table/jstreetable.js net::ERR_ABORTED 404 (Not Found)

Question: How can I keep the app pointing to the node_modules folder, keeping the path as the following?

http://localhost:3000/node_modules/jstree-table/jstreetable.js

so that it points to the correct path.

Second step:

I have several APIs defined as:

server.js

app.use('/api/forge', require('./routes/datamanagement'));

/routes/datamanagement.js

router.get('/datamanagement', async (req, res) => {
    ...code here...
}

Question: How can I have the user access this API through the page localhost:3000/example1, making API calls through:

localhost:3000/example1/api/forge/datamanagement

and also have the API function handle the request based on the page from which it has been called? (e.g. handle it differently if the call is made from 'localhost:3000/example1' or 'localhost:3000/example2')

CodePudding user response:

Your first question can be solved by using an absolute path, eg

<script src="/node_modules/jstree-table/jstreetable.js"></script>

However, I wouldn't advise exposing the entire node_modules folder publicly.

Instead, I would only expose the paths that are required. Eg

app.use("/libs/jstree-table", express.static(
  path.join(__dirname, "node_modules", "jstree-table")));

and

<script src="/libs/jstree-table/jstreetable.js"></script>

For your second question, you can use an array of paths when attaching your routes.

For example

const paths = ["/example1", "/example2", "/example3"];

app.use(paths, express.static(publicPath));
app.use(paths.map(path => `${path}/api/forge`), require('./routes/datamanagement'));

In your route handlers you can determine the path using req.baseUrl

const basePath = req.baseUrl.split("/")[1]; // example1, example2, etc

To make generic requests from your prefixed URLs, you can use something like this

fetch(location.pathname   "/api/forge/datamanagement")
  • Related