NodeJS Express - Return the JSON file of the URL path that it triggered

10,955

You can use the express static middleware to serve static json files from a specified folder.

const express = require('express');
const app = express();

// Setup express static middleware to look for files in the api directory for all requests starting with /api
app.use('/api', express.static('api') , function(req, res){
    // Optional 404 handler
    res.status(404);
    res.json({error:{code:404}})
});


var server = app.listen(8081, () => {

   var host = server.address().address
   var port = server.address().port

   console.log("Example app listening at http://%s:%s", host, port)

})

You can then access your user.json in the folder /api/user.json at localhost:8081/api/user.json

EDIT:

If you want to be able to add multiple folders, you can create a designated public (you can call it anything, actually) directory and put all your top level folders there.

Consider the following JSON files stored in a nested fashion:

/public/api/user.json [ One level nest in api folder]

/public/data/config.json [ One level nest in data folder]

/public/data/server/config.json [Two level nest in data -> server folder]

you can then do

const express = require('express');
const app = express();

// EDIT: added options to ensure json can be accessed without extension
app.use(express.static('public',{index:false, extensions:['json']}));
app.use(function (req, res) {
    // Optional 404 handler
    res.status(404);
    res.json({
        error: {
            code: 404
        }
    });
})


var server = app.listen(8081, () => {

    var host = server.address().address
    var port = server.address().port

    console.log("Example app listening at http://%s:%s", host, port)

})

and then access your files as :

localhost:8081/api/user.json OR localhost:8081/api/user

localhost:8081/data/config.json OR localhost:8081/data/config

localhost:8081/data/server/config.json OR localhost:8081/data/server/config

Reference for options accepted by the express static middleware


Additional Improvement

NOTE: This method may accidentally expose sensitive server side configuration files [like your package.json] and potentially your entire codebase. Please use this method carefully and only if you know what you are doing.

If you do not want to create a designated directory (in this case 'public' folder) and put all your top level folders there in order to access it, you can use the code below to dynamically serve your files:

const express = require('express');
const app = express();

var publicdir = __dirname + '/';

app.use(express.static(publicdir,{extensions:['json']})); //or ,{index:false, extensions:['json']}
app.use(function (req, res) {

    res.status(404);
    res.json({
        error: {
            code: 404
        }
    });
})


var server = app.listen(8081, () => {

    var host = server.address().address
    var port = server.address().port

    console.log("Example app listening at http://%s:%s", host, port)

})
Share:
10,955

Related videos on Youtube

I am a Student
Author by

I am a Student

Still Learning

Updated on June 04, 2022

Comments

  • I am a Student
    I am a Student almost 2 years

    I trying to write a NodeJS project that read JSON files from the project directory and response back the JSON file data whenever, user trigger a specific URL.

    For the Project below, I am able to get the JSON data response when I trigger http://localhost:8081/api/user in web browser.

    In order to make this work I have to explicitly hardcode a function that response to a specific URL. For example, if I wanted to add 1 more JSON files in the api folder and enable user to access it, I have to explicitly hardcode another function just to response to different request.

    app.get('/api/newJSONFile', (req, res) => {
    
           fs.readFile( __dirname +'/api/newJSONFile' +".json", 'utf8', function (err, data) {
               res.send(data);
               res.end( data );
           });
    
        });
    

    So, after adding the code above the user will able to access the JSON file through http://localhost:8081/api/newJsonFile. Without the explicitly hardcode function above user will not able to get response when launch the http://localhost:8081/api/newJsonFile

    My Question:

    1. Is this the only way to perform the response upon URL request? It seem inefficient, as if I have 100 JSON File then I have to explicitly hardcode another 100 functions.

    2. What is the proper way to code the implementation?

    Thank you.

    My Project Structure:

    enter image description here

    server.js

    const express = require('express');
    const app = express();
    const fs = require("fs");
    
    
    app.get('/api/user', (req, res) => {
    
       fs.readFile( __dirname +'/api/user' +".json", 'utf8', function (err, data) {
           res.send(data);
           res.end( data );
       });
    
    });
    
    
    var server = app.listen(8081, () => {
    
      var host = server.address().address
      var port = server.address().port
    
      console.log("Example app listening at http://%s:%s", host, port)
    
    })
    
  • I am a Student
    I am a Student almost 6 years
    seem like the folder need to be hardcode too, for the '/api'. Is it possible to make it, auto detect the folder URL too? for example, I add a new folder with other json file in it, I do not need to declare another use() function.
  • Chirag Ravindra
    Chirag Ravindra almost 6 years
    @EricWong Yup, you can do that but you may need to reorganise your folder structure a little bit. See my edited answer
  • I am a Student
    I am a Student almost 6 years
    This actually working well too, is there any method to output the JSON data which is well-formatted? I tried this > obj = JSON.parse(data); res.send(obj); < but it doesn't seem the JSON data get formatted.
  • Farhan Tahir
    Farhan Tahir almost 6 years
    @EricWong I modified my answer to send back pretty JSON. See if that works for you.
  • I am a Student
    I am a Student almost 6 years
    in my case, it wrote, res.send(JSON.stringify(data, null, 4)); and it didn't work out.
  • Farhan Tahir
    Farhan Tahir almost 6 years
    Are you adding res.header as well ?
  • I am a Student
    I am a Student almost 6 years
    btw, is it possible to make the URL does not need to put the file extension ".json" to load the file? for example, localhost:8081/api/user instead of localhost:8081/api/user.json
  • I am a Student
    I am a Student almost 6 years
    yes, anywhere, the JSON Format Output doesn't really matter. I found that using this parameter method, if I add a new folder inside the api folder, the URL will not able load. Is there any solution to overcome this limitation?
  • I am a Student
    I am a Student almost 6 years
    actually I was looking for a method call the API without the need to put the file extension ".json" eg. localhost:8081/api/user , now this method is good as it does not need to be like localhost:8081/api/user.json to call the file, but the issue is it cannot access to multiple tier folder.
  • Farhan Tahir
    Farhan Tahir almost 6 years
    You can simply add more params to your route: '/api/:parentDir/:jsonFile'
  • I am a Student
    I am a Student almost 6 years
    It look like a hardcode method, it is possible to make it auto detect the it, instead of having us to add more parems?
  • Farhan Tahir
    Farhan Tahir almost 6 years
    You can then use nodejs readdirsync to read and process directories to find the json file. Have a look at researchhubs.com/post/computing/javascript/…
  • I am a Student
    I am a Student almost 6 years
    i think i found the solution, using stackoverflow.com/questions/16895047/…
  • Chirag Ravindra
    Chirag Ravindra almost 6 years
    Yup, express static middleware provides the extensions option. Although the accepted answer works, the other answer which uses the extensions option would be the better way to do it.. will update my answer when I get to my laptop
  • I am a Student
    I am a Student almost 6 years
    seem like its a syntax error, I have help you edit the mistakes. Really appreciate your help.
  • Chirag Ravindra
    Chirag Ravindra almost 6 years
    Thanks, accepted your edits for the syntax and the additional method. The additional method you have added is VERY risky. It is never a good idea to expose your server root using a static middleware [Your entire codebase will become accessible through the static file service]. However, I have left the edit in place as it is in line with the question you have asked.