REST isn't carved in stone and this many-to-many relationship of nested resources is a very common problem with mostly two possible approaches. Which of the two is best for your specific case would depend on a few details and maybe how exactly asp.net handles things. But I will just describe both and explain why I mostly prefer the second approach.
Approach one would simply use the nested resources approach you already have. Doing
POST /api/Lists/234/Persons/123
would add Person 123 to list 234. This is simple and easy and you could see this used often enough but has a few disadvantages. (obviously you could mirror this and us POST /api/Persons/123/Lists/234
instead)
The second alternative is to handle it as a resource of its own named ListPersons (as you maybe already named the table holding the relationship information for this).
To create such a resource:
POST /api/ListPersons?list=234&person=123
similar to delete a person from a list or update the relationship. While at first this may seem a bit superficial it is most likely easier to implement and test. Also it keeps the controller actions simpler, since it lets them stay "single responsibility". The main advantage may be that if you later want to add additional data to the relationship adding this information was params will be easy and names can't clash with similar names in the other two tables.
As an example assume a List would be a team and later you decide to add the 'role' the Person (in this case a player) has in this team. You can easily add this like
POST /api/ListPersons?list=234&person=123&role=captain
even if the Person resource has a role (say the preferred role for this Person) by itself.
At least in Rails this has the additional advantage that within the controllers the action names can still reflect the REST verbs, while in approach one since create etc are already taken for the List itself you would have to come up with new names.
For completeness approach three would be to simply update a List with a param that contains a list of Persons. I would totally dislike this for many reasons so I just mention that this too is seen in the wild.
Your solution is OK, save for a few things:
Versioning REST APIs at the resource level is generally not a good practice, although this not necessarily a consensus view. See here for some comments and links to further discussion.
To your second question, you could probably argue either way as to whether /keys/{id}/
or /values/{id}/
is correct, but my instinct would be to either use keys
since it's the "parent" of the tuple, or I'd use an entirely different name such as /data/
or /elements/
, or whatever it is these things actually represent.
I would probably have different GET methods for the whole key-value dictionary, e.g. /keys/{id}
/, and a separate resource for those for a particular user, e.g. /users/{id}/keys/{keyId}
.
Finally, it's not great (although possible) to use query strings with POST/PUT/DELETE methods. It is a query string, after all. Instead, you could use POST /data/
, and put the key-value pair as JSON data in the request body.
See this question as well.
Best Answer
No - REST doesn't care about how you spell your identifiers.
It's violates URI design guidelines, for exactly the reason you specify -- you are naming an entity (a noun) with a verb. HTTP is already giving you verbs, so you don't need them in the identifier.
The most common solution to this sort of problem is to create a resource that represents the specific noun you want to manipulate, for instance
This suggests that the resource that is being manipulated isn't a status, but an event or a command -- for example: ContractorDismissed, and the change to the status is a side effect.