riotcitybluescountrygirl
@riotcitybluescountrygirl

Are you sure you want to delete the question?

If your question is resolved, you may close it.

Leaving a resolved question undeleted may help others!

We hope you find it useful!

node.jsのルーティング

node.jsのルーティング

入門書を見ながらnode.jsの勉強をしています。現在複数のページをルーティングで表示の分岐をさせているところなのでですが、一部書籍のコードで理解できないな部分がありますので教えていただければと思います。

不明なソースコードファイル

router.js
'use strict';

const httpStatus = require('http-status-codes'),
    contentTypes = require('./contentTypes'),
    utils = require('./utils'),
    routes = {
    'GET': {},
    'POST': {}
};

exports.handle = (req, res) => {
    try {
        routes[req.method][req.url](req, res);
        console.log(routes);
    } catch (e) {
        res.writeHead(httpStatus.OK, contentTypes.html);
        utils.getFile('views/error.html', res);
    }
};

exports.get = (url, action) => {
    routes['GET'][url] = action;
};
exports.post = (url, action) => {
    routes['POST'][url] = action;
};

exports.handle先ファイル

main.js
'use strict';

const port = 3000,
    http = require('http'),
    httpStatus = require('http-status-codes'),
    router = require('./router'),
    contentTypes = require('./contentTypes'),
    utils = require('./utils');

router.get('/', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.html);
    utils.getFile('views/index.html', res);
});

router.get('/courses', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.html);
    utils.getFile('views/courses.html', res);
});

router.get('/contact', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.html);
    utils.getFile('views/contact.html', res);
});

router.post('/', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.html);
    utils.getFile('views/thanks.html', res);
});

router.get('/graph.png', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.png);
    utils.getFile('public/images/graph.png', res);
});

router.get('/people.jpg', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.jpg);
    utils.getFile('public/images/people', res);
});

router.get('/product.jpg', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.jpg);
    utils.getFile('public/images/product.jpg', res);
});

router.get('/confetti_cuisine.css', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.css);
    utils.getFile('public/css/confetti_cuisine.css', res);
});

router.get('/bootstrap.css', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.css);
    utils.getFile('public/css/bootstrap.css', res);
});

router.get('/confetti_cuisine.js', (req, res) => {
    res.writeHead(httpStatus.OK, contentTypes.js);
    utils.getFile('public/js/confetti_cuisine.js', res);
});

http.createServer(router.handle).listen(port);
console.log(`The server is listening on port number: ${port}`);

不明点

routerjsのexports.handleの箇所ですが、try~catchのtryの処理がよくわかりません。2つ不明点があるのですが、
1つ目はroutes[req.method]req.url;の(req, res)。コンソールログで見てみると[Function (anonymous)]ということで関数?になるのでしょうか?
2つ目はそもそもtry~でどのような処理が行われているのか?
拙い質問で失礼ですが、ご回答いただけると助かります。

$ node main
The server is listening on port number: 3000
{
  GET: {
    '/': [Function (anonymous)],
    '/courses': [Function (anonymous)],
    '/contact': [Function (anonymous)],
    '/graph.png': [Function (anonymous)],
    '/people.jpg': [Function (anonymous)],
    '/product.jpg': [Function (anonymous)],
    '/confetti_cuisine.css': [Function (anonymous)],
    '/bootstrap.css': [Function (anonymous)],
    '/confetti_cuisine.js': [Function (anonymous)]
  },
  POST: { '/': [Function (anonymous)] }
}
0

1Answer

1つめ。はい。関数です。オブジェクトの値として、関数が指定されています。

2つめ。routes[req.method][req.url](req, res);は関数呼び出しを行っています。

routesオブジェクトのreq.methodフィールドのreq.urlフィールドの関数を(req, res)引数で実行しています。
関数の登録はmain.jsで行っています。

reqが以下の場合:

{
  "method": "GET",
  "url" : "/"
}

以下の関数が呼び出されます。

function (req, res) {
    res.writeHead(httpStatus.OK, contentTypes.html);
    utils.getFile('views/index.html', res);
}
1Like

Comments

  1. 御回答ありがとうございます。
    2つの不明点の回答を読んで改めて不明点がはっきりしたのですが、routesはオブジェクトですが関数として働くことができるのですか?
  2. `routes`はオブジェクトです。関数として動くことはできません。
    `routes[req.method]`もオブジェクトです。関数として動くことはできません。
    `routes[req.method][req.url]`は関数です。オブジェクトではありません。

    `routes`と`routes[req.method]`と`routes[req.method][req.url]`は親子関係ではありますが、全く別のアドレスを参照しています。混同しないようにしてください。

Your answer might help someone💌