Express:如何实现JSON API

时间:2022-09-02 11:07:47

I have a very basic express server which simply offers model-data via mongoose for webapps. So now since in my Framework (ember) the JSON-API is the new default adapter for requesting model-data, Im wondering how to implement a response for my route in a way which respects the JSON API specification.

我有一个非常基本的express服务器,它只是通过mongoose为web应用提供模型数据。因此,既然在我的框架(ember)中,JSON-API是请求模型-数据的新默认适配器,我想知道如何以符合JSON API规范的方式实现对路由的响应。

My current route in express looks like that.

我现在的快运路线是这样的。

router.get('/:id', function(req, res, next) {
  postModel.find({ //Mongoose functions
    _id: req.params.id
  }, function(err, doc) {
    res.json({ //returning the doc
      data: doc //within 'doc', the 'type'-key must be added
    });
  });

});

I have to include a key for the "type" in each responded object so the responding object will looks like that:

我必须在每个响应对象中包含一个“类型”的键,以便响应对象看起来是这样的:

{
  data:{
    type:"post",
    id:"123",
    title:"test"
  }
}

4 个解决方案

#1


1  

Here is a better answer. My request handler in express:

这里有一个更好的答案。我的请求处理程序:

router.get('/:id', function(req, res, next) {
  Lookup.findById(req.params.id, function(err, result) {
    if (err) {
      res.send({
        error: err
      });
    } else {
      res.send(to_jsonapi(result, 'lookup'));
    }
  });
});

This calls a utility function which converts the mongoose result into a valid jsonapi result. You just need to call it with the result plus the 'type' value.

这将调用一个实用函数,该函数将mongoose结果转换为有效的jsonapi结果。你只需要用结果加上“类型”值来调用它。

function to_jsonapi(result, type) {
  datajson = [];
  if (Array.isArray(result)) {
    result.forEach(function(item) {
      datajson.push({
        "type": type,
        "id": item._id,
        "attributes": item
      });
    });
  } else if (typeof result === "object") {
    // Happens when there is only one item
    datajson.push({
      "type": type,
      "id": result._id,
      "attributes": result
    });
  } else {
    datajson.push({
      "type": type
    });
  }
  return {
    "data": datajson
  };
}

This is not perfect yet but should get you down the road!

这还不完美,但应该会让你走上这条路!

#2


0  

I am just running in to this same problem. There is an ember-mongoose npm package but I have not used it yet. The way they solve the problem is actually back in the ember-data side by extending the DS.RESTAdapter. There they overwrite the findQuery function.

我也遇到了同样的问题。有一个emt -mongoose的npm包,但我还没有使用它。通过扩展DS.RESTAdapter,他们解决问题的方式实际上回到了ember数据端。在那里,它们覆盖findQuery函数。

findQuery: function(store, type, query) {
    var data = { query: query };
    return this.ajax(this.buildURL(type.typeKey), 'POST', { data: data });
  }

This is not that elegant though since it requires a customization for every data type. You can see the example here.

这并不是那么优雅,因为它需要为每个数据类型进行定制。你可以在这里看到这个例子。

Hope it helps.

希望它可以帮助。

#3


0  

Try using lean()

尝试使用精益()

router.get('/:id', function(req, res, next) {
  postModel
    .find({_id: req.params.id})
    .lean()
    .then( docs => {
      _.each( docs, doc => {
        doc.type = "post";
      });
      res.json(data: docs);
    });
});

#4


0  

If you are implementing jsonapi on server side because it will be then automatically parsed by your Ember.js Data, then I would suggest to look at different Serializers which Ember.js provides. It will solve the problem. Because it's the job of the client to parse the data in whatever way Backend provides, not that we have to make our backend compatible with clients :)

如果您正在服务器端实现jsonapi,那么它将被您的烬自动解析。js数据,然后我建议查看不同的序列化器。js提供。它将解决问题。因为客户端的工作是用后端提供的任何方式解析数据,而不是让后端与客户端兼容:)

#1


1  

Here is a better answer. My request handler in express:

这里有一个更好的答案。我的请求处理程序:

router.get('/:id', function(req, res, next) {
  Lookup.findById(req.params.id, function(err, result) {
    if (err) {
      res.send({
        error: err
      });
    } else {
      res.send(to_jsonapi(result, 'lookup'));
    }
  });
});

This calls a utility function which converts the mongoose result into a valid jsonapi result. You just need to call it with the result plus the 'type' value.

这将调用一个实用函数,该函数将mongoose结果转换为有效的jsonapi结果。你只需要用结果加上“类型”值来调用它。

function to_jsonapi(result, type) {
  datajson = [];
  if (Array.isArray(result)) {
    result.forEach(function(item) {
      datajson.push({
        "type": type,
        "id": item._id,
        "attributes": item
      });
    });
  } else if (typeof result === "object") {
    // Happens when there is only one item
    datajson.push({
      "type": type,
      "id": result._id,
      "attributes": result
    });
  } else {
    datajson.push({
      "type": type
    });
  }
  return {
    "data": datajson
  };
}

This is not perfect yet but should get you down the road!

这还不完美,但应该会让你走上这条路!

#2


0  

I am just running in to this same problem. There is an ember-mongoose npm package but I have not used it yet. The way they solve the problem is actually back in the ember-data side by extending the DS.RESTAdapter. There they overwrite the findQuery function.

我也遇到了同样的问题。有一个emt -mongoose的npm包,但我还没有使用它。通过扩展DS.RESTAdapter,他们解决问题的方式实际上回到了ember数据端。在那里,它们覆盖findQuery函数。

findQuery: function(store, type, query) {
    var data = { query: query };
    return this.ajax(this.buildURL(type.typeKey), 'POST', { data: data });
  }

This is not that elegant though since it requires a customization for every data type. You can see the example here.

这并不是那么优雅,因为它需要为每个数据类型进行定制。你可以在这里看到这个例子。

Hope it helps.

希望它可以帮助。

#3


0  

Try using lean()

尝试使用精益()

router.get('/:id', function(req, res, next) {
  postModel
    .find({_id: req.params.id})
    .lean()
    .then( docs => {
      _.each( docs, doc => {
        doc.type = "post";
      });
      res.json(data: docs);
    });
});

#4


0  

If you are implementing jsonapi on server side because it will be then automatically parsed by your Ember.js Data, then I would suggest to look at different Serializers which Ember.js provides. It will solve the problem. Because it's the job of the client to parse the data in whatever way Backend provides, not that we have to make our backend compatible with clients :)

如果您正在服务器端实现jsonapi,那么它将被您的烬自动解析。js数据,然后我建议查看不同的序列化器。js提供。它将解决问题。因为客户端的工作是用后端提供的任何方式解析数据,而不是让后端与客户端兼容:)