ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Router Parameters
    Node.js/Express 2021. 11. 18. 19:54

    이 글은 Express의 Router Parameters에 관한 심화 내용을 정리하였습니다.




    < Introduction >

    When building interfaces with Express, we will run into the pattern of expecting certain information in a requested URL and using that information to identify the data that is being requested.
    To give an example :
    app.get('/sorcerers/:sorcererName', (req, res, next) => {
      const sorcerer = Sorcerers[req.params.sorcererName];
      res.send(sorcerer.info);
    });
     
    app.get('/sorcerers/:sorcererName/spellhistory', (req, res, next) => {
      const sorcerer = Sorcerers[req.params.sorcererName];
      const spellHistory = Spells[sorcerer.id].history;
      res.send(spellHistory);
    });​

    In the above code we need to extract the request parameter ' :sorcererName ' from the url in both instances, and end up duplicating the necessary code so that it appears in both routes.

    -> Here are some ways to avoid this duplication and write more quality code!

     

     


    < router.param( ) >

    To avoid replicated parameter-matching code, use router.param( ) method.

     

    < router.param( ) method >

    1. router.param( )  intercept any request
    to a route handler with the first argument.
    2. in the app.param function signature, the first argument does not have the leading :
    3. The actual value will be passed in as the fourth argument in the middleware.

    ex)

    app.param('spellId', (req, res, next, id) => {
      let spellId = Number(id);
        try {
          const found = SpellBook.find((spell) => {
            return spellId === spell.id;
          })
          if (found) {
            req.spell = found;
            next();
          } else {
            next(new Error('Your magic spell was not found in any of our tomes'));
          };
        } catch (err) {
          next(err)
        }
    });

     

    1. 'spellId' does not have the leading :
    2. The actual ID will be passed in as the middleware's fourth argument, id in this case, to the app.param callback function when a request arrives.

    -> Note that inside an app.param callback, you should use the fourth argument as the parameter’s value, not a key from the req.params object.

     

    < example in practice! >

    1. Not use router.param( ) method

    app.get('/spices/:spiceId', (req, res, next) => {
      const spiceId = Number(req.params.id);
      const spiceIndex = spiceRack.findIndex(spice => spice.id === spiceId);
      if (spiceIndex !== -1) {
        res.send(spiceRack[spiceIndex]);
      } else {
        res.status(404).send('Spice not found.');
      }
    });
    
    app.put('/spices/:spiceId', (req, res, next) => {
      const spiceId = Number(req.params.id);
      const spiceIndex = spiceRack.findIndex(spice => spice.id === spiceId);
      if (spiceIndex !== -1) {
        spiceRack[spiceIndex] = req.body.spice;
        res.send(spiceRack[spiceIndex]);
      } else {
        res.status(404).send('Spice not found.');
      }
    });

    2. use router.param( ) method

    app.param('spiceId', (req, res, next, id) => {
      let spiceId = Number(id);
      const found = spiceRack.findIndex(e => e.id === spiceId)
      if (found !== -1) {
        req.spiceIndex = found;
        next();
      } else {
        res.status(404);
      }
    })
    
    app.get('/spices/:spiceId', (req, res, next) => {
      const spiceIndex = req.spiceIndex;
      res.send(spiceRack[spiceIndex]);
    });
    
    app.put('/spices/:spiceId', (req, res, next) => {
      const spiceIndex = req.spiceIndex;
      spiceRack[spiceIndex] = req.body.spice;
      res.send(spiceRack[spiceIndex]);
    });

     

     


    < Merge Parameters >

    When we’re building web endpoints, we might want to access some property of a complex object.
    In order to do this in Express, we can design a nested router.


     

    • In order to pass parameters the parent router has access to, we pass a special configuration object when defining the router.
      {mergeParams: true}

    ex)

    const sorcererRouter = express.Router();
    const familiarRouter = express.Router({mergeParams: true});
     
    app.use('/sorcerer', sorcererRouter);
    sorcererRouter.use('/:sorcererId/familiars', familiarRouter);
     
    sorcererRouter.get('/', (req, res, next) => {
      res.status(200).send(Sorcerers);
      next();
    });
     
    sorcererRouter.param('sorcererId', (req, res, next, id) => {
      const sorcerer = getSorcererById(id);   
      req.sorcerer = sorcerer;
      next();
    });
     
    familiarRouter.get('/', (req, res, next) => {
      res.status(200).send(`Sorcerer ${req.sorcerer} has familiars ${getFamiliars(sorcerer)}`);
    });

    : in the above code, familiarRouter can access the parant(sorcererRouter)'s param!

     

     

     

     

     

     

     

     

     

     

    'Node.js > Express' 카테고리의 다른 글

    Middleware  (0) 2021.11.18
    Express Routes  (0) 2021.11.14

    댓글

Designed by Tistory.