1

I consume a webservice API that is written in Sinatra and uses a nonrelational database (MongoDB).

There are things stored like this:

article:{
    "title:"foo",
    "comments": ["first comment", "lolz", "fake comment"],
    "foo", "bar"
}

The update method requires me to send ALL the data AGAIN with the modified values. So, if I want to add a comment I need to send:

article: {
    "title:"foo",
    "comments": ["first comment", "lolz", "fake comment", "another comment"],
    "foo", "bar"
}

This may result in data loss. For example:

Bob gets the article on his iPhone. Alice gets the same article on her iPad. They read it. Bob decides to leave a long comment. Alice leaves a short comment and finishes before Bob (makes the update request). Bob finishes after a while and makes his comment - makes the update request rewriting Alice's comment.

I argued that this is a problem. The result of this was a new API call to ADD a comment to an article with a specific ID - not sending again all the existing parameters.

This is still not ok (if I do update a parameter, I still have to send the arrays). I guess that the array fields of a model should not be available when doing POST or PUT. There should be another resource called URL (at least for the end user if the model in the DB remains the same).

I don't know a good approach on this.

4

1 回答 1

1

这只是一个例子——我不知道你使用的是 Mongoid 还是什么。这些都是即兴的,所以如果有什么不对劲的地方请见谅。

假设您有一个文章模型,其方法如下:

class Article
    # Stuff
    def add_comment(comment)
        @comments.push comment
    end
    # More stuff.
end

我不明白为什么不能有这样的路线:

post '/api/article/:article_id/comment/:comment' do
    # retrieve an article by its ID.
    article.add_comment params[:comment]
    article.save
end

即使您没有模型,也只是一个查询问题,例如:

article_collection.update(
    {_id: BSON::ObjectId.from_string(params[:article_id])},
    {"$push" => {comments: {params[:comment]}},
    {w: 1} # Or 0 if you like to live dangerously.
)
于 2013-06-24T13:38:57.373 回答