JSON:从对象返回整个匹配数组

时间:2016-02-15 12:16:10

标签: javascript json node.js api express

我有一个API的JSON文件。这将为我的下一个个人网站提供静态内容:

[
  {
    "articles": [
      {
        "_id": "0",
        "url": "audrey-hepburn",
        "title": "Audrey Hepburn",
        "category": "foo",
        "body": "Nothing is impossible, the word itself says 'I'm possible'!",
        "tags": [ "foo" ]
      },
      {
        "_id": "1",
        "url": "walt-disney",
        "title": "Walt Disney",
        "category": "foo",
        "body": "You may not realize it when it happens, but a kick in the teeth may be the best thing in the world for you.",
        "tags": [ "foo", "bar" ]
      },
      {
        "_id": "2",
        "url": "unknown",
        "title": "Unknown",
        "category": "bar",
        "body": "Even the greatest was once a beginner. Don't be afraid to take that first step.",
        "tags": [ "foo", "bar", "baz" ]
      },
      {
        "_id": "3",
        "url": "neale-donald-walsch",
        "title": "Neale Donald Walsch",
        "category": "bar",
        "body": "You are afraid to die, and you're afraid to live. What a way to exist.",
        "tags": [ "foo", "bar", "baz" ]
      },
      {
        "_id": "4",
        "url": "test",
        "title": "Test Article",
        "category": "bar",
        "body": "This is a test article.",
        "tags": [ "foo", "bar", "baz", "bam" ]
      }
    ]
  },
  {
    "users": [
      { "name": "Admin" },
      { "name": "User" }
    ]
  }
]

此API调用此JSON文件:

/////////////////////////////////////////////////////////////
// GRABS EVERY ARTICLES PER PAGES BY LATEST
// http://127.0.0.1:3000/api/articles/page/0/2/order/adddate/auth/<API-TOKEN>
/////////////////////////////////////////////////////////////

router.get('/articles/page/:start/:end/order/:order/auth/:token', function(req, res) {
  fsAsync(function(err, data) {
    if (err) {
      return res.send(err);
    }

    if(req.params.order === 'adddate') {
      var articles = data[0].articles.reverse();
    }
    else {
      var articles = data[0].articles;
    }

    var start = req.params.start;
    var end = req.params.end;
    var slice = articles.slice(start, end);

    var q = slice.filter(function (article) {
      return article && apiToken === req.params.token;
    });
    res.json(q);
  });
});

/////////////////////////////////////////////////////////////
// GRABS SINGLE ARTICLE BY URL
// http://127.0.0.1:3000/api/articles/url/foo/auth/<API-TOKEN>
// Match any field like "url" and not just the index "id"
/////////////////////////////////////////////////////////////

router.get('/articles/url/:id/auth/:token', function(req, res) {
  fsAsync(function(err, data) {
    if (err) {
      return res.send(err);
    }
    var articles = data[0].articles;
    var q = articles.filter(function (article) {
      // return article.id === req.params.id;
      return article.url === req.params.id && apiToken === req.params.token;
    });
    res.json(q[0]);
  });
});

单个博文的路由器,当我使用http://domain.com/journal/audrey-hepburn网址请求单个博文时使用url api:

router.get('/:url', function(req, res, next) {
  var URL = req.params.url;
  console.log(URL);

  var reqURL = req.protocol + '://' + req.hostname + ':' + usedPort + '/api/articles/url/' + URL + '/auth/' + apiToken;

  request(reqURL, function (error, response, body) {
    console.log(JSON.parse(body));
    var articles = JSON.parse(body);
    res.render('blog-article', {
      layout: 'main',
      data: articles
    });
  })
});

单个博文的车把模板:

<article class="id-{{data._id}}">
  <h1><a href="/journal/{{data.url}}">{{data.title}}</a></h1>
  <div class="category"><a href="/category/{{data.category}}">{{data.category}}</a></div>
  <p>{{data.body}}</p>
  <div class="tags">
    <ul>
      {{#each data.tags}}
      <li><a href="/tags/{{this}}">{{this}}</a></li>
      {{/each}}
    </ul>
  </div>
</article>

例如,当我想查看http://domain.com/journal/audrey-hepburn时,如果我想访问我的Audrey Hepburn网址?我使用这个解决方案。

我的问题是我如何修改路由器如果没有任何URL路由器解决方案,只是第一个将每个文章数组抓到JSON文件中的单个对象的解决方案?

当然,最简单的方法是,如果我为每个文章数组创建一个名称为_idurl的对象,但不幸的是我想将此模板用于将来具有外部api的站点,而不是每个api将其帖子内容与唯一标识符分开,而是遵循相同的路由,将请求与其他数组放在同一个对象中。

感谢您的帮助!

解决方案(谢谢ShanShan):

var db = '/../public/articles/data.json';
var data = require(__dirname + db);

router.get('/:url', function (req, res, next) {
  var articles = data[0].articles;
  var url = req.params.url;

  var selectedArticle = articles.find(function(article) {
      return article.url === url;
  });

  console.log(selectedArticle);

  res.render('blog-article', {
    layout: 'main',
    data: selectedArticle
  });
});

1 个答案:

答案 0 :(得分:2)

您已经知道如何创建路线,您只需要过滤文章:

router.get('/journal/:url', function (req, res, next) {
    fsAsync(function (err, data) {
        var articles = data[0].articles;
        var url = req.params.url;

        // this will get you the first article matching the url
        var selectedArticle = articles.find(function(article) {
            return article.url == url;
        });

        // render your page with selectedArticle

    });
});

另一方面,如果您的应用未更改您的JSON文件或经常不更改,您可以使用require一次性加载它,而不是一次又一次地读取文件:

// data is an object
var data = require(__dirname + db);

router.get('', function (req, res, next) {
    var articles = data[0].articles;
    // ...
});