0

So I'd like to create a commenting system, which will have an endpoint of something like:

mysite.com/comments/12345

So, I'd like the user who created the comment to be able to close off a comment, which would prevent any additional replies to the comment. Let's just say that the server method will be named "Close".

My question:

  • What does the url look like?
  • What does the body contain? (I assume that it will need to contain some way to authenticate who the user is that is submitting the action, but does it include any additional information, such as commentid?)
  • What Http Verb do I use?

I will probably use ASP.Net Web API as the platform, though this is REST, so I assume that should have no bearing on the solution.

Tim
  • 41,901
  • 18
  • 127
  • 145
John
  • 3,332
  • 5
  • 33
  • 55

2 Answers2

1

Possible solution for your situation would be to add a field 'closed' or similar.
You probably already have a field user or author or something similar that specifies who is doing the request.

So when you create a comment

POST mysite.com/comments HTTP/1.1

{
  "body": "hey sway",
  "user": "John",
  "closed": "no"
}

This is using JSON and is just an example, I don't know how your server is implemented but that does not really matter.

Then, to 'close off' a comment you would do a PATCH (partial update) to that resource

PATCH mysite.com/comments/12345

{
  "closed": "yes"
}

Depending on how your server is implemented, providing only the fields that need to be updated/edited could be sufficient. However, because you only want the creator of the comment to be able to close it off, you should include user in the request as well:

PATCH mysite.com/comments/12345

{
  "user": "John"
  "closed": "yes"
}

Above example assumes the resource id for the created comment is 12345 like in your example.

Then on the server you can check if John is allowed to close the comment off.


So to sum it up

What does the url look like?

The url is the same as it would be for a GET

What does the body contain?

All the fields that need to be updated/edited, and user

What Http Verb do I use?

A PATCH makes the most sense here, since you are partially updating a resource.

Tim
  • 41,901
  • 18
  • 127
  • 145
  • So following up just to see if I have a decent understanding: the "resource" doesn't actually have to exactly coincide with what is kept in a data store, does it? For example, say that I wanted to ban one user from making replies, I could have a "property" called "banuser". Or if I wanted to up-vote a comment, I could have a "property" called upvote. Is that correct? – John Jun 17 '14 at 16:51
  • @John sort of yes. In those cases it would make more sense for users to have a field `banned` instead of `banuser` because it is a property that says something about the user, not an action. Same for the votes; you would give comments a field `upvotes` that keeps track of the number of upvotes that comment has – Tim Jun 17 '14 at 16:54
  • @John I realize I didn't really answer your question in your previous comment.. `the "resource" doesn't actually have to exactly coincide with what is kept in a data store, does it?` it does actually. Key part here is that actions are not defined in the resource's fields, the fields say something about the user. The actions that do something with a resource are a different thing – Tim Jun 17 '14 at 16:58
  • Now I'm a bit confused. Two things. 1)So actually, I wouldn't be banning the user entirely, but only from replying to a specific comment. 2) I would think that with the principle of Separation of Concerns that the client calling the service doesn't need to know anything about what's in the datastore. It's a convenience when the two match, but they shouldn't have to. Perhaps banning a user also sends an alert to the NSA. I don't want that showing up in my public RESTful API =) – John Jun 17 '14 at 17:04
  • An additional comment on 1). I actually don't know how this would be implemented on the back end exactly. Maybe it's on the user. Maybe it's NoSQL and is on the comments. Just thinking that I should be able to write the RESTful service without even knowing how the back end will look at this point. – John Jun 17 '14 at 17:06
  • @John haha - good reason. You are correct that the client does not need to know what is in the datastore, but usually the server is implemented in such a way that it only accepts data it can do something with, and for a resource that is a couple fields it can store in a data store, actions are not information that define a resource – Tim Jun 17 '14 at 17:07
  • Another question. In RESTful Web Services, they wrapped a resource around an operation. In particular, they handled transactions (something specified in SOAP, but not REST) by doing a PUT to /transactions/account-transfer/abc-123. For something like "banninga user", which could involve some back-end work more than just updating a record, would you instead do something like /commands/block-user/ and send powerUserId, userToBlockId, commentId in the body? – John Jun 17 '14 at 18:06
  • @John, no I would do it the way I described earlier – Tim Jun 17 '14 at 19:06
  • A `PATCH` request should contain a set of instruction _how_ an entity should be modified not just simple values. [Here is a good article about that](http://williamdurand.fr/2014/02/14/please-do-not-patch-like-an-idiot/). – lefloh Jun 18 '14 at 12:18
0

If the information if a comment is closed is part of the resource you can PUT the new version of the resource:

PUT /comments/12345 HTTP/1.1

{
  "id" : "12345",
  "content" : "something",
  "replies" : [ "foo", "bar" ],
  "closed" : true
}

According to the HTTP Specification you must PUT the whole resource:

If the Request-URI refers to an already existing resource, the enclosed entity SHOULD be considered as a modified version of the one residing on the origin server.

If you don't want to send the whole resource you can use PATCH:

PATCH /comments/12345 HTTP/1.1

{ 
  "op" : "replace", 
  "path" : "/closed", 
  "value": true 
}

See the JSON Patch draft for more details.

You can also use POST for updating a resource. There are already lots of discussions about that like here, here and here.

Community
  • 1
  • 1
lefloh
  • 10,653
  • 3
  • 28
  • 50