kentcdodds
kentcdodds

Reputation: 29031

RESTful Mongoose with ObjectID references

My Question: How can I have a RESTful mongodb instance which uses mongoosejs without making a million http requests?

My Setup: I'm using NodeJS for the backend with MongooseJS. I'm using AngularJS on the front-end, so I've decided to use angular-bridge to restify my MongoDB database.

My Schemas: I have the following schema:

Schemas

Note: The start of the arrow represents that object has a reference to the object at the end of the arrow (for example, comment has a owningPost property which is an ObjectID reference to the post). Also, the asterisks (*) means "many" so, a post can have many comments, but a comment references only one post and a stream can reference many buckets and a bucket can have many streams referencing it.

The issue: Let's say the user hits the page representing a bucket. I need to make the following get requests:

  1. Bucket
  2. User
  3. Every post that references the bucket
  4. Every comment that references a post
  5. The user for each comment

The number of requests can explode quickly. Perhaps I could have the comment contained in the post, that may not be a problem. However, I can't do that for everything else (and stay sane).

I tried making an endpoint that gets all of the data in different properties like:

data: {
  bucket: {},
  user: {},
  posts: [
    {
      post: {},
      comments: [
        user: {},
        comment: {}
      ]
    }
  ]
}

But then it's not longer restful... Right? It makes updating stuff a little difficult.

What am I doing wrong? What's a better way to do this?

Upvotes: 3

Views: 797

Answers (3)

dliu
dliu

Reputation: 168

It is, to me, more like a document-oriented data design problem than a REST design one. My approach is to drive the design of data model by the view or the pages, not to design the model first then try to fit the view to it. This somehow aligns with Reda's answer.

In order to reduce the number of requests or mongoose populations, I always allow duplications in the documents. In your example, a bucket will has an array of post id's and an array of stream ids. At the same time, a post will has an array of buckets id's and even some detailed information of each bucket. Such a design will make retrieval of the document very fast, but slow down update operations, and also introduces the risk of inconsistence.

Upvotes: 1

Synzvato Chavea
Synzvato Chavea

Reputation: 320

What I usually do is:

  • I don't populate anything on a "list" request.
  • I populate all objectId references on a "show" request.

This would not make your service less RESTful, as far as I'm concerned. It will still be resource oriented and the attached data actually belongs to that specific resource. That should reduce the amount of requests you'd need to make.

Alternatively, you could create a container resource that gathers all the required information and sends it back to the client. I'd personally go with a couple of separate requests though. Especially because, since HTTP 1.1, multiple requests can be executed through the same connection. I don't think that requesting multiple JSON objects at the same time would have any significant impact on the performance of your application.

I wouldn't nest everything inside a "data" schema though.

Hope it helps and good luck!

Upvotes: 2

Reda
Reda

Reputation: 2289

You should denormalise your schema

Upvotes: 0

Related Questions