title: RESTful API related objects & denormalization (MongoDB)
body: <p>I'm building a RESTful web application using node.js and MongoDB.</p>
  
  <p>I have a <strong>Person model</strong></p>
  
  <pre><code>Person
    id:         '12345'
    name:       'John'
    likes:      [ {id: '54321', name: 'Mary'} ]
    isLikeydBy: []
  
  
  Person
    id:         '54321'
    name:       'Mary'
    likes:      []
    isLikeydBy: [ {id: '12345', name: 'John'} ]
  </code></pre>
  
  <p><strong>What is the best way to model "likes" and "isLikedBy" relationships?</strong> Since I am using MongoDB I thought that this is a good way to model the relationships, as there is only one access to database needed to get all data about one person. </p>
  
  <p><strong>How to create a REST api for this relationship?</strong> What if 'John' doesn't like 'Mary' anymore. The server only receives the following put request.</p>
  
  <pre><code>  Person
    id:         '12345'
    name:       'John'
    likes:      []
    isLikeydBy: []
  </code></pre>
  
  <p>But the server should also update 'Mary', because now she is not liked by 'John' anymore. (I know that MongoDB does not directly support transactions and that I have to implement them myself.)</p>
  
  <p><strong>My ideas:</strong></p>
  
  <p><strong>1.</strong> On each update of Person (of it's 'likes' and 'isLikedBy' fields) get this person from database and compare their 'likes' and 'isLikedBy' fields with the request. There is some overhead with this approach and also I do not know if it is in the spirit of RESTful APIs.</p>
  
  <p><strong>2.</strong> Make the client send both the original 'likes' and 'isLikedBy' fields and also the new updated ones (or only the diff). This seems even further away from RESTful design, since  the client must now be aware of which data was last successfully saved to the server.</p>
  
  <p><strong>3.</strong> Create a separate object which would contain the relationship information (3 fields: id, me, whoILike). But this means that each time I would want to get data about a person I would need 2 queries, one for the person and one for relationships and then combine the data into single object.</p>
  
  <p>What should I do?</p>