简体   繁体   English

如何在REST API中公开MongoDB文档的主键?

[英]How to expose MongoDB documents primary keys in a REST API?

I am building a REST API with MongoDB + nodeJS. 我正在使用MongoDB + nodeJS构建REST API。 All the documents are stored and are using _id as the primary key. 所有文档都已存储,并使用_id作为主键。 I've read here that we should not expose the _id and we should use another ID which is not incremental. 我在这里读到,我们不应该公开_id,而应该使用另一个非增量ID。

In the DB, a document is represented as: 在数据库中,文档表示为:

{ 
   _id: ObjectId("5d2399b83e9148db977859ea")
   bookName: "My book"
}

For the following the endpoints, how should the documents be exposed? 对于以下端点,应如何公开文档?

GET /books
GET /books/{bookId}

Currently my API returns: 目前,我的API返回:

{ 
   _id: "5d2399b83e9148db977859ea"
   bookName: "My book"
}

but should it instead return something like: 但它应该返回如下内容:

{ 
   id: "some-unique-id-generated-on-creation"
   bookName: "My book"
}

Questions 问题

  • Should I expose the _id so that one can make queries such as: 我是否应该公开_id以便进行如下查询:

    GET /books/5d2399b83e9148db977859ea GET / books / 5d2399b83e9148db977859ea

  • Should I use a UUID for my ID instead of ObjectId? 我应该使用UUID代替ID作为ID吗?

  • Should I keep the internal _id (but never expose it) and create another attribute id which would use UUID or another custom generated ID ? 我应该保留内部_id(但不要公开它)并创建另一个将使用UUID或另一个自定义生成的ID的属性ID吗?
  • Is it a good practice to work with _id in my backend or should I only make queries using my own custom ID? 在后端使用_id是一种好习惯,还是仅使用自己的自定义ID进行查询? Example: find({ id: }) instead of find({ _id: }) 示例:find({id:})而不是find({_id:})

To answer your questions. 回答您的问题。

  1. You can expose _id so that authenticated users can make queries like GET, PUT and PATCH on that _id. 您可以公开_id,以便经过身份验证的用户可以对该_id进行查询,例如GET,PUT和PATCH。

  2. MongoDB has support that allows you to generate your own BSON ID and use it, instead of mongodb created it's own _id during the insert. MongoDB具有支持,允许您生成自己的BSON ID并使用它,而不是mongodb在插入过程中创建它自己的_id。

  3. There is no need of duplicating logic, the main purpose of _id is to identify each document separately and having two id columns means you are storing redundant data, follow DRY (DO NOT REPEAT YOURSELF) principle wherever possible. 有没有必要重复的逻辑,_id的主要目的是分别确定每个文档并且具有两个ID列意味着你存储的冗余数据,遵循DRY(不要重复自己)原则上尽可能。

  4. It's not a bad practice to work with _id in your backend. 在后端使用_id并不是一个坏习惯。

Hope this helps! 希望这可以帮助!

Given you're using Mongoose, you can use 'virtuals', which are essentially fake fields that Mongoose creates. 假设您使用的是Mongoose,则可以使用“虚拟”,这实际上是Mongoose创建的伪字段。 They're not stored in the DB, they just get populated at run time: 它们没有存储在数据库中,只是在运行时填充:

// Duplicate the ID field.
Schema.virtual('id').get(function(){
    return this._id.toHexString();
});

// Ensure virtual fields are serialised.
Schema.set('toJSON', {
    virtuals: true
});

Any time toJSON is called on the Model you create from this Schema, it will include an 'id' field that matches the _id field Mongo generates. 每当在您从此模式创建的模型上调用toJSON时,它将包含一个与Mongo生成的_id字段匹配的'id'字段。 Likewise you can set the behaviour for toObject in the same way. 同样,您可以以相同的方式为toObject设置行为。

You can refer the following docs: 您可以参考以下文档:
1) 1) https://mongoosejs.com/docs/api.html https://mongoosejs.com/docs/api.html
2) toObject method 2) toObject方法

In my case, whether it's a security risk or not, but my _id is a concatenation of any of the fields in my Document that are semantically considered as keys, ie if i have First Name, Last Name, and Email as my identifier, and a fourth field such as Age as attribute, then _id would be concatenation of all these 3 fields. 就我而言,是否存在安全风险,但是我的_id是文档中任何在语义上被视为关键字的字段的串联,即,如果我将名字,姓氏和电子邮件作为标识符,并且第四个字段,例如Age作为属性,则_id将是所有这三个字段的串联。 It would not be difficult to get and update such record as long as I have First Name, Last Name and email information available 只要我有名字,姓氏和电子邮件信息,获取和更新此类记录就不会困难

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM